Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Windows Common Dialogs "Per Monitor DPI-Aware"

I have a program which was created in VS2008 with MFC. Now I've modified it to make it "Per Monitor DPI-Aware", and it's almost done. I've modified the manifest and handled the WM_DPICHANGE message. But there's still one problem:

I used CFileDialog class to show Open/Save dialogs, and used SHBrowseForFolder function to show folder selection dialog. But all these dialogs are NOT "Per Monitor DPI-Aware", they won't adjust their UI when you move them between monitors with different DPI settings.

I use spy++ to monitor messages of these dialogs, I find they can receive WM_DPICHANGED message but they just don't handle it.

And I've tested the open file dialog in notepad.exe on Windows 10, it worked perfectly.

Does anyone know how can I make these dialogs "Per Monitor DPI-Aware"?

--------EDIT--------

There're two more problems:

  1. When I move a window to a monitor with different DPI, the window resize itself, but the height of it's title bar and title font-size are not changed.
  2. The checkbox controls' box size is not changed either.

I feel these problems may have some kind of connections, but I can't figure it out.

--------SAD NEWS--------

I compiled microsoft's "DPI Tutorial Sample" with VS2013, and it has the same problem.

https://code.msdn.microsoft.com/DPI-Tutorial-sample-64134744

like image 795
Caspar Lee Avatar asked Feb 17 '16 10:02

Caspar Lee


Video Answer


1 Answers

The titlebar (caption bar) can be scaled by calling EnableNonClientDpiScaling which is available on versions of Windows >= the Windows 10 Anniversary Update (1607).

If you want to DPI scale an older dialog that doesn't support per-monitor DPI scaling you can use SetThreadDpiAwarenessContext (with DPI_AWARENESS_CONTEXT_SYSTEM_AWARE or DPI_AWARENESS_CONTEXT_UNAWARE) to have the top-level windows of the dialog scaled by Windows. The dialog might be blurry but it will at least be sized correctly (also only available on >= 1607 builds of Windows 10). The usage pattern is to call this API before opening the dialog and then restore the previous DPI context immediately after calling the API.

like image 189
peterfelts Avatar answered Sep 19 '22 16:09

peterfelts