0

I am modifying my application to support high-DPI values (above 100%/96dpi).

I modified the application's manifest file to include:

<dpiAware>true/PM</dpiAware>

I am able to handle all the DPI scaling for my own app's forms, but how do I handle standard windows dialogs (Font selector, open files, folder browser, etc) through WinAPI. Is there a way to manually inform windows that I want only these dialogs automatically scaled for the higher DPI?

* Update *

After using the "SetThreadDpiAwarenessContext" WinAPI function, windows does seem to handle the scaling, but it does so in the by scaling the image (blurred text) instead of scaling the controls (remember, these are standard windows controls like the ones generated by calling "GetOpenFileNameW").

Any ideas how to get windows to draw the open-file dialog properly scaled without blurred text?

bLight
  • 803
  • 7
  • 23

1 Answers1

0

Thank you @zett42, to sum up the linked answer for future visitors, Win 10 Aniv. edition introduced a new "SetThreadDpiAwarenessContext()" function to set a per-thread DPI awareness, allowing you to open standard windows dialogs from a separate thread and have the Windows DPI setting automatically handle scaling on the dialog.

bLight
  • 803
  • 7
  • 23
  • 2
    The system dialogs you mention in your question are commonly used as owned dialogs, either modal or modeless. Offloading them to another thread will yield a cross-thread window hierarchy with your other UI. This is not safe. See [Is it legal to have a cross-process parent/child or owner/owned window relationship?](https://blogs.msdn.microsoft.com/oldnewthing/20130412-00/?p=4683). – IInspectable Jun 22 '17 at 11:11
  • @IInspectable You are correct, calling "GetOpenFileNameW" with hwndOwner handle (setting up a modal dialog) from the primary thread triggers a freeze. Is there an elegant solution to this (without having to disable all keyboard and mouse input on the calling window) ? – bLight Jun 22 '17 at 12:20
  • I think you don't need another thread. From the linked answer: _DPI awareness of a window created by the thread will depend on the DPI awareness of the calling thread at the time windows was created_ ... If I understand this correctly, you just need to call `SetThreadDpiAwarenessContext()` before creating one of the common dialogs in your *main thread* and restore it to the previous setting after the dialog has been closed. – zett42 Jun 22 '17 at 13:03
  • The blog post linked in the answer confirms this: _Any API calls that are made after the context is changed will run in the corresponding DPI context (and may be virtualized). When a thread that is running with a given context creates a new top-level window, the new top-level window will be assigned the same context that the thread that created it had, at the time of creation._ – zett42 Jun 22 '17 at 13:08