IsProcessDPIAware 始终返回 true

发布于 2024-10-01 18:05:02 字数 746 浏览 8 评论 0原文

在 Visual Studio 2005 中创建的默认未修改项目中运行以下命令会在 Vista 和 Windows 7 中显示“是”消息框。有人知道为什么吗? IsProcessDPIAware 的描述如下: http://msdn.microsoft.com /en-us/library/aa969261(VS.85).aspx

HMODULE hUser32 = LoadLibrary(L"user32.dll");
typedef BOOL (*fnPtr)();
fnPtr IsProcessDPIAware = (fnPtr)GetProcAddress(hUser32, "IsProcessDPIAware");
if(IsProcessDPIAware) {
    if(IsProcessDPIAware() == TRUE) {
        MessageBox(NULL, L"yes", NULL, MB_OK);
    }
    else {
        MessageBox(NULL, L"no", NULL, MB_OK);
    }
}
else {
    MessageBox(NULL, L"no fn", NULL, MB_OK);
}
FreeLibrary(hUser32);

我在 vwmare 中运行 vista 和 windows 7,如果这很重要的话。

Running the following in a default unmodified project created in Visual Studio 2005 displays the "yes" message box in both vista and windows 7. Does anyone know why? IsProcessDPIAware is described here: http://msdn.microsoft.com/en-us/library/aa969261(VS.85).aspx.

HMODULE hUser32 = LoadLibrary(L"user32.dll");
typedef BOOL (*fnPtr)();
fnPtr IsProcessDPIAware = (fnPtr)GetProcAddress(hUser32, "IsProcessDPIAware");
if(IsProcessDPIAware) {
    if(IsProcessDPIAware() == TRUE) {
        MessageBox(NULL, L"yes", NULL, MB_OK);
    }
    else {
        MessageBox(NULL, L"no", NULL, MB_OK);
    }
}
else {
    MessageBox(NULL, L"no fn", NULL, MB_OK);
}
FreeLibrary(hUser32);

I'm running both vista and windows 7 in vwmare, if that matters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑕疵 2024-10-08 18:05:02

无论清单如何,在 Windows 7 中强制 DPI 感知的条件有以下三种:

  • DPI 虚拟化全局禁用(“使用 Windows XP 样式 DPI 缩放”设置)
  • 当前桌面禁用桌面合成(或者选择了非 Aero 主题或硬件加速不可用请注意,这意味着在 HyperV VM 中运行时 DPI 感知始终处于开启状态!)。
  • 在兼容性设置中禁用显示缩放。

请注意,其他兼容性设置都不会改变这一点。选择“禁用桌面合成”会在初始化进程时禁用桌面合成,但在进行强制DPI感知检查后,导致启动多个实例会导致第一个实例不具有强制DPI感知,但后续实例具有。

DPI 感知由 TEB->Win32ClientInfo.CI_flags 中设置的标志 0x20000000 强制执行。这是在 win32k!SetAppCompatFlags 中初始化的,一旦 gdi32.dll 调用 NtGdiInit 就会调用它(此初始化在进程入口点运行之前执行)。请注意,在较新版本的 Windows 7 上,仅在 64 位版本的 TEB 中设置此标志。

win32k!SetAppCompatFlags 中的实际代码看起来像

if ( (&threadInfo->dwCompatFlags2 & 0x10000000) || !IsCurrentDesktopComposed() || gbForceDPIAware )
{
  w32ProcessInfo = PsGetCurrentProcessWin32Process();
  w32ProcessInfo->W32PF_Flags |= 0x20000000;
  threadInfo->pClientInfo->CI_flags |= 0x20000000;
}

There are three conditions that forces DPI awareness in Windows 7 regardless of the manifest:

  • DPI Virtualization is globally disabled (the "Use Windows XP style DPI scaling" setting)
  • Desktop composition is disabled for the current desktop (either a non-Aero theme is selected or hardware acceleration in unavailable note that this means that DPI awareness is always on when running in a HyperV VM!).
  • Display scaling is disabled in compatibility settings.

Note that none of the other compatibility settings changes this. Selecting Disable desktop composition will disable desktop composition when initializing the process, but after the check for forcing DPI awareness is made, resulting in starting more than one instance will cause the first one to not have forced DPI awareness, but subsequent ones to have.

DPI awareness is forced by flag 0x20000000 being set in TEB->Win32ClientInfo.CI_flags. This is initialized in win32k!SetAppCompatFlags which will be called once gdi32.dll calls NtGdiInit (this initialization is performed before the process entry point is run). Note that on newer versions of Windows 7 this flag is only set in the 64-bit version of the TEB.

The actual code in win32k!SetAppCompatFlags looks something like

if ( (&threadInfo->dwCompatFlags2 & 0x10000000) || !IsCurrentDesktopComposed() || gbForceDPIAware )
{
  w32ProcessInfo = PsGetCurrentProcessWin32Process();
  w32ProcessInfo->W32PF_Flags |= 0x20000000;
  threadInfo->pClientInfo->CI_flags |= 0x20000000;
}
木槿暧夏七纪年 2024-10-08 18:05:02

您的 Vista 或 Windows 7 系统中是否启用了 DPI Virtualization?我不确定,但这可能是 IsProcessDPIAware 返回 TRUE 的原因。

http://msdn.microsoft.com/en-us/library/dd464660 .aspx#setting_dpi_by_using_control_panel

Is DPI Virtualiztion enabled in your Vista or Windows 7 systems? I am not sure, but it could be the reason that IsProcessDPIAware returns TRUE.
http://msdn.microsoft.com/en-us/library/dd464660.aspx#setting_dpi_by_using_control_panel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文