如何确保应用程序在高 DPI 显示器上正确显示
尽管 DirectWrite 可解决许多高 DPI 问题,但应采取两个步骤来确保应用程序在高 DPI 显示器上正常工作。
步骤 1:创建窗口后使用窗口自己的 DPI
Direct2D
GetDpiForWindow 函数检索指定窗口的每英寸点数 (dpi) 值。 若要使用该值设置窗口的宽度,请使用以下公式:
< Dpi> * <宽度,以像素> 为单位/ <默认 DPI>
...其中 DPI 是 GetDpiForWindow 重新尝试的值, 默认 DPI 为 96。 垂直轴的公式类似:
< Dpi> * <高度,以像素> 为单位/ <默认垂直 DPI>
创建简单 Direct2D 应用程序的步骤 2.3 中的代码示例检索窗口的 DPI,然后将其大小设置为 640 × 480,缩放到 DPI。
注意
对于通用 Windows 平台 (UWP) 应用,可以使用 DisplayInformation::LogicalDpi 属性。
GDI
GDI 提供 GetDeviceCaps 函数用于检索设备信息。 可以通过传递 LOGPIXELSX 和 LOGPIXELSY 索引值来检索 DPI 信息。 用于确定窗口的水平和垂直大小的公式与上面的 Direct2D 示例相同。
以下代码使用 GetDeviceCaps 函数创建一个缩放为系统 DPI 的 640 x 480 窗口。
FLOAT dpiX, dpiY;
HDC screen = GetDC(0);
dpiX = static_cast<FLOAT>(GetDeviceCaps(screen, LOGPIXELSX));
dpiY = static_cast<FLOAT>(GetDeviceCaps(screen, LOGPIXELSY));
ReleaseDC(0, screen);
hWnd = CreateWindow(
TEXT("DirectWriteApp"),
TEXT("DirectWrite Demo App"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<INT>(dpiX * 640.f / 96.f),
static_cast<INT>(dpiY * 480.f / 96.f),
NULL,
NULL,
hInstance,
NULL);
步骤 2:声明应用程序可感知 DPI
当应用程序声明自己为 DPI 感知时,它是一个语句,指定应用程序在高达 200 DPI 的 DPI 设置下表现良好。 在 Windows Vista 和 Windows 7 中,启用 DPI 虚拟化后,将缩放不感知 DPI 的应用程序,应用程序将从系统 API(如 GetSystemMetric 函数)接收虚拟化数据。 若要声明应用程序可识别 DPI,请完成以下步骤。
创建名为 DeclareDPIAware.manifest 的文件。
将以下 xml 复制到 文件中并保存:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" > <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application> </assembly>
在项目的 .vcproj 文件中,在 VisualStudioProject/Configurations 下的每个 Configuration 元素中添加以下条目:
<Tool Name="VCManifestTool" AdditionalManifestFiles="DeclareDPIAware.manifest"/>