IsProcessDPIAware всегда возвращает true

Выполнение следующего в немодифицированном проекте по умолчанию, созданном в 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);

Я запускаю Vista и Windows 7 в vwmare, если это имеет значение.


person jack    schedule 13.11.2010    source источник


Ответы (2)


Есть три условия, которые заставляют учитывать DPI в Windows 7 независимо от манифеста:

  • Виртуализация DPI глобально отключена (параметр «Использовать масштабирование DPI в стиле Windows XP»).
  • Композиция рабочего стола отключена для текущего рабочего стола (либо выбрана тема, отличная от Aero, либо аппаратное ускорение недоступно, обратите внимание, что это означает, что учет DPI всегда включен при работе на виртуальной машине HyperV!< /эм>).
  • Масштабирование экрана отключено в настройках совместимости.

Обратите внимание, что ни один из других параметров совместимости не меняет этого. Выбор параметра «Отключить композицию рабочего стола» отключит композицию рабочего стола при инициализации процесса, но после того, как будет выполнена проверка принудительного определения DPI, в результате запуска более одного экземпляра первый экземпляр не будет иметь принудительное определение DPI, а последующие будут иметь.

Осведомленность о DPI принудительно устанавливается флагом 0x20000000 в TEB->Win32ClientInfo.CI_flags. Это инициализируется в 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;
}
person poizan42    schedule 13.09.2018

Включена ли функция DPI Virtualiztion в ваших системах Vista или Windows 7? Я не уверен, но это может быть причиной того, что IsProcessDPIAware возвращает TRUE.
http://msdn.microsoft.com/en-us/library/dd464660.aspx#setting_dpi_by_using_control_panel

person swatkat    schedule 13.11.2010