Поделиться через


Настройка осведомленности по умолчанию о 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.