1

I have a Windows application with floating windows. I am running it on a multi-monitor setup (FHD, 4K). The application is marked as system-aware, so we pick the current DPI value for the primary monitor and scale according to that. After that, the OS bitmap-scales it. The application is running on Windows 10.

Now, when one of the floating windows is dragged to another monitor, the OS bitmap-scales it automatically, and it all works fine.

The problem is that we have some windows without a title bar, and we have code to move those windows by dragging from the client area of the window. When the mouse is released, we call the MoveWindow() API to move the window to the target location. This works fine on a single monitor, but when we drop the window on a different monitor, it does not bitmap-scale, it seems to lose its drop location. The OS only seems to bitmap-scale when we drag a window by its title bar and not when it is moved programmatically.

Any ideas on how this automatic scaling can be achieved when moving a window programmatically?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
A9S6
  • 6,575
  • 10
  • 50
  • 82
  • Why don't you handle `WM_NCHITTEST` on windows that don't have a titlebar, returning `HTCAPTION`, and have the system deal with everything else? – IInspectable Sep 25 '21 at 15:16
  • These floating windows are actually custom made dockable toolbars created using title-less windows. The mouse movement is tracked to see if it will dock at the current location. Its all existing old code and I am trying to figure out why manual dragging scales the window but MoveWindow does not. – A9S6 Sep 25 '21 at 15:25
  • Even with handling `WM_NCHITTEST` the window does not scale. The only improvement I see is that it does not oddly jump to a different location. I had previously tried simulating a `WM_NCLBUTTONDOWN` on a `WM_LBUTTONDOWN` and it simulated the drag but the window still didn't scale when moved to another screen – A9S6 Sep 25 '21 at 16:19
  • Another way to let the OS drag a title-less window for you is to send the window a `WM_SYSCOMMAND` message with the undocumented but well-known `SC_DRAGMOVE` (0xF012) command. – Remy Lebeau Sep 26 '21 at 07:13
  • Ensure you [asked for PMv2](https://blogs.windows.com/windowsdeveloper/2017/04/04/high-dpi-scaling-improvements-desktop-applications-windows-10-creators-update/). – Hans Passant Sep 26 '21 at 07:47
  • I suggest you could try to use [SetWindowPos function (winuser.h)](https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setwindowpos?redirectedfrom=MSDN) to move it. You could refer to the thread:https://stackoverflow.com/questions/51757438/how-can-i-get-a-borderless-child-window-to-re-scale-to-current-screen-in-multi-m – Jeaninez - MSFT Sep 27 '21 at 03:19
  • I tried SC_DRAGMOVE and SetWindowPos and none worked for me. It would move the window but wouldn't scale it. I've posted an answer on how I fixed it – A9S6 Sep 28 '21 at 09:29

1 Answers1

0

So it depends on how the window is created. I fixed it by creating the window using WS_CAPTION style and then removing that style later. I am not sure what is does internally but it now scales correctly when it is moved to another screen either through mouse-drag or by using an API such as MoveWindow.

::CreateWindowEx(WS_EX_PALETTEWINDOW,...,..., WS_POPUP | WS_CAPTION,...);
::SetWindowLong(hWnd, GWL_STYLE, ::GetWindowLong(hWnd, GWL_STYLE) & ~WS_CAPTION);
A9S6
  • 6,575
  • 10
  • 50
  • 82