WM_DPICHANGED 消息

当窗口的有效的每英寸点数 (dpi) 发生更改时发送。 DPI 是窗口的缩放因子。 有多个事件可能导致 DPI 更改。 以下列表指示 DPI 更改的可能原因。

  • 窗口会移动到一个使用另一 DPI 的新监视器。
  • 承载窗口的监视器的 DPI 会更改。

窗口的当前 DPI 始终等于 WM_DPICHANGED 发送的最后 DPI。 对于了解 DPI 更改的线程,窗口应缩放到该缩放因子。

#define WM_DPICHANGED       0x02E0

参数

wParam

wParamHIWORD 包含窗口新 DPI 的 Y 轴值。 wParamLOWORD 包含窗口新 DPI 的 X 轴值。 例如,96、120、144 或 192。 对于 Windows 应用,X 轴和 Y 轴的值完全相同。

lParam

一个指向 RECT 结构的指针,该结构提供针对新 DPI 进行缩放的当前窗口的建议大小和位置。 我们期望应用会在处理此消息时根据 lParam 提供的建议重新定位窗口并重设窗口大小。

返回值

如果应用程序处理此消息,它应返回零。

注解

此消息仅与 PROCESS_PER_MONITOR_DPI_AWARE 应用程序或 DPI_AWARENESS_PER_MONITOR_AWARE 线程相关。 如果顶级窗口或进程以“DPI 未感知”或“系统 DPI 感知”方式运行,则可能会在某些 DPI 更改时收到该消息,但在这些情况下,可以放心地忽略该消息。 有关不同类型感知的详细信息,请参阅 PROCESS_DPI_AWARENESSDPI_AWARENESS。 旧版 Windows 要求将 DPI 感知绑定到应用程序级别。 这些应用使用 PROCESS_DPI_AWARENESS。 目前,DPI 感知与线程和单个窗口相关,而不是与整个应用程序相关。 这些应用使用 DPI_AWARENESS

缩放应用程序时,只需使用 X 轴或 Y 轴值,因为它们相同。

为了正确处理此消息,需要根据 lParam 提供的建议使用 SetWindowPos 重设窗口大小和重新定位窗口。 如果不这样做,窗口会相对于新显示器上的其他所有内容增大或缩小。 例如,如果用户使用多个显示器并将窗口从 96 DPI 显示器拖动到 192 DPI 显示器,则相对于 192 DPI 显示器上的其他项而言,窗口将显示为一半大。

DPI 的基值定义为 USER_DEFAULT_SCREEN_DPI,后者设置为 96。 若要确定显示器的缩放因子,请获取 DPI 值并将其除以 USER_DEFAULT_SCREEN_DPI。 下表提供了一些示例 DPI 值和相关缩放因子。

DPI 值 缩放百分比
96 100%
120 125%
144 150%
192 200%

以下示例提供示例 DPI 更改处理程序。

    case WM_DPICHANGED:
    {
        g_dpi = HIWORD(wParam);
        UpdateDpiDependentFontsAndResources();

        RECT* const prcNewWindow = (RECT*)lParam;
        SetWindowPos(hWnd,
            NULL,
            prcNewWindow ->left,
            prcNewWindow ->top,
            prcNewWindow->right - prcNewWindow->left,
            prcNewWindow->bottom - prcNewWindow->top,
            SWP_NOZORDER | SWP_NOACTIVATE);
        break;
    }

以下代码将值从 100% (96 DPI) 线性缩放到由 g_dpi 定义的任意 DPI。

    INT iBorderWidth100 = 5;
    iBorderWidth = MulDiv(iBorderWidth100, g_dpi, USER_DEFAULT_SCREEN_DPI);

缩放值的另一种方法是将 DPI 值转换为缩放因子并使用它。

    INT iBorderWidth100 = 5;
    FLOAT fscale = (float) g_dpi / USER_DEFAULT_SCREEN_DPI;
    iBorderWidth = iBorderWidth100 * fscale;

要求

要求
最低受支持的客户端
Windows 8.1 [仅限桌面应用]
最低受支持的服务器
Windows Server 2012 R2 [仅限桌面应用]
标头
WinUser.h

另请参阅

DPI_AWARENESS

PROCESS_DPI_AWARENESS