Существует три условия, которые заставляют осведомленность о 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;
}