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


Основные сведения о проблемах масштабирования экрана

Windows Vista и более поздние версии операционной системы позволяют пользователям изменять точки на дюйм (dpi), чтобы большинство элементов пользовательского интерфейса на экране отображались больше. В более ранних версиях Windows масштабирование должно быть реализовано приложениями. В Windows Vista и более поздних версиях диспетчер окон рабочего стола (DWM) выполняет масштабирование по умолчанию для всех приложений, которые не обрабатывают собственное масштабирование. Клиентские приложения службы автоматизации пользовательского интерфейса Майкрософт должны учитывать эту функцию.

В этом разделе содержатся следующие разделы:

Масштабирование в Windows Vista и более поздних версиях

Параметр dpi по умолчанию равен 96, что означает, что 96 пикселей занимают ширину или высоту одного нотального дюйма. Точное измерение "дюйма" зависит от размера и физического разрешения монитора. Например, на мониторе 12 дюймов в ширину при горизонтальном разрешении 1280 пикселей горизонтальная линия 96 пикселей расширяется примерно на 9/10 дюйма.

Изменение параметра dpi не совпадает с изменением разрешения экрана. При масштабировании dpi количество физических пикселей на экране остается неизменным. Однако масштабирование применяется к размеру и расположению элементов пользовательского интерфейса. Это масштабирование можно выполнять автоматически с помощью DWM для настольных компьютеров и приложений, которые явно не запрашивают масштабирование.

По сути, когда пользователь устанавливает коэффициент масштабирования на 120 dpi, вертикальный или горизонтальный дюйм на экране становится больше на 25 процентов. Все измерения масштабируются соответствующим образом. Смещение окна приложения с верхнего края и левого края экрана увеличивается на 25 процентов. Если масштабирование приложений включено, и приложение не учитывает dpi, размер окна увеличивается в той же пропорции, а также смещения и размеры всех элементов пользовательского интерфейса, содержащихся в нем.

Заметка

По умолчанию DWM не выполняет масштабирование для приложений, не учитывающих DPI, если пользователь устанавливает значение 120 dpi, но выполняет масштабирование, если для dpi задано настраиваемое значение 144 или больше. Однако пользователь может переопределить поведение по умолчанию.

 

Масштабирование экрана создает новые проблемы для приложений, которые каким-либо образом связаны с координатами экрана. Теперь экран содержит две системы координат: физические и логические. Физические координаты точки — это фактическое смещение в пикселях в левом верхнем углу точки источника. Логические координаты — это смещения, которые были бы, если бы масштабирование применялось непосредственно к пикселям.

Предположим, что вы разрабатываете диалоговое окно с кнопкой с координатами (100, 48). Если это диалоговое окно отображается по умолчанию 96 dpi, кнопка находится в физических координатах (100, 48). В 120 dpi он расположен в физических координатах (125, 60). Но логические координаты одинаковы при любом параметре dpi: (100, 48).

Логические координаты важны, так как они делают поведение операционной системы и приложений согласованными независимо от параметра dpi. Например, обычно функция GetCursorPos возвращает логические координаты. При перемещении курсора над элементом в диалоговом окне возвращаются те же координаты независимо от параметра dpi. Если вы размещаете элемент управления в координатах (100, 100), он отрисовывается на этих логических координатах и будет занимать ту же относительную позицию при любом значении dpi.

Масштабирование в клиентах автоматизации пользовательского интерфейса

API автоматизации пользовательского интерфейса не использует логические координаты. Следующие методы и свойства возвращают физические координаты или принимают физические координаты в качестве параметров.

По умолчанию приложения автоматизации пользовательского интерфейса, работающие в среде, где значение не установлено на 96 dpi, не получат правильные результаты от этих методов и свойств. Например, так как позиция курсора находится в логических координатах, клиент не может передать эти координаты в IUIAutomation::ElementFromPoint, чтобы получить элемент, расположенный под курсором. Кроме того, приложение не сможет правильно размещать окна за пределами клиентской области.

Решение состоит из двух частей.

Во-первых, сделайте клиентское приложение чувствительным к dpi. Для этого вызовите функцию SetProcessDPIAware при запуске. Эта функция делает весь процесс учитывающим dpi, что означает, что все окна, принадлежащие процессу, остаются немасштабированными.

Во-вторых, чтобы получить координаты курсора, вызовите функцию getPhysicalCursorPos.