我通过在清单文件中设置<dpiAware>True/PM</dpiAware>,使我的应用程序能够识别每个监视器的dpi。我可以使用process explorer验证这是否确实有效,或者调用GetProcessDpiAwareness。
这一切都运行得很好,我可以在我的代码中很好地缩放客户端区中的任何内容。然而,我唯一的问题是,如果我将我的应用程序从系统dpi监视器拖到非系统dpi监视器上,标题栏和任何系统菜单都会变得太大或太小。这不是大多数内置应用程序的情况(例如calc、edge browser等)。因此,必须有适当的扩展。有人知道微软的开发人员是怎么做到这一点的吗?
下面的截图应该能更好地解释我的问题。还要注意,close、min和max按钮之间的填充在缩放时是不同的(96dpi)。

Sample app我附加了一个非常简单的应用程序,这是每个显示器的dpi感知。
发布于 2015-08-04 05:48:07
有没有人知道微软的开发人员是怎么做到的?
这有一个相当令人失望的答案。使用Alin Constantin的WinCheat并检查计算器的顶层窗口,我看到窗口大小为320x576,客户端大小也是320x576。
换句话说,Microsoft通过隐藏窗口的非工作区,而将所有内容都放在工作区中,完全避免了这个问题。要想让这个工作对你很好,可能需要自定义标题栏的绘制。
值得注意的是,计算器和Windows资源管理器的标题栏颜色不同。计算器对标题栏进行自定义绘制可以很好地解释这一点。
发布于 2016-09-15 06:57:09
Windows10周年纪念更新(Windows10周年纪念更新)增加了一个新的v1607,您必须调用它才能对非客户端区域进行缩放:EnableNonClientDpiScaling。当接收到WM_NCCREATE时,应调用此函数。在窗口创建期间,消息被发送到窗口的过程回调。
示例:
case WM_NCCREATE:
{
if (!EnableNonClientDpiScaling(hWnd))
{
// Error handling
return FALSE;
}
return DefWindowProcW(...);
}如果应用程序的DPI感知上下文为DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2,则应该省略调用EnableNonClientDpiScaling,因为它不会有任何效果,尽管函数仍将成功返回。
默认情况下,顶级窗口的
非客户端伸缩未启用。您必须调用此API,以便为您希望自动缩放其非工作区的每个单独的顶级窗口启用它。一旦你这样做了,就没有办法禁用它。启用非客户端缩放意味着系统为窗口绘制的所有区域都将自动缩放,以响应窗口上的DPI更改。包括标题栏、滚动条和菜单栏等区域。当您希望操作系统负责根据监视器的应用编程接口以正确的大小自动呈现这些区域时,您需要调用
EnableNonClientDpiScaling。
有关Windows10AU中DPI缩放更改的其他信息,请参阅this blog post。
发布于 2015-10-09 00:09:55
请注意,支持每个显示器的DPI的应用程序的非工作区不会被窗口缩放,并且在高DPI显示上会按比例变小。
您链接的Microsoft应用程序通过删除非客户端区并使客户端区覆盖整个窗口来处理此问题。
https://stackoverflow.com/questions/31781767
复制相似问题