Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
Эта документация предназначена для разработчиков .NET Framework, которые хотят использовать управляемые классы автоматизации пользовательского интерфейса, определенные в пространстве имен System.Windows.Automation. Последние сведения об автоматизации пользовательского интерфейса см. в разделе API автоматизации Windows: автоматизация пользовательского интерфейса.
Начиная с Windows Vista, Windows позволяет пользователям изменять точки на дюйм (dpi), чтобы большинство элементов пользовательского интерфейса на экране отображались больше. Хотя эта функция уже давно доступна в Windows, в предыдущих версиях масштабирование должно быть реализовано приложениями. Начиная с Windows Vista диспетчер окон рабочего стола выполняет масштабирование по умолчанию для всех приложений, которые не обрабатывают собственное масштабирование. Клиентские приложения службы автоматизации пользовательского интерфейса должны учитывать эту функцию.
Масштабирование в Windows Vista
Параметр dpi по умолчанию равен 96, что означает, что 96 пикселей занимают ширину или высоту одного нотального дюйма. Точное измерение "дюйма" зависит от размера и физического разрешения монитора. Например, на мониторе 12 дюймов в ширину при горизонтальном разрешении 1280 пикселей горизонтальная линия 96 пикселей расширяется примерно на 9/10 дюйма.
Изменение параметра dpi не совпадает с изменением разрешения экрана. При масштабировании dpi количество физических пикселей на экране остается неизменным. Однако масштабирование применяется к размеру и расположению элементов пользовательского интерфейса. Это масштабирование можно выполнять автоматически диспетчером окон рабочих столов (DWM) для рабочего стола и для приложений, которые явно не запрашивают масштабирование.
По сути, когда пользователь устанавливает коэффициент масштабирования на 120 dpi, вертикальный или горизонтальный дюйм на экране становится больше на 25 процентов. Все измерения масштабируются соответствующим образом. Смещение окна приложения от верхних и левых краев экрана увеличивается на 25 процентов. Если масштабирование приложений включено, и приложение не учитывает dpi, размер окна увеличивается в той же пропорции, а также смещения и размеры всех элементов пользовательского интерфейса, содержащихся в нем.
Замечание
По умолчанию DWM не выполняет масштабирование для приложений, не поддерживающих dpi, когда пользователь устанавливает значение dpi 120, но выполняет его, когда для dpi установлено настраиваемое значение 144 или выше. Однако пользователь может переопределить поведение по умолчанию.
Масштабирование экрана создает новые проблемы для приложений, которые каким-либо образом связаны с координатами экрана. Теперь экран содержит две системы координат: физические и логические. Физические координаты точки — это фактическое смещение в пикселях в левом верхнем углу источника. Логические координаты — это смещения, которые были бы, если бы масштабирование применялось непосредственно к пикселям.
Предположим, что вы разрабатываете диалоговое окно с кнопкой с координатами (100, 48). Если это диалоговое окно отображается по умолчанию 96 dpi, кнопка находится в физических координатах (100, 48). В 120 dpi он расположен в физических координатах (125, 60). Но логические координаты одинаковы при любом параметре dpi: (100, 48).
Логические координаты важны, так как они делают поведение операционной системы и приложений согласованными независимо от параметра dpi. Например, Cursor.Position обычно возвращает логические координаты. При перемещении курсора над элементом в диалоговом окне возвращаются те же координаты независимо от параметра dpi. Если вы рисуете элемент управления на координатах (100, 100), он рисуется по этим логическим координатам и будет занимать ту же относительную позицию при любом значении dpi.
Масштабирование в клиентах автоматизации пользовательского интерфейса
API автоматизации пользовательского интерфейса не использует логические координаты. Следующие методы и свойства либо возвращают физические координаты, либо принимают их в качестве параметров.
По умолчанию клиентское приложение автоматизации пользовательского интерфейса, работающее в среде, отличной от 96-dpi, не сможет получить правильные результаты из этих методов и свойств. Например, поскольку позиция курсора находится в логических координатах, клиент не может просто передать эти координаты в FromPoint, чтобы получить элемент, находящийся под курсором. Кроме того, приложение не сможет правильно размещать окна за пределами клиентской области.
Решение состоит из двух частей.
Во-первых, сделайте клиентское приложение чувствительным к dpi. Для этого вызовите функцию
SetProcessDPIAware
Win32 при запуске. В управляемом коде следующее объявление делает эту функцию доступной.[System.Runtime.InteropServices.DllImport("user32.dll")] internal static extern bool SetProcessDPIAware();
<System.Runtime.InteropServices.DllImport("user32.dll")> _ Friend Shared Function SetProcessDPIAware() As Boolean End Function
Эта функция делает весь процесс учитывающим dpi, что означает, что все окна, принадлежащие процессу, остаются немасштабированными. Например, в примере средства выделения четыре окна, составляющие прямоугольник выделения, находятся в физических координатах, полученных от автоматизации пользовательского интерфейса, а не логических координат. Если образец не учитывается на уровне dpi, выделение будет вырисовано по логическим координатам на рабочем столе, что приведет к неправильному размещению в среде, отличной от 96-dpi.
Чтобы получить координаты курсора, вызовите функцию
GetPhysicalCursorPos
Win32. В следующем примере показано, как объявить и использовать эту функцию.public struct CursorPoint { public int X; public int Y; } [System.Runtime.InteropServices.DllImport("user32.dll")] internal static extern bool GetPhysicalCursorPos(ref CursorPoint lpPoint); private bool ShowUsage() { CursorPoint cursorPos = new CursorPoint(); try { return GetPhysicalCursorPos(ref cursorPos); } catch (EntryPointNotFoundException) // Not Windows Vista { return false; } }
Structure CursorPoint Public X As Integer Public Y As Integer End Structure <System.Runtime.InteropServices.DllImport("user32.dll")> _ Friend Shared Function GetPhysicalCursorPos(ByRef lpPoint As CursorPoint) As Boolean End Function Private Function ShowUsage() As Boolean Dim cursorPos As New CursorPoint() Try Return GetPhysicalCursorPos(cursorPos) Catch e As EntryPointNotFoundException ' Not Windows Vista Return False End Try End Function
Осторожность
Не используйте Cursor.Position. Поведение этого свойства за пределами клиентских окон в масштабируемой среде не определено.
Если ваше приложение выполняет прямой межпроцессный обмен данными с приложениями, не поддерживающими DPI, может понадобиться преобразовать между логическими и физическими координатами с помощью функций Win32 PhysicalToLogicalPoint
и LogicalToPhysicalPoint
.