如何创建与Windows 7向后兼容的缩放和大小更改Per-Monitor DPI感知应用程序?

时间:2015-08-19 12:39:37

标签: c# c++ wpf windows dpi

我是WPF(以及DPI-awareness API)的新手,我正在编写一个在Windows 7,8.1和10中运行的应用程序。我使用具有不同每个监视器DPI设置的多个监视器,我感兴趣使我的应用程序尽可能兼容桌面配置。

我已经知道可以在WPF应用程序中添加Manifest,取消注释DPI感知部分,并将其设置为True/PM。这成功地使程序在Windows 8.1和10中具有Per-Monitor DPI感知能力(因此在各种监视器上看起来干净利落),但在Windows 7中以系统感知的方式运行。

但我们能更好地迈出一步吗? Microsoft提供了neat tutorial here that shows how to create a Per-Monitor DPI-Aware WPF应用程序。 他们所做的实际上是用C ++创建一个新对象来替换使用Windows 8.1 API的<Window>,不仅可以检测监视器之间的DPI变化,还可以重新调整应用程序的大小运行时,有效地匹配DPI的变化。 最终结果是,不仅应用程序Per-DPI能够识别且外观清晰,而且当在各种尺寸的大型和小型显示器之间切换时,应用程序会向用户显示在屏幕上更改相同的物理尺寸(以英寸或厘米为单位)

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

我已经完成了this article on Dr.Dobbsthis one by Kenny Karr,但没有充分了解这些API,以便让事情顺利进行。

有没有人知道一种类似于Microsoft代码的方法,在Windows 8.1及更高版本中,Per-Monitor识别的应用程序在移动时实际上会更改大小监视器,但在Windows 7中作为系统感知运行?

1 个答案:

答案 0 :(得分:-1)

我没有查看代码,但我的猜测是因为在win 7中缺少本机方法而导致崩溃。 解决此问题的方法是修改本机方法包装器,例如(伪代码):

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

这样你就不会在7下崩溃,因为你没有调用丢失的原生方法。