9

I have a MFC app that has default MFC DPI support: it is high DPI aware, but not per-monitor DPI aware. Windows 10 version 1703 added support for System (enhanced) DPI scaling. I enabled this mode from Windows Explorer in the .exe compatibility settings, and it works for my app.

Ideally, I'd make the app fully multi-monitor DPI compliant, but that's a fair amount of work. So instead, I want to tell the OS to use system (enhanced) DPI scaling for my app, if the OS supports it.

Does the applications's manifest enable this, and if so, what needs to be added or changed?

Additionally, how do I modify the manifest? Currently, I'm using the default Visual Studio 2017 MFC project structure, which doesn't have a manifest file in my project. Instead, the manifest's contents are specified as project properties, and the manifest is generated with mt.exe. Can I inject a change with mt.exe? If I need to replace the manifest with a custom one, what's the easiest way?

Edward Brey
  • 40,302
  • 20
  • 199
  • 253
  • 3
    Yes you can [enable that setting through your manifest](https://blogs.windows.com/buildingapps/2017/05/19/improving-high-dpi-experience-gdi-based-desktop-apps/) (the example is somewhere near the end of that article). – zett42 Sep 26 '17 at 14:31
  • It looks like I need `asmv3:application`, `asmv3:windowsSettings`, and `gdiScaling` elements. Can I add these as an incremental change with the mt.exe auto-generation approach, or do I need to explicitly state the entire manifest by hand? – Edward Brey Sep 26 '17 at 14:47
  • 1
    You can add this as incremental change through project settings > manifest tool > additional manifest files. Files defined there get "merged" with the auto-generated file. – zett42 Sep 26 '17 at 14:56

1 Answers1

14

Add the gdiScaling setting to your application's manifest to tell Windows to apply GDI scaling on all monitors.

  1. Create a new file GdiScaling.manifest in your project.
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2017/WindowsSettings">
      <gdiScaling>true</gdiScaling>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>
  1. In project settings, in Manifest Tool, set Additional Manifest Files to GdiScaling.manifest. This will merge your GDI scaling settings into the rest of the generated manifest.

When you build, you will get a warning about Microsoft not having its act together, but you already knew that. :-) The exact text of the warning is this:

GdiScaling.manifest : manifest authoring warning 81010002: Unrecognized Element "gdiScaling" in namespace "http://schemas.microsoft.com/SMI/2017/WindowsSettings".

Fortunately, Windows doesn't care and recognizes the setting anyway.

Edward Brey
  • 40,302
  • 20
  • 199
  • 253
  • Why? How do you know that `gdiScaling=true` maps to `Override high DPI scaling behavior = System (enhanced)` ? I need to use `System` - without enhanced. That works the best for our app. So what to use here, docs are not clear at all. Maybe `dpiAwareness=system` ? – Zoli Mar 27 '23 at 07:42
  • @Zoli I based my answer on the similar descriptions of two and they have the same effect in practice. System scaling (i.e. fuzzy text scaling) is the default if you don't put anything in the manifest. – Edward Brey Mar 28 '23 at 11:25
  • It was not the case for us, but adding `dpiAwareness=system` did the trick. Not the best, little blurry, but otherwise we have gui glitches. (no resource to implement full 'Application' support for high dpi). Although I have to say after building with VS2019 and using 4.x net, setting 'Application' is surprisingly good. Except some glitch, but I say the 90% which is ok look really nice with high dpi – Zoli Mar 29 '23 at 13:32