BrightnessTray.WindowPositioning.GetWindowPosition C# (CSharp) Метод

GetWindowPosition() публичный статический Метод

Returns the optimum window position in relation to the specified notify icon.
public static GetWindowPosition ( System.Windows.Forms.NotifyIcon notifyicon, double windowwidth, double windowheight, double dpi ) : Point
notifyicon System.Windows.Forms.NotifyIcon The notify icon that the window should be aligned to.
windowwidth double The width of the window.
windowheight double The height of the window.
dpi double The system's DPI (in relative units: 1.0 = 96 DPI, 1.25 = 120 DPI, etc.).
Результат Point
        public static Point GetWindowPosition(NotifyIcon notifyicon, double windowwidth, double windowheight, double dpi)
        {
            // retrieve taskbar information
            TaskBarInfo taskbarinfo = GetTaskBarInfo();

            // retrieve notify icon location
            Rect? nipositiontemp = GetNotifyIconRectangle(notifyicon);

            // if our functions can't find the rectangle, align it to a corner of the screen
            Rect niposition;
            if (nipositiontemp == null)
            {
                switch (taskbarinfo.Alignment)
                {
                    case TaskBarAlignment.Bottom: // bottom right corner
                        niposition = new Rect(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Bottom - 1, 1, 1);
                        break;
                    case TaskBarAlignment.Top: // top right corner
                        niposition = new Rect(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Top, 1, 1);
                        break;
                    case TaskBarAlignment.Right: // bottom right corner
                        niposition = new Rect(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Bottom - 1, 1, 1);
                        break;
                    case TaskBarAlignment.Left: // bottom left corner
                        niposition = new Rect(taskbarinfo.Position.Left, taskbarinfo.Position.Bottom - 1, 1, 1);
                        break;
                    default:
                        goto case TaskBarAlignment.Bottom;
                }
            }
            else
                niposition = (Rect)nipositiontemp;

            // check if notify icon is in the fly-out
            bool inflyout = IsNotifyIconInFlyOut(niposition, taskbarinfo.Position);

            // if the window is pinned open and in the fly-out (Windows 7 only),
            // we should position the window above the 'show hidden icons' button
            // if (inflyout && pinned)
            //     niposition = (Rect)GetNotifyAreaButtonRectangle();

            // determine centre of notify icon
            Point nicentre = new Point(niposition.Left + (niposition.Width / 2), niposition.Top + (niposition.Height / 2));

            // get window offset from edge
            double edgeoffset = Compatibility.WindowEdgeOffset * dpi;

            // get working area bounds
            Rect workarea = GetWorkingArea(niposition);

            // calculate window position
            double windowleft = 0, windowtop = 0;

            switch (taskbarinfo.Alignment)
            {
                case TaskBarAlignment.Bottom:
                    // horizontally centre above icon
                    windowleft = nicentre.X - (windowwidth / 2);
                    if (inflyout)
                        windowtop = niposition.Top - windowheight - edgeoffset;
                    else
                        windowtop = taskbarinfo.Position.Top - windowheight - edgeoffset;

                    break;

                case TaskBarAlignment.Top:
                    // horizontally centre below icon
                    windowleft = nicentre.X - (windowwidth / 2);
                    if (inflyout)
                        windowtop = niposition.Bottom + edgeoffset;
                    else
                        windowtop = taskbarinfo.Position.Bottom + edgeoffset;

                    break;

                case TaskBarAlignment.Left:
                    // vertically centre to the right of icon (or above icon if in flyout and not pinned)
                    if (inflyout)
                    {
                        windowleft = nicentre.X - (windowwidth / 2);
                        windowtop = niposition.Top - windowheight - edgeoffset;
                    }
                    else
                    {
                        windowleft = taskbarinfo.Position.Right + edgeoffset;
                        windowtop = nicentre.Y - (windowheight / 2);
                    }

                    break;

                case TaskBarAlignment.Right:
                    // vertically centre to the left of icon (or above icon if in flyout and not pinned)
                    if (inflyout)
                    {
                        windowleft = nicentre.X - (windowwidth / 2);
                        windowtop = niposition.Top - windowheight - edgeoffset;
                    }
                    else
                    {
                        windowleft = taskbarinfo.Position.Left - windowwidth - edgeoffset;
                        windowtop = nicentre.Y - (windowheight / 2);
                    }

                    break;

                default:
                    goto case TaskBarAlignment.Bottom; // should be unreachable
            }

            //// check that the window is within the working area
            //// if not, put it next to the closest edge

            if (windowleft + windowwidth + edgeoffset > workarea.Right) // too far right
                windowleft = workarea.Right - windowwidth - edgeoffset;
            else if (windowleft < workarea.Left) // too far left
                windowleft = workarea.Left + edgeoffset;

            if (windowtop + windowheight + edgeoffset > workarea.Bottom) // too far down
                windowtop = workarea.Bottom - windowheight - edgeoffset;
            //// the window should never be too far up, so we can skip checking for that

            return new Point(windowleft, windowtop);
        }

Usage Example

        /// <summary>
        /// Updates the display (position and appearance) of the window.
        /// </summary>
        /// <param name="activatewindow">True if the window should be activated, false if not.</param>
        public void UpdateWindowDisplay(bool activatewindow)
        {
            if (this.IsLoaded)
            {
                // set handlers if necessary
                this.SetHandlers();

                // get the handle of the window
                HwndSource windowhandlesource = PresentationSource.FromVisual(this) as HwndSource;

                bool glassenabled = Compatibility.IsDWMEnabled;

                //// update location

                Rect windowbounds = (glassenabled ? WindowPositioning.GetWindowSize(windowhandlesource.Handle) : WindowPositioning.GetWindowClientAreaSize(windowhandlesource.Handle));

                // work out the current screen's DPI
                Matrix screenmatrix = windowhandlesource.CompositionTarget.TransformToDevice;

                double dpiX = screenmatrix.M11; // 1.0 = 96 dpi
                double dpiY = screenmatrix.M22; // 1.25 = 120 dpi, etc.

                Point position = WindowPositioning.GetWindowPosition(this.NotifyIcon, windowbounds.Width, windowbounds.Height, dpiX);

                // translate wpf points to screen coordinates
                Point screenposition = new Point(position.X / dpiX, position.Y / dpiY);

                this.Left = screenposition.X;
                this.Top  = screenposition.Y;

                // update borders
                if (glassenabled)
                {
                    this.Style = (Style)FindResource("AeroBorderStyle");
                }
                else
                {
                    this.SetNonGlassBorder(this.IsActive);
                }

                // fix aero border if necessary
                if (glassenabled)
                {
                    // set the root border element's margin to 1 pixel
                    WindowBorder.Margin  = new Thickness(1 / dpiX);
                    this.BorderThickness = new Thickness(0);

                    // set the background of the window to transparent (otherwise the inner border colour won't be visible)
                    windowhandlesource.CompositionTarget.BackgroundColor = Colors.Transparent;

                    // get dpi-dependent aero border width
                    int xmargin = Convert.ToInt32(1); // 1 unit wide
                    int ymargin = Convert.ToInt32(1); // 1 unit tall

                    NativeMethods.MARGINS margins = new NativeMethods.MARGINS()
                    {
                        cxLeftWidth = xmargin, cxRightWidth = xmargin, cyBottomHeight = ymargin, cyTopHeight = ymargin
                    };

                    NativeMethods.DwmExtendFrameIntoClientArea(windowhandlesource.Handle, ref margins);
                }
                else
                {
                    WindowBorder.Margin  = new Thickness(0);        // reset the margin if the DWM is disabled
                    this.BorderThickness = new Thickness(1 / dpiX); // set the window's border thickness to 1 pixel
                }

                if (activatewindow)
                {
                    this.Show();
                    this.Activate();
                }
            }
        }