如何创build一个缩放和尺寸变化的Per-Monitor DPI感知应用程序,与Windows 7向后兼容?

我是WPF(和DPI意识API)的新手,正在编写一个在Windows 7,8.1和10中运行的应用程序。我使用多个监视器,每个监视器的DPI设置不同,并且有兴趣将我的应用程序设置为尽可能跨桌面configuration兼容。

我已经知道可以将一个Manifest添加到WPF应用程序中,取消注释DPI感知部分,并将其设置为True/PM 。 这成功地允许该程序在Windows 8.1和Windows 10(每个显示器上看起来清晰而清晰)中的每个显示器支持DPI,但在Windows 7中以系统感知的方式运行。

但是我们可以做得更好吗? 微软在这里提供了一个简洁的教程,展示了如何创build一个每个监视器的DPI-Aware WPF应用程序。 他们所做的实际上是在C ++中创build一个新的对象来replace使用Windows 8.1 API的<Window> ,以便不仅检测监视器之间的DPI更改,还可以在运行时重新调整应用程序的大小 ,从而有效地匹配DPI中的更改。 最终的结果是,不仅应用程序Per-DPI了解清晰,而且在各种尺寸的大型和小型显示器之间切换时,应用程序还会寻找用户在屏幕上更改相同的物理尺寸(以英寸或厘米为单位) 。

微软的Win32代码的缺点是它不能与Windows 7向后兼容。试图在7中运行导致应用程序崩溃。

我已经阅读了Dr.Dobbs上的这篇文章 ,Kenny Karr也阅读了这篇文章,但是不明白这些API是否足以让事情发挥作用。

有谁知道有一种方法可以做类似于微软的代码,在Windows 8.1和更新的版本中,每个监视器感知的应用程序在显示器之间移动时实际上会改变大小 ,但是在Windows 7中以系统感知的方式运行?

我没有看过代码,但我的猜测是崩溃是由于在win 7中缺少本地方法而导致的。解决这个问题的方法是修改本地方法wrapper,例如(伪代码):

 public int GetDPIOfMonitor(IntPtr monitorHandle) { if (Enviroment.OSVersion >= "6.2") // win 8 and above { return NativeMethods.PInvoke.GetMonitorDPI(monitorHandle); } else return systemDPI; } 

这样你就不会在7以下崩溃,因为你没有调用缺少的本地方法。