1

在 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,如果这很重要的话。

4

2 回答 2

1

无论清单如何,在 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;
}
于 2018-09-13T09:29:22.013 回答
0

您的 Vista 或 Windows 7 系统中是否启用了DPI虚拟化?我不确定,但这可能是IsProcessDPIAware返回的原因TRUE
http://msdn.microsoft.com/en-us/library/dd464660.aspx#setting_dpi_by_using_control_panel

于 2010-11-13T18:15:28.537 回答