c++ - 如何在 DPI 感知 win 应用程序上缩放标题栏?

标签 c++ winapi windows-8.1 dpi windows-10

我通过设置 <dpiAware>True/PM</dpiAware> 让我的应用程序在每台显示器上都能感知 dpi在 list 文件中。我可以使用进程资源管理器验证这确实有效,或者通过调用 GetProcessDpiAwareness。

这一切都很好,我可以在我的代码中很好地扩展客户区域中的任何内容。但是,我唯一的问题是,如果我将应用程序从系统 dpi 监视器拖到非系统 dpi 监视器,标题栏和任何系统菜单要么变得太大,要么太小。对于大多数内置应用程序(例如 calc、edge browser 等)来说,情况并非如此,因此必须有足够的空间来正确缩放它。有人知道 MS 的开发人员是如何做到这一点的吗?

下面的截图应该能更好地解释我的问题。另请注意,在缩放 (96dpi) 时,关闭、最小和最大按钮之间的填充是不同的。

Screenshot

Sample app我正在附加一个非常简单的应用程序,它可以感知每个显示器的 dpi。

最佳答案

Windows 10 周年更新 (v1607) 添加了一个新的 API,您必须调用它才能启用非客户端区域的 DPI 缩放:EnableNonClientDpiScaling .这个函数应该被调用,当WM_NCCREATE收到。消息在窗口创建期间被发送到窗口的过程回调。

例子:

case WM_NCCREATE:
{
    if (!EnableNonClientDpiScaling(hWnd))
    {
        // Error handling
        return FALSE;
    }

    return DefWindowProcW(...);
}

如果应用程序的 DPI 感知上下文是 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2,则应省略调用 EnableNonClientDpiScaling,因为它不会有任何效果,尽管该函数仍会成功返回.

来自 the documentation :

Non-client scaling for top-level windows is not enabled by default. You must call this API to enable it for each individual top-level window for which you wish to have the non-client area scale automatically. Once you do, there is no way to disable it. Enabling non-client scaling means that all the areas drawn by the system for the window will automatically scale in response to DPI changes on the window. That includes areas like the caption bar, the scrollbars, and the menu bar. You want to call EnableNonClientDpiScaling when you want the operating system to be responsible for rendering these areas automatically at the correct size based on the API of the monitor.

this blog post有关 Windows 10 AU 中 DPI 缩放更改的更多信息。

关于c++ - 如何在 DPI 感知 win 应用程序上缩放标题栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31781767/

相关文章:

php - 使用 boost 进程间库的 php exec 的共享内存和 Cloudfoundry 容器问题

winapi - GlobalFree() 导致用户断点...内存块是固定的,未锁定,单个模块,无 DLL

windows - 符号链接(symbolic link)限制 - Windows

c# - HttpClient.GetStringAsync(url) 抛出 "The underlying connection was closed: An unexpected error occurred on a send."Windows 8.1 C#

c# - 在 Windows 8.1 中启用 Windows 身份验证

C++数据库通信库

c++ - 将 QString 转换为 Local8bit,然后将 String 转换为 QString

c++ - 查找数字字段中的最大总和

c++ - Win32应用程序调用C代码

windows - 在 Windows 8 上声明每个窗口的高 DPI 感知