// Check if current location of this window is good for delayed adjustment. bool IsLocationGood() { if (dpiOld == 0) { return(false); // Abort. } float factor = dpiNew / dpiOld; // Prepare new rectangle shrinked or expanded sticking Left-Top corner. int widthDiff = (int)(this.ClientSize.Width * factor) - this.ClientSize.Width; int heightDiff = (int)(this.ClientSize.Height * factor) - this.ClientSize.Height; W32.RECT rect = new W32.RECT() { left = this.Bounds.Left, top = this.Bounds.Top, right = this.Bounds.Right + widthDiff, bottom = this.Bounds.Bottom + heightDiff }; // Get handle to monitor that has the largest intersection with the rectangle. IntPtr handleMonitor = W32.MonitorFromRect(ref rect, W32.MONITOR_DEFAULTTONULL); if (handleMonitor != IntPtr.Zero) { // Check if DPI of the monitor matches. if (GetDpiSpecifiedMonitor(handleMonitor) == dpiNew) { return(true); } } return(false); }
// Catch window message of DPI change. protected override void WndProc(ref Message m) { base.WndProc(ref m); // Check if Windows 8.1 or newer and if not, ignore message. if (!IsEightOneOrNewer()) { return; } const int WM_DPICHANGED = 0x02e0; // 0x02E0 from WinUser.h if (m.Msg == WM_DPICHANGED) { // wParam short lo = W32.GetLoWord(m.WParam.ToInt32()); // lParam W32.RECT r = (W32.RECT)Marshal.PtrToStructure(m.LParam, typeof(W32.RECT)); // Hold new DPI as target for adjustment. dpiNew = lo; switch (method) { case ResizeMethod.Immediate: if (dpiOld != lo) { MoveWindow(); AdjustWindow(); } break; case ResizeMethod.Delayed: if (dpiOld != lo) { if (isBeingMoved) { willBeAdjusted = true; } else { AdjustWindow(); } } else { if (willBeAdjusted) { willBeAdjusted = false; } } break; } } }
// Get new location of this window after DPI change. void MoveWindow() { if (Util.DesignMode) { return; } if (dpiOld == 0) { return; // Abort. } float factor = dpiNew / dpiOld; // Prepare new rectangles shrinked or expanded sticking four corners. int widthDiff = (int)(this.ClientSize.Width * factor) - this.ClientSize.Width; int heightDiff = (int)(this.ClientSize.Height * factor) - this.ClientSize.Height; List <W32.RECT> rectList = new List <W32.RECT>(); // Left-Top corner rectList.Add(new W32.RECT { left = this.Bounds.Left, top = this.Bounds.Top, right = this.Bounds.Right + widthDiff, bottom = this.Bounds.Bottom + heightDiff }); // Right-Top corner rectList.Add(new W32.RECT { left = this.Bounds.Left - widthDiff, top = this.Bounds.Top, right = this.Bounds.Right, bottom = this.Bounds.Bottom + heightDiff }); // Left-Bottom corner rectList.Add(new W32.RECT { left = this.Bounds.Left, top = this.Bounds.Top - heightDiff, right = this.Bounds.Right + widthDiff, bottom = this.Bounds.Bottom }); // Right-Bottom corner rectList.Add(new W32.RECT { left = this.Bounds.Left - widthDiff, top = this.Bounds.Top - heightDiff, right = this.Bounds.Right, bottom = this.Bounds.Bottom }); // Get handle to monitor that has the largest intersection with each rectangle. for (int i = 0; i <= rectList.Count - 1; i++) { W32.RECT rectBuf = rectList[i]; IntPtr handleMonitor = W32.MonitorFromRect(ref rectBuf, W32.MONITOR_DEFAULTTONULL); if (handleMonitor != IntPtr.Zero) { // Check if at least Left-Top corner or Right-Top corner is inside monitors. IntPtr handleLeftTop = W32.MonitorFromPoint(new W32.POINT(rectBuf.left, rectBuf.top), W32.MONITOR_DEFAULTTONULL); IntPtr handleRightTop = W32.MonitorFromPoint(new W32.POINT(rectBuf.right, rectBuf.top), W32.MONITOR_DEFAULTTONULL); if ((handleLeftTop != IntPtr.Zero) || (handleRightTop != IntPtr.Zero)) { // Check if DPI of the monitor matches. if (GetDpiSpecifiedMonitor(handleMonitor) == dpiNew) { // Move this window. this.Location = new Point(rectBuf.left, rectBuf.top); break; } } } } }
// Check if current location of this window is good for delayed adjustment. bool IsLocationGood() { if (dpiOld == 0) return false; // Abort. float factor = dpiNew / dpiOld; // Prepare new rectangle shrinked or expanded sticking Left-Top corner. int widthDiff = (int)(this.ClientSize.Width * factor) - this.ClientSize.Width; int heightDiff = (int)(this.ClientSize.Height * factor) - this.ClientSize.Height; W32.RECT rect = new W32.RECT() { left = this.Bounds.Left, top = this.Bounds.Top, right = this.Bounds.Right + widthDiff, bottom = this.Bounds.Bottom + heightDiff }; // Get handle to monitor that has the largest intersection with the rectangle. IntPtr handleMonitor = W32.MonitorFromRect(ref rect, W32.MONITOR_DEFAULTTONULL); if (handleMonitor != IntPtr.Zero) { // Check if DPI of the monitor matches. if (GetDpiSpecifiedMonitor(handleMonitor) == dpiNew) { return true; } } return false; }