简体   繁体   中英

IsProcessDPIAware always returns true

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.

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

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM