Ejemplo n.º 1
0
        /// <summary>
        /// Handles window position changing event.
        /// </summary>
        protected override void HandleWindowPosChanging(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            var position = Marshal.PtrToStructure <WindowHelper.WINDOWPOS>(lParam);

            double width  = position.cx;
            double height = position.cy;

            if (position.flags.HasFlag(WindowHelper.SWP.SWP_SHOWWINDOW))
            {
                var dpi = VisualTreeHelperAddition.GetDpi(_window);
                width  = _window.ActualWidth * dpi.DpiScaleX;
                height = _window.ActualHeight * dpi.DpiScaleY;
            }

            if ((0 < width) && (0 < height) &&
                TryGetAdjacentLocation(width, height, out Point adjacentLocation) &&
                TryGetAdjustedPosition(width, height, adjacentLocation, out Rect adjustedPosition))
            {
                position.x      = (int)adjustedPosition.X;
                position.y      = (int)adjustedPosition.Y;
                position.flags &= ~WindowHelper.SWP.SWP_NOMOVE;

                if (((int)adjustedPosition.Width < (int)width) || ((int)adjustedPosition.Height < (int)height))
                {
                    position.cx     = (int)adjustedPosition.Width;
                    position.cy     = (int)adjustedPosition.Height;
                    position.flags &= ~WindowHelper.SWP.SWP_NOSIZE;
                }

                Marshal.StructureToPtr <WindowHelper.WINDOWPOS>(position, lParam, true);
            }
        }
Ejemplo n.º 2
0
        private void OnSourceInitialized(object sender, EventArgs e)
        {
            _source = PresentationSource.FromVisual(_window) as HwndSource;
            _source?.AddHook(WndProc);

            var dpi = VisualTreeHelperAddition.GetDpi(_window);

            if (!dpi.Equals(VisualTreeHelperAddition.SystemDpi))
            {
                AdjustWindow(dpi);
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Gets Per-Monitor DPI of the monitor.
 /// </summary>
 /// <returns>DPI information</returns>
 protected virtual DpiScale GetDpi() => VisualTreeHelperAddition.GetDpi(_window);
Ejemplo n.º 4
0
        /// <summary>
        /// Attempts to get the adjacent location to NotifyIcon using specified window width and height.
        /// </summary>
        /// <param name="windowWidth">Window width</param>
        /// <param name="windowHeight">Window height</param>
        /// <param name="location">Location of window</param>
        /// <returns>True if successfully gets</returns>
        protected bool TryGetAdjacentLocationToTaskbar(double windowWidth, double windowHeight, out Rect location)
        {
            if (!WindowHelper.TryGetTaskbar(out Rect taskbarRect, out TaskbarAlignment taskbarAlignment, out bool isShown))
            {
                location = default;
                return(false);
            }

            var iconPlacement    = IconPlacement.Unknown;
            var overflowAreaRect = default(Rect);

            if (NotifyIconHelper.TryGetNotifyIconRect(_notifyIcon, out Rect iconRect))
            {
                if (taskbarRect.Contains(
                        iconRect.X + iconRect.Width / 2D,
                        iconRect.Y + iconRect.Height / 2D))
                {
                    iconPlacement = IconPlacement.InTaskbar;
                }
                else if (WindowHelper.TryGetOverflowAreaRect(out overflowAreaRect) &&
                         overflowAreaRect.Contains(iconRect))
                {
                    iconPlacement = IconPlacement.InOverflowArea;
                }
            }

            if (!WindowHelper.TryGetDwmWindowMargin(_window, out Thickness windowMargin))
            {
                windowMargin = new Thickness(0);                 // Fallback
            }
            var isLeftToRight = !CultureInfoAddition.UserDefaultUICulture.TextInfo.IsRightToLeft;

            var distance = KeepsDistance
                                ? new Vector(Distance, Distance) * VisualTreeHelperAddition.GetDpi(_window).ToMatrix()
                                : new Vector(0, 0);

            double x = 0, y = 0;

            // To avoid a gap between window and taskbar when taskbar alignment is right or bottom
            // and monitor DPI is 125%, 150%, 175%, the window width and height (in DIP) must be
            // a multiple of 4. Otherwise, the window width and height multiplied with those DPI
            // will have a fraction and it will cause a blurry edge looking as if there is a gap.
            switch (taskbarAlignment)
            {
            case TaskbarAlignment.Top:
            case TaskbarAlignment.Bottom:
                x = iconPlacement switch
                {
                    IconPlacement.InTaskbar => isLeftToRight ? iconRect.Right : iconRect.Left,
                    IconPlacement.InOverflowArea => isLeftToRight ? (overflowAreaRect.Left - distance.X) : (overflowAreaRect.Right + distance.X),
                    _ => isLeftToRight ? (taskbarRect.Right - distance.X) : (taskbarRect.Left + distance.X),                             // Fallback
                };
                x -= isLeftToRight ? (windowWidth - windowMargin.Right) : windowMargin.Left;

                switch (taskbarAlignment)
                {
                case TaskbarAlignment.Top:
                    y = (isShown ? taskbarRect.Bottom : taskbarRect.Top) - windowMargin.Top + distance.Y;
                    PivotAlignment = isLeftToRight ? PivotAlignment.TopRight : PivotAlignment.TopLeft;
                    break;

                case TaskbarAlignment.Bottom:
                    y = (isShown ? taskbarRect.Top : taskbarRect.Bottom) - (windowHeight - windowMargin.Bottom) - distance.Y;
                    PivotAlignment = isLeftToRight ? PivotAlignment.BottomRight : PivotAlignment.BottomLeft;
                    break;
                }
                break;

            case TaskbarAlignment.Left:
            case TaskbarAlignment.Right:
                switch (taskbarAlignment)
                {
                case TaskbarAlignment.Left:
                    x = (isShown ? taskbarRect.Right : taskbarRect.Left) - windowMargin.Left + distance.X;
                    PivotAlignment = PivotAlignment.BottomLeft;
                    break;

                case TaskbarAlignment.Right:
                    x = (isShown ? taskbarRect.Left : taskbarRect.Right) - (windowWidth - windowMargin.Right) - distance.X;
                    PivotAlignment = PivotAlignment.BottomRight;
                    break;
                }

                y = iconPlacement switch
                {
                    IconPlacement.InTaskbar => iconRect.Bottom,
                    IconPlacement.InOverflowArea => overflowAreaRect.Top - distance.Y,
                    _ => taskbarRect.Bottom - distance.Y,                             // Fallback
                };
                y -= (windowHeight - windowMargin.Bottom);
                break;
            }
            location = new Rect(x, y, windowWidth, windowHeight);
            return(true);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Gets Per-Monitor DPI of the monitor.
 /// </summary>
 /// <returns>DPI information</returns>
 protected override DpiScale GetDpi() => VisualTreeHelperAddition.GetDpi(_pivot);