PROCESS_DPI_AWARENESS 枚举 (shellscalingapi.h)

标识每英寸点数 (dpi) 感知值。 DPI 感知指示应用程序为 DPI 执行的缩放工作量与系统完成的缩放量。

用户可以在其显示器上设置 DPI 比例系数,彼此独立。 某些旧版应用程序无法针对多个 DPI 设置调整其缩放比例。 为了使用户能够使用这些应用程序,而不会在显示器上显示太大或太小的内容,Windows 可以将 DPI 虚拟化应用于应用程序,使系统自动缩放该应用程序以匹配当前显示器的 DPI。 PROCESS_DPI_AWARENESS值指示应用程序自行处理的缩放级别以及 Windows 提供的缩放级别。 请记住,系统缩放的应用程序可能看起来模糊,并且会读取有关监视器的虚拟化数据以保持兼容性。

语法

typedef enum PROCESS_DPI_AWARENESS {
  PROCESS_DPI_UNAWARE = 0,
  PROCESS_SYSTEM_DPI_AWARE = 1,
  PROCESS_PER_MONITOR_DPI_AWARE = 2
} ;

常量

 
PROCESS_DPI_UNAWARE
值: 0
DPI 不知道。 此应用不会缩放 DPI 更改,并且始终假定其比例系数为 100% (96 DPI) 。 系统将在任何其他 DPI 设置上自动缩放它。
PROCESS_SYSTEM_DPI_AWARE
值:1
系统 DPI 感知。 此应用不会缩放 DPI 更改。 它将查询 DPI 一次,并在应用的生存期内使用该值。 如果 DPI 发生更改,应用将不会调整为新的 DPI 值。 当 DPI 与系统值发生更改时,系统会自动纵向扩展或缩减它。
PROCESS_PER_MONITOR_DPI_AWARE
值: 2
按监视器 DPI 感知。 此应用在创建 DPI 时检查 DPI,并在 DPI 发生更改时调整比例系数。 系统不会自动缩放这些应用程序。

注解

重要说明  

以前版本的 Windows 要求设置整个应用程序的 DPI 感知。 现在 DPI 感知已绑定到单个线程、进程或窗口。 这意味着,当应用运行时,DPI 感知可能会更改,并且多个窗口可以有自己的独立 DPI 感知值。 有关 DPI 感知当前工作原理的详细信息,请参阅 DPI_AWARENESS 。 以下有关在应用程序清单中设置 DPI 感知的建议仍受支持,但当前建议使用 DPI_AWARENESS_CONTEXT

 
应用程序的 DPI 感知应通过应用程序清单进行设置,以便在执行依赖于系统的 DPI 的任何操作之前确定它。 或者,可以使用 SetProcessDpiAwareness 设置 DPI 感知,但如果这样做,则需要确保在执行依赖于系统 DPI 的任何操作之前对其进行设置。 为进程设置 DPI 感知后,无法更改它。
提示  

如果应用 PROCESS_DPI_UNAWARE,则无需在应用程序清单中设置任何值。 除非 指定了其他值,否则PROCESS_DPI_UNAWARE是应用的默认值。

 
PROCESS_DPI_UNAWAREPROCESS_SYSTEM_DPI_AWARE 应用不需要响应 WM_DPICHANGED ,并且不需要处理 DPI 中的更改。 当 DPI 更改时,系统会根据需要自动纵向扩展或缩减这些类型的应用。 PROCESS_PER_MONITOR_DPI_AWARE 应用负责识别和响应由 WM_DPICHANGED发出信号的 DPI 更改。 系统不会缩放这些内容。 如果此类型的应用不调整窗口及其内容的大小,则当窗口从具有不同 DPI 设置的另一个显示器移动到另一个显示器时,它似乎会随着相对 DPI 变化而增大或收缩。
提示  

在以前版本的 Windows 中,没有 PROCESS_PER_MONITOR_DPI_AWARE设置。 应用要么没有 DPI 感知,要么是 DPI 感知。 在Windows 8.1之前分类为 DPI 感知的旧版应用程序被视为当前版本的 Windows 中具有PROCESS_SYSTEM_DPI_AWARE PROCESS_DPI_AWARENESS设置。

 
若要了解不同 DPI 感知值的重要性和影响,请考虑有三个显示器的用户:A、B 和 C。显示 A 设置为 100% 缩放因子 (96 DPI) ,将显示器 B 设置为 200% 缩放因子 (192 DPI) ,显示 C 设置为 300% 缩放因子 (288 DPI) 。 系统 DPI 设置为 200%。

PROCESS_DPI_UNAWARE的应用程序将始终使用 100% (96 DPI) 比例系数。 在此方案中,将创建大小为 500 乘以 500 的 PROCESS_DPI_UNAWARE 窗口。 在显示 A 上,它将以本机方式呈现,无需缩放。 在显示器 B 和 C 上,系统将分别自动纵向扩展 2 和 3。 这是因为 PROCESS_DPI_UNAWARE 始终假定 DPI 为 96,而系统为此负责。 如果应用查询窗口大小,它将始终获得 500 乘 500 的值,无论它位于什么屏幕中。 如果此应用请求三个监视器中的任何一个的 DPI,它将收到 96。

现在考虑一个 PROCESS_SYSTEM_DPI_AWARE的应用程序。 请记住,在示例中,系统 DPI 为 200% 或 192 DPI。 这意味着此应用创建的任何窗口将以本机方式呈现在显示 B 上。它窗口移动以显示 A,它将自动按 2 因子缩小。 这是因为此方案中 PROCESS_SYSTEM_DPI_AWARE 应用假定 DPI 始终为 192。 它会在启动时查询 DPI,然后从不更改它。 系统通过在移动到显示 A 时自动纵向缩减来适应这种情况。同样,如果窗口移动到显示 C,系统将自动纵向扩展 1.5。 如果应用查询窗口大小,它将始终获得相同的值,类似于 PROCESS_DPI_UNAWARE。 如果请求三个监视器中的任何一个的 DPI,它将收到 192。

与其他感知值不同, PROCESS_PER_MONITOR_DPI_AWARE 应适应其打开的显示。 这意味着它始终以本机方式呈现,并且永远不会由系统缩放。 应用负责在接收 WM_DPICHANGED 消息时调整比例系数。 此消息的一部分包括窗口的建议矩形。 此建议是从旧 DPI 值缩放到新 DPI 值的当前窗口。 例如,在显示 A 上为 500 乘以 500 且移动到显示 B 的窗口将收到建议的窗口矩形,即 1000 乘以 1000。 如果将同一窗口移动到显示 C,则附加到 WM_DPICHANGED 的建议窗口矩形将为 1500 到 1500。 此外,当此应用查询窗口大小时,它将始终获取实际的本机值。 同样,如果请求三个监视器中的任何一个的 DPI,它将分别收到 96、192 和 288。

由于 DPI 虚拟化,如果一个应用程序以不同的感知级别查询另一个应用程序以获取与 DPI 相关的信息,系统将自动缩放值以匹配调用者的感知级别。 例如,调用 GetWindowRect 并传入由另一个应用程序创建的窗口。 使用上述情况,假设 PROCESS_DPI_UNAWARE 应用在显示 C 上创建了一个 500 乘以 500 的窗口。如果从其他应用程序查询窗口矩形,则 rect 的大小将因应用的 DPI 感知而异。

PROCESS_DPI_UNAWARE 你将得到一个 500 乘以 500 的矩形,因为系统将假定 DPI 为 96,并自动将实际矩形缩小 3。
PROCESS_SYSTEM_DPI_AWARE 你将得到一个 1000 乘 1000 的矩形,因为系统将假定 DPI 为 192,并自动按 3/2 的系数缩小实际矩形。
PROCESS_PER_MONITOR_DPI_AWARE 你将获得 1500x1500 矩形,因为系统将使用显示器的实际 DPI,并且不会在后台执行任何缩放。
 

示例

此代码片段演示如何在应用程序清单中设置 值 PROCESS_SYSTEM_DPI_AWARE

<dpiAware>true</dpiAware>

此代码片段演示如何在应用程序清单中设置 值 PROCESS_PER_MONITOR_DPI_AWARE

<dpiAware>true/PM</dpiAware>

要求

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

另请参阅

DPI_AWARENESS