Windows 8.1引入了为不同监视器提供不同DPI设置的功能.此功能称为"每监视器高DPI支持".它在Windows 10中持续存在并得到进一步完善.
如果应用程序没有选择加入(即,DPI不知道或高DPI意识),它将由DWM自动扩展到正确的DPI.大多数应用程序属于这两个类别之一,包括与Windows捆绑在一起的大多数实用程序(例如,记事本).在我的测试系统上,高DPI监视器设置为150%标度(144 DPI),而普通监视器设置为系统DPI(100%标度,96 DPI).因此,当您在高DPI屏幕上打开其中一个应用程序(或将其拖到那里)时,虚拟化会启动,放大所有内容,但也会让它变得非常模糊.
另一方面,如果应用程序明确指出它支持每个监视器的高DPI,则不执行虚拟化,并且开发人员负责扩展.微软在这里有一个相当全面的解释*,但为了一个独立的问题,我将总结一下.首先,通过<dpiAware>True/PM</dpiAware>在清单中设置来指示支持.这会选择接收WM_DPICHANGED消息,它会告诉您新的DPI设置以及窗口的建议新大小和位置.它还允许您调用GetDpiForMonitor函数并获取实际 DPI,而不会因兼容性原因而被欺骗.肯尼克尔也写了一个全面的教程.
我已经在一个小小的C++测试应用程序中成功完成了所有这些工作.这是很多样板和大多数项目设置,所以我在这里发布一个完整的例子并不是很重要.如果您想测试它,请遵循Kenny的说明,MSDN上的本教程,或下载官方SDK示例.现在,客户端区域中的文本看起来很好(因为我的处理WM_DPICHANGED),但由于不再执行虚拟化,因此不会缩放非客户区域.结果是标题/标题栏和菜单栏的大小错误 - 它们在高DPI屏幕上不会变大:
所以问题是,如何让窗口的非客户区扩展到新的DPI?
无论您是创建自己的窗口类还是使用对话框,它们在这方面都具有相同的行为.
它已经表明,有是没有答案,那你唯一的选择是自定义绘制整个窗口,包括非客户区.虽然这当然是可能的,实际上UWP应用程序(以前称为Metro)的功能,例如Windows 10计算器,对于使用许多非客户端小部件并希望看起来像原生的桌面应用程序来说,它不是一个可行的选择.
除此之外,它显然是错误的.自定义绘制的标题栏不能是获得正确行为的唯一方法,因为Windows shell团队已经完成了它.简洁的"运行"对话框的行为完全符合预期,当您在具有不同DPI的监视器之间拖动时,正确调整客户端和非客户端区域的大小:
使用Spy ++进行的调查证实,这只是一个标准的Win32对话框 - 没什么特别的.所有控件都是标准的Win32 SDK控件.它不是一个UWP应用程序,也没有自定义绘制标题栏 - 它仍然具有WS_CAPTION风格.它是由explorer.exe进程,它推出被标记为每个监视器高DPI感知(使用Process Explorer和GetProcessDpiAwareness验证).此博客文章确认已在Windows 10中重写了"运行"对话框和"命令提示符"以正确扩展(请参阅" 命令shell等 ").Run对话框用于调整其标题栏的大小是什么?
负责新式打开和保存对话框的Common Item Dialog API在从每个监视器高DPI感知的进程启动时也可以正确扩展,如您在Run对话框中单击"Browse"按钮时所看到的.同样的事情任务对话框API,创建奇数情况下的应用程序启动一个对话框,以不同大小的标题栏.(但是,传统的MessageBox …
我有一个在VS2008中使用MFC创建的程序.现在我已经修改它以使其成为"Per Monitor DPI-Aware",它几乎已经完成了.我修改了清单并处理了WM_DPICHANGE消息.但仍有一个问题:
我使用CFileDialog类来显示打开/保存对话框,并使用SHBrowseForFolder函数显示文件夹选择对话框.但是,所有这些对话都是不 "每个监视器DPI感知",当你与不同的DPI设置显示器之间移动他们,他们不会调整自己的UI.
我使用spy ++来监视这些对话框的消息,我发现它们可以接收WM_DPICHANGED消息,但它们只是不处理它.
我已经在Windows 10上的notepad.exe中测试了打开的文件对话框,它运行得很好.
有谁知道如何使这些对话框"Per Monitor DPI-Aware"?
-------- 编辑 --------
还有两个问题:
我觉得这些问题可能有某种联系,但我无法弄清楚.
-------- SAD NEWS --------
我用VS2013编译了microsoft的"DPI Tutorial Sample",它也有同样的问题.
https://code.msdn.microsoft.com/DPI-Tutorial-sample-64134744