Настройка осведомленности по умолчанию о DPI для процесса
Классические приложения в Windows могут работать в разных режимах осведомленности о DPI. Эти режимы позволяют использовать различные режимы масштабирования DPI и могут использовать разные пространства координат. Дополнительные сведения о поддержке DPI см. в статье "Разработка классических приложений с высоким уровнем DPI на платформе Windows". Важно явно задать режим осведомленности о DPI по умолчанию для процесса, чтобы избежать непредвиденного поведения.
Существует два основных метода для указания осведомленности о DPI по умолчанию для процесса:
1) с помощью параметра манифеста приложения
2) программным путем через вызов API
Мы рекомендуем указать использование DPI по умолчанию для процесса с помощью параметра манифеста. Указание значения по умолчанию через API поддерживается, но не рекомендуется.
Настройка осведомленности по умолчанию с помощью манифеста приложения
Существует два параметра манифеста, которые позволяют указать режим осведомленности о DPI по умолчанию процесса: <dpiAwareness> и <dpiAware>. <DpiAware> была представлена в Windows Vista и позволяет задать уровень осведомленности о системе только по умолчанию. <dpiAwareness> появился в Windows 10 версии 1607 и позволяет указать упорядоченный список режимов осведомленности DPI по умолчанию. Это позволяет задать резервные режимы DPI-осведомленности, которые будут использоваться, если приложение запущено в версии Windows, которая не поддерживает первый указанный режим осведомленности. В более старых версиях Windows более новый <тег dpiAwareness> будет игнорироваться. Это означает, что вы можете использовать оба этих параметра манифеста, чтобы включить сценарий, в котором в вашем процессе по умолчанию учитывается система на более старых версиях Windows, оставаясь Per-Monitor на версиях, превышающих Windows 10, версия 1607. В Windows 10 версии 1607 и выше параметр <dpiAware> игнорируется, если присутствует элемент <dpiAwareness>.
В таблице ниже показано, как указать различные режимы определения DPI по умолчанию, используя два параметра манифеста:
Режим учета DPI по умолчанию | <Параметр dpiAware> |
<Параметр dpiAwareness> (Windows 10, версия 1607 и более поздние версии) |
---|---|---|
не подозревающий | N/A (без параметра dpiAware в манифесте) или <dpiAware>false</dpiAware> |
<dpiAwareness>неосведомленный</dpiAwareness> |
Осведомленность системы | <dpiAware>true</dpiAware> | <dpiAwareness>система</dpiAwareness> |
На каждый монитор | <dpiAware>true/pm<dpiAware> | <dpiAwareness>PerMonitor</dpiAwareness> |
На монитор версии 2 | Не поддерживается | <dpiAwareness PerMonitorV2>/dpiAwareness<> |
В приведенном ниже примере показано использование как <dpiAwareness>, так и <dpiAware> в одном файле манифеста для настройки поведения осведомленности DPI по умолчанию процесса для различных версий Windows.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
Настройка осведомленности по умолчанию программным способом
Хотя это не рекомендуется, можно программно задать уровень осведомленности о DPI по умолчанию. После создания окна (HWND) в процессе изменение режима осведомленности о DPI больше не поддерживается. Если вы задаете режим осведомленности о DPI по умолчанию для процесса программно, необходимо вызвать соответствующий API перед созданием каких-либо HWND.
Существует несколько API, которые позволяют указать осведомленность о DPI по умолчанию для процесса. Текущий рекомендуемый API — SetProcessDpiAwarenessContext, так как старые API предлагают меньше функциональных возможностей.
API | Минимальная версия Windows | DPI не знает | Учет системного DPI | Учет DPI для каждого монитора |
---|---|---|---|---|
SetProcessDPIAware | Windows Vista | Н/П | SetProcessDPIAware() | Н/П |
SetProcessDpiAwareness | Windows 8.1 | SetProcessDpiAwareness(PROCESS_DPI_UNAWARE) | SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE) | SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) |
SetProcessDpiAwarenessContext | Windows 10, версия 1607 | SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE) | Функция SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE) используется для настройки осведомленности программы о системном DPI. | SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) |
Процесс по умолчанию vs. Поток по умолчанию
В этом документе описывается настройка осведомленности о DPI по умолчанию для процесса. Это связано с тем, что Windows 10 представила поддержку запуска нескольких режимов осведомленности о DPI в рамках одного процесса (до Windows 10 весь процесс должен соответствовать одному режиму осведомленности DPI). Поддержка запуска нескольких режимов осведомленности о DPI в процессе называется "масштабированием DPI в смешанном режиме". При использовании масштабирования DPI в смешанном режиме в процессе каждое окно верхнего уровня может работать в режиме распознавания DPI, который может отличаться от режима по умолчанию для процесса. Если не указано явно, каждый поток при создании будет использовать настройки по умолчанию процесса. Для получения дополнительной информации о масштабировании DPI в смешанном режиме см. статью Масштабирование DPI в смешанном режиме и DPI-осведомленные API.