/// <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; }
/// <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); }