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


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

ПримечаниеПримечание

Эта документация предназначена для разработчиков на платформе .NET Framework, которым требуется использовать управляемые классы UI Automation, определенные в пространстве имен System.Windows.Automation.Последние сведения о UI Automation см. на веб-странице Windows Automation API: UI Automation.

Windows Vista позволяет пользователям изменять параметр dots per inch (dpi) таким образом, чтобы большинство элементов user interface (UI) на экране отображались крупнее. Хотя эта возможность уже давно была доступна в Microsoft Windows, в предыдущих версиях масштабирование реализовывалось приложениями. В Windows Vista диспетчер окон рабочего стола выполняет масштабирование по умолчанию для всех приложений, которые не обрабатывают свое собственное масштабирование. Приложения клиента автоматизации пользовательского интерфейса должны учитывать эту возможность.

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

  • Масштабирование в Windows Vista
  • Масштабирование в клиенте автоматизации пользовательского интерфейса
  • Связанные разделы

Масштабирование в Windows Vista

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

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

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

ПримечаниеПримечание

По умолчанию 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 UI Automation не использует логические координаты. Следующие методы и свойства либо возвращают физические координаты, либо принимают их в качестве параметров.

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

Решение этой проблемы состоит из двух частей.

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

    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Friend Shared Function SetProcessDPIAware() As Boolean
    End Function
    
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern bool SetProcessDPIAware();
    

    Эта функция делает весь процесс dpi-зависимым. Это означает, что все принадлежащие процессу окна являются немасштабируемыми. Например, в Highlighter Sample четыре окна, входящие в прямоугольник выделения, находятся в физических координатах, полученных от UI Automation, а не в логических координатах. Если бы образец не зависел от количества dpi, выделение было бы выполнено в логических координатах на рабочем столе, что привело бы к неверному размещению в среде со значением, отличным от 96 dpi.

  2. Чтобы получить координаты курсора, вызовите функцию Win32 GetPhysicalCursorPos. В следующем примере показано объявление и использование этой функции.

    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
    
    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;
        }
    }
    
Предупреждающее замечаниеВнимание

Не используйте Cursor.Position.Поведение этого свойства вне клиентских окон в масштабируемой среде не определено.

Если приложение выполняет межпроцессное взаимодействие с не-dpi-зависимыми приложениями, то возможно сделать преобразование между логическими и физическими координатами с помощью функций Win32 PhysicalToLogicalPoint и LogicalToPhysicalPoint. 

См. также

Задачи

Highlighter Sample