Skip to content
Roman Starkov edited this page Apr 2, 2016 · 1 revision

Test results below are from a WPF demo application running on Win10 / .NET 4.6.1, while changing DPI without signing out. "Original DPI" stands for the DPI setting that was active when the user signed in.

For App.manifest dpiAware = "True/PM":

  • Window chrome: scaled to original DPI, except close/maximize/minimize symbols which scale to current DPI (broken)
  • Window content: displayed at original DPI (bad)
  • LOGPIXELSX: original DPI (bad)
  • VirtualScreen / VERTRES: correct
  • DESKTOPVERTRES: correct

For App.manifest dpiAware = "true":

  • Window chrome: shows at current DPI (correct)
  • Window content: bitmap-scaled to current DPI (bad and unfixable)
  • LOGPIXELSX: original DPI (bad but easy workaround)
  • VirtualScreen / VERTRES: scaled relative to original DPI (bad but easy workaround)
  • DESKTOPVERTRES: correct

So, to summarise, neither setting produces acceptable results. dpiAware=true is mostly OK, except for the huge dealbreaker that is bitmap-based scaling. dpiAware=True/PM has broken window chrome and won't rescale window content. Moreover, this setting means that we can't use VERTRES/DESKTOPVERTRES to figure out the difference between original and current DPI.

In other words, WPF doesn't support dynamically changing DPI under either setting, and works well enough if the user signs out and back in under both settings, meaning that it doesn't matter which one you pick.

.NET 4.6.2 might support this properly, also this Microsoft article contains sample code which claims to do the right thing, but uses C++ to implement the required functionality and is said to crash on Windows 7.

Clone this wiki locally