Exemplo n.º 1
0
        public Taskbar()
        {
            IntPtr taskbarHandle = PInvoke.FindWindow(Taskbar.ClassName, null);

            var data = new APPBARDATA
            {
                cbSize = (uint) Marshal.SizeOf(typeof (APPBARDATA)),
                hWnd = taskbarHandle
            };

            IntPtr result = PInvoke.SHAppBarMessage(AppBarMessages.GetTaskbarPos, ref data);

            if (result == IntPtr.Zero)
                throw new InvalidOperationException();

            this.Position = (TaskbarPosition) data.uEdge;
            this.Bounds = Rectangle.FromLTRB(data.rc.Left, data.rc.Top, data.rc.Right, data.rc.Bottom);

            data.cbSize = (uint) Marshal.SizeOf(typeof (APPBARDATA));
            result = PInvoke.SHAppBarMessage(AppBarMessages.GetState, ref data);
            int state = result.ToInt32();
            this.AlwaysOnTop = (state & AppBarState.AlwaysOnTop) == AppBarState.AlwaysOnTop;
            this.AutoHide = (state & AppBarState.Autohide) == AppBarState.Autohide;
        }
Exemplo n.º 2
0
        private void UnRegisterAppBar()
        {
            Log.Info("UnRegisterAppBar called");

            if (getWindowState() != WindowStates.Docked) return;

            var abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = windowHandle;
            PInvoke.SHAppBarMessage(AppBarMessages.Remove, ref abd);
            appBarCallBackId = -1;
        }
Exemplo n.º 3
0
        private void SetAppBarSizeAndPosition(DockEdges dockPosition, Rect sizeAndPosition, bool isInitialising = false)
        {
            Log.InfoFormat("SetAppBarSizeAndPosition called with dockPosition:{0}, sizeAndPosition.Top:{1}, sizeAndPosition.Bottom:{2}, sizeAndPosition.Left:{3}, sizeAndPosition.Right:{4}",
                    dockPosition, sizeAndPosition.Top, sizeAndPosition.Bottom, sizeAndPosition.Left, sizeAndPosition.Right);
            Log.InfoFormat("Screen bounds in px - Top:{0}, Left:{1}, Width:{2}, Height:{3}", screenBoundsInPx.Top, screenBoundsInPx.Left, screenBoundsInPx.Width, screenBoundsInPx.Height);

            if (getWindowState() != WindowStates.Docked) return;

            var barData = new APPBARDATA();
            barData.cbSize = Marshal.SizeOf(barData);
            barData.hWnd = windowHandle;
            barData.uEdge = dockPosition.ToAppBarEdge();
            barData.rc.Left = (int)Math.Round(sizeAndPosition.Left);
            barData.rc.Top = (int)Math.Round(sizeAndPosition.Top);
            barData.rc.Right = (int)Math.Round(sizeAndPosition.Right);
            barData.rc.Bottom = (int)Math.Round(sizeAndPosition.Bottom);

            //Submit a query for the proposed dock size and position, which might be updated
            PInvoke.SHAppBarMessage(AppBarMessages.QueryPos, ref barData);

            Log.InfoFormat("QueryPos returned barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            //Compensate for lost thickness due to other app bars
            switch (dockPosition)
            {
                case DockEdges.Top:
                    barData.rc.Bottom += barData.rc.Top - (int) Math.Round(sizeAndPosition.Top);
                    break;
                case DockEdges.Bottom:
                    barData.rc.Top -= (int)Math.Round(sizeAndPosition.Bottom) - barData.rc.Bottom;
                    break;
                case DockEdges.Left:
                    barData.rc.Right += barData.rc.Left - (int)Math.Round(sizeAndPosition.Left);
                    break;
                case DockEdges.Right:
                    barData.rc.Left -= (int)Math.Round(sizeAndPosition.Right) - barData.rc.Right;
                    break;
            }

            Log.InfoFormat("Rect values adjusted (to compensate for other app bars) to barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            //Then set the dock size and position, using the potentially updated barData
            PInvoke.SHAppBarMessage(AppBarMessages.SetPos, ref barData);

            Log.InfoFormat("SetPos returned barData.rc.Top:{0}, barData.rc.Bottom:{1}, barData.rc.Left:{2}, barData.rc.Right:{3}",
                    barData.rc.Top, barData.rc.Bottom, barData.rc.Left, barData.rc.Right);

            var finalDockLeftInDp = barData.rc.Left/Graphics.DipScalingFactorX;
            var finalDockTopInDp = barData.rc.Top / Graphics.DipScalingFactorY;
            var finalDockWidthInDp = (barData.rc.Right - barData.rc.Left) / Graphics.DipScalingFactorX;
            var finalDockHeightInDp = (barData.rc.Bottom - barData.rc.Top) / Graphics.DipScalingFactorY;

            Log.InfoFormat("finalDockLeftInDp:{0}, finalDockTopInDp:{1}, finalDockWidthInDp:{2}, finalDockHeightInDp:{3}", finalDockLeftInDp, finalDockTopInDp, finalDockWidthInDp, finalDockHeightInDp);
            Log.InfoFormat("Screen bounds in dp - Top:{0}, Left:{1}, Width:{2}, Height:{3}", screenBoundsInDp.Top, screenBoundsInDp.Left, screenBoundsInDp.Width, screenBoundsInDp.Height);

            if (finalDockLeftInDp < 0 ||
                finalDockTopInDp < 0 ||
                finalDockWidthInDp <= 0 ||
                finalDockHeightInDp <= 0 ||
                (finalDockLeftInDp + finalDockWidthInDp) > screenBoundsInDp.Right ||
                (finalDockTopInDp + finalDockHeightInDp) > screenBoundsInDp.Bottom)
            {
                Log.Error("Final dock size and/or position is invalid - reverting to floating size and position");
                UnRegisterAppBar();
                saveWindowState(WindowStates.Floating);
                savePreviousWindowState(WindowStates.Floating);
                PublishError(this, new ApplicationException("There was a problem positioning OptiKey - reverting to floating position"));
            }
            else if (!isInitialising)
            {
                //Apply final size and position to the window. This is dispatched with ApplicationIdle priority
                //as WPF will send a resize after a new appbar is added. We need to apply the received size & position after this happens.
                //RECT values are in pixels so I need to scale back to DIPs for WPF.
                var rect = new Rect(finalDockLeftInDp, finalDockTopInDp, finalDockWidthInDp, finalDockHeightInDp);
                window.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ApplySizeAndPositionDelegate(ApplyAndPersistSizeAndPosition), rect);
            }
        }
Exemplo n.º 4
0
        private void RegisterAppBar()
        {
            Log.Info("RegisterAppBar called");

            if (getWindowState() != WindowStates.Docked) return;

            //Register a new app bar with Windows - this adds it to a list of app bars
            var abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = windowHandle;
            appBarCallBackId = PInvoke.RegisterWindowMessage("AppBarMessage"); //Get a system wide unique window message (id)
            abd.uCallbackMessage = appBarCallBackId;
            var result = PInvoke.SHAppBarMessage((int)AppBarMessages.New, ref abd);

            //Add hook to receive position change messages from Windows
            HwndSource source = HwndSource.FromHwnd(abd.hWnd);
            source.AddHook(AppBarPositionChangeCallback);
        }
Exemplo n.º 5
0
 public static extern IntPtr SHAppBarMessage(AppBarMessages dwMessage, ref APPBARDATA pData);
Exemplo n.º 6
0
        private void SetAppBarSizeAndPosition(DockEdges dockPosition, Rect sizeAndPosition)
        {
            if (getWindowState() != WindowStates.Docked) return;

            var barData = new APPBARDATA();
            barData.cbSize = Marshal.SizeOf(barData);
            barData.hWnd = windowHandle;
            barData.uEdge = dockPosition.ToAppBarEdge();
            barData.rc.Left = (int)Math.Round(sizeAndPosition.Left);
            barData.rc.Top = (int)Math.Round(sizeAndPosition.Top);
            barData.rc.Right = (int)Math.Round(sizeAndPosition.Right);
            barData.rc.Bottom = (int)Math.Round(sizeAndPosition.Bottom);

            //Submit a query for the proposed dock size and position, which might be updated
            PInvoke.SHAppBarMessage(AppBarMessages.QueryPos, ref barData);

            //Compensate for lost thickness due to other app bars
            switch (dockPosition)
            {
                case DockEdges.Top:
                    barData.rc.Bottom += barData.rc.Top - (int) Math.Round(sizeAndPosition.Top);
                    break;
                case DockEdges.Bottom:
                    barData.rc.Top -= (int)Math.Round(sizeAndPosition.Bottom) - barData.rc.Bottom;
                    break;
                case DockEdges.Left:
                    barData.rc.Right += barData.rc.Left - (int)Math.Round(sizeAndPosition.Left);
                    break;
                case DockEdges.Right:
                    barData.rc.Left -= (int)Math.Round(sizeAndPosition.Right) - barData.rc.Right;
                    break;
            }

            //Then set the dock size and position, using the potentially updated barData
            PInvoke.SHAppBarMessage(AppBarMessages.SetPos, ref barData);

            //Extract the final size and position and apply to the window. This is dispatched with ApplicationIdle priority
            //as WPF will send a resize after a new appbar is added. We need to apply the received size & position after this happens.
            //RECT values are in pixels so I need to scale back to DIPs for WPF.
            var rect = new Rect(
                barData.rc.Left / Graphics.DipScalingFactorX,
                barData.rc.Top / Graphics.DipScalingFactorY,
                (barData.rc.Right - barData.rc.Left) / Graphics.DipScalingFactorX,
                (barData.rc.Bottom - barData.rc.Top) / Graphics.DipScalingFactorY);
            window.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ApplySizeAndPositionDelegate(ApplyAndPersistSizeAndPosition), rect);
        }