Windows 10 自 1703 开始引入第二代的多屏 DPI 机制(PerMonitor V2),而 WPF 框架可以支持此第二代的多屏 DPI 机制。
本文将介绍 WPF 框架利用第二代多屏 DPI 机制进行高 DPI 适配的方法。同时,也介绍低版本的 WPF 或者低版本的操作系统下如何做兼容。
本文内容
添加应用程序清单文件
在你现有 WPF 项目的主项目中需要添加两个文件以支持第二代的多屏 DPI 机制。
- app.manifest (决定性文件)
- app.config (修复 Bug, .NET Framework 4.6.2 及以上可忽略)
▲ 项目中新增的两个文件
默认情况下,app.config 在你创建 WPF 项目的时候就会存在,而 app.manifest 则不是。如果你的项目中已经存在这两个文件,就不需要添加了。
如果你没有 app.config,如何添加?
打开项目属性,然后在属性中选择 .NET Framework 的版本,无论你选择哪个,app.config 都会自动为你添加。
当然,正统的方法是跟下面的 app.manifest 的添加方法相同,你会在下面看到 Visual Studio 新建项中 app.manifest 和 app.config 文件是挨在一起的。
如果你没有 app.manifest,如何添加?
▲ 新建文件的时候选择应用程序清单文件(应用程序配置文件就在旁边)
了解 WPF 清单文件中的 DPI 感知设置
DpiAware
在你打开了 app.manifest 文件后,找到以下代码,然后取消注释:
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
-->
上面这一段代码是普通的 DPI 感知的清单设置,开启后获得系统 DPI 感知级别(System DPI Awareness)。
如果要开启 Per-Monitor DPI 感知,将上面的 true
改成 true/pm
(pm 表示 per-monitor)。
不过这只是兼容性的设计而已,感谢老版本的系统使用字符串包含的方式,于是可以老版本的系统可以兼容新的 DPI 感知值:
- 什么都不填
- 如果你额外也没做什么 DPI 相关的操作,那么就是 Unaware。
- 如果你在程序启动的时候调用了 SetProcessDpiAwareness 或 SetProcessDPIAware 函数,那么就会按照调用此函数的效果来感知 DPI。
- 包含
true
字符串- 当前进程设置为系统级 DPI 感知(System DPI Awareness)。
- 包含
false
字符串- 在 Windows Vista / 7 / 8 中,与什么都不填的效果是一样的。
- 在 Windows 8.1 / 10 中,当前进程设置为不感知 DPI(Unaware),就算你调用了