I have two monitors connected to my desktop. A 3840x2160 main monitor on the left set to 150% scaling (144 DPI) and a 1920x1080 monitor on the right set to 100% scaling (96 DPI). The are aligned on the bottom edge. This is on Windows 8.1, but the same issue occurs on Windows 10.
My application is C++ using native Win32 windows. It is set at per-monitor DPI aware.
I have a dialog window that is a borderless (not title bar either) window with a custom title bar inside the client area. The user can drag this custom title bar to move the window, and internally it gets moved using SetWindowPos().
When this window is dragged from the High-DPI left monitor over to the regular monitor on the right, I get a WM_DPICHANGED message. The current RECT for the window is: curRect = {LeftTop(3527, 1099) RightBottom(4157, 2098) WidthHeight[630 x 999]}
The new suggested RECT that the WM_DPICHANGED message gives me is: newRect = {LeftTop(3527, 1099) RightBottom(3947, 1765) WidthHeight[420 x 666]}
If I pass the new RECT to SetWindowPos as the documentation for WM_DPICHANGED suggests, then the window is now considered back on my high-DPI monitor, and in the SetWindowPos() I get another WM_DPICHANGED message telling me to change the window pos/size again. This occurs before my original WM_DPICHANGED event has returned.
This makes sense based on the new suggested RECT since the left edge doesn't get moved, but the width is getting reduced. The WM_DPICHANGED message for the same window doesn't have this issue if I'm using an actual non-client titlebar. The left edge is moved in the new suggested RECT.
Any suggestions on how to handle this? Any way to minimally change the new suggest RECT such that it ensures the window w/h is as suggested, but it's positioned so it doesn't fire another DPICHANGED event (stays on the new monitor).
Thanks!