8

我有一个使用 MFC 在 VS2008 中创建的程序。现在我已经对其进行了修改,使其成为“Per Monitor DPI-Aware”,几乎完成了。我已经修改了清单并处理了 WM_DPICHANGE 消息。但是还有一个问题:

我使用CFileDialog类显示打开/保存对话框,并使用SHBrowseForFolder函数显示文件夹选择对话框。但是所有这些对话框都不是 Per Monitor DPI-Aware”,当您在具有不同 DPI 设置的监视器之间移动它们时,它们不会调整它们的 UI。

我使用 spy++ 来监视这些对话框的消息,我发现他们可以收到 WM_DPICHANGED 消息,但他们只是不处理它。

我已经在 Windows 10 上测试了 notepad.exe 中的打开文件对话框,它运行良好。

有谁知道如何使这些对话框“每监视器 DPI-Aware”?

--------编辑--------

还有两个问题:

  1. 当我将窗口移动到具有不同 DPI 的监视器时,窗口会自行调整大小,但标题栏的高度和标题字体大小不会改变。
  2. 复选框控件的框大小也没有改变。

我觉得这些问题可能有某种联系,但我想不通。

--------悲伤的消息--------

我用VS2013编译了微软的“DPI Tutorial Sample”,也出现了同样的问题。

https://code.msdn.microsoft.com/DPI-Tutorial-sample-64134744

4

2 回答 2

1

可以通过调用EnableNonClientDpiScaling来缩放标题栏(标题栏) ,这在 Windows >= Windows 10 周年更新 (1607) 的版本上可用。

如果要对不支持按监视器 DPI 缩放的旧对话框进行 DPI 缩放,可以使用SetThreadDpiAwarenessContext(使用 DPI_AWARENESS_CONTEXT_SYSTEM_AWARE 或 DPI_AWARENESS_CONTEXT_UNAWARE)使对话框的顶级窗口由 Windows 缩放。该对话框可能会模糊,但至少可以正确调整大小(也仅适用于 >= 1607 的 Windows 10 版本)。使用模式是在打开对话框之前调用此 API,然后在调用 API 后立即恢复之前的 DPI 上下文。

于 2016-09-06T21:50:18.653 回答
0

根据MSDN,处理WM_DPICHANGED消息的窗口应该返回 0。但是,您发送的任何 MFC 窗口或控件都WM_DPICHANGED将返回 0,因为它们为未知消息调用了默认窗口过程。

WM_DPICHANGED因此,通过测试其LRESULT返回值是否为零来判断某个窗口是否确实处理消息是不准确的。

如MSDN中所述,在跨不同 DPI 监视器移动时,每个监视器 DPI 感知应用程序的窗口标题栏不会缩放。不幸的是,窗口的非客户区永远不会调整 DPI。

计算器和其他每台显示器 DPI 感知 Windows 本机应用程序具有自定义标题栏绘图,如此所述。

于 2016-04-18T10:25:31.207 回答