/// <summary>
 /// Constructor
 /// </summary>
 /// <param name="oldDpi">Old DPI</param>
 /// <param name="newDpi">New DPI</param>
 public DpiChangedEventArgs(Dpi oldDpi, Dpi newDpi)
 {
     this.OldDpi = oldDpi;
     this.NewDpi = newDpi;
 }
Exemple #2
0
        /// <summary>
        /// Handles window messages.
        /// </summary>
        /// <param name="hwnd">The window handle</param>
        /// <param name="msg">The message ID</param>
        /// <param name="wParam">The message's wParam value</param>
        /// <param name="lParam">The message's lParam value</param>
        /// <param name="handled">Whether the message was handled</param>
        /// <returns>Return value depending on the particular message</returns>
        /// <remarks>This is an implementation of System.Windows.Interop.HwndSourceHook.</remarks>
        protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
            case (int)WindowMessage.WM_DPICHANGED:
                var oldDpi = MonitorDpi;
                MonitorDpi = new Dpi(
                    NativeMacro.GetLoWord((uint)wParam),
                    NativeMacro.GetHiWord((uint)wParam));

                Debug.WriteLine($"DPICHANGED: {oldDpi.X} -> {MonitorDpi.X}");

                if (MonitorDpi.Equals(oldDpi))
                {
                    break;
                }

                _isDpiChanged = true;

                var newInfo = new WindowInfo {
                    Dpi = MonitorDpi
                };

                switch (_currentStatus)
                {
                case WindowStatus.None:
                case WindowStatus.LocationChanged:
                    if ((_baseSize == Size.Empty) || (_currentStatus == WindowStatus.None))
                    {
                        _baseSize = new Size(_targetWindow.Width, _targetWindow.Height);
                    }

                    _baseSize = new Size(
                        _baseSize.Width * (double)MonitorDpi.X / oldDpi.X,
                        _baseSize.Height * (double)MonitorDpi.Y / oldDpi.Y);

                    newInfo.Size = _baseSize;
                    break;

                case WindowStatus.SizeChanged:
                    // None.
                    break;
                }

                Interlocked.Exchange(ref _dueInfo, newInfo);

                switch (_currentStatus)
                {
                case WindowStatus.None:
                    ChangeDpi();
                    break;

                case WindowStatus.LocationChanged:
                    // None.
                    break;

                case WindowStatus.SizeChanged:
                    ChangeDpi(WindowStatus.SizeChanged);
                    break;
                }

                handled = true;
                break;

            case (int)WindowMessage.WM_ENTERSIZEMOVE:
                Debug.WriteLine("ENTERSIZEMOVE");

                if (!IsPerMonitorDpiAware)
                {
                    break;
                }

                _baseSize = new Size(_targetWindow.Width, _targetWindow.Height);

                _isEnteredSizeMove    = true;
                _isDpiChanged         = false;
                _countLocationChanged = 0;
                _countSizeChanged     = 0;
                break;

            case (int)WindowMessage.WM_EXITSIZEMOVE:
                Debug.WriteLine("EXITSIZEMOVE");

                if (_isEnteredSizeMove)
                {
                    _isEnteredSizeMove = false;

                    // Last stand!!!
                    if (_isDpiChanged && (_currentStatus == WindowStatus.LocationChanged))
                    {
                        var lastInfo = new WindowInfo
                        {
                            Dpi  = MonitorDpi,
                            Size = _baseSize,
                        };

                        Interlocked.Exchange(ref _dueInfo, lastInfo);

                        ChangeDpi(WindowStatus.LocationChanged);
                    }

                    _currentStatus = WindowStatus.None;
                }

                ChangeColorProfilePath();
                break;

            case (int)WindowMessage.WM_MOVE:
                Debug.WriteLine("MOVE");

                if (_isEnteredSizeMove)
                {
                    _countLocationChanged++;
                    if (_countLocationChanged > _countSizeChanged)
                    {
                        _currentStatus = WindowStatus.LocationChanged;
                    }

                    ChangeDpi(WindowStatus.LocationChanged);
                }
                break;

            case (int)WindowMessage.WM_SIZE:
                if ((uint)wParam != NativeMethod.SIZE_RESTORED)
                {
                    break;
                }

                Debug.WriteLine("SIZE");

                if (_isEnteredSizeMove)
                {
                    _countSizeChanged++;
                    if (_countLocationChanged < _countSizeChanged)
                    {
                        _currentStatus = WindowStatus.SizeChanged;
                    }

                    // DPI change by resize will be managed when WM_DPICHANGED comes.
                }
                break;
            }
            return(IntPtr.Zero);
        }
 /// <summary>
 /// Equals operator
 /// </summary>
 /// <param name="other">Other instance to compare</param>
 /// <returns>True if equal</returns>
 public bool Equals(Dpi other)
 {
     return(this == other);
 }