Реализация поставщика автоматизации пользовательского интерфейса на стороне сервера

Примечание.

Эта документация предназначена для разработчиков .NET Framework, желающих использовать управляемые классы автоматизации пользовательского интерфейса, определенные в пространстве имен System.Windows.Automation. Последние сведения об автоматизации пользовательского интерфейса см. в статье API автоматизации Windows. Автоматизация пользовательского интерфейса.

В этом разделе описывается реализация серверного поставщика автоматизации пользовательского интерфейса для пользовательского элемента управления.

Реализация элементов Windows Presentation Foundation (WPF) и элементов, отличных от WPF (например, предназначенных для Windows Forms), существенно отличается. Элементы WPF обеспечивают поддержку модель автоматизации пользовательского интерфейса через класс, производный от AutomationPeer. Элементы, отличные от WPF, поддерживают реализацию интерфейсов поставщика.

Соображения безопасности

Поставщики должны быть написаны так, чтобы они могли работать в среде с частичным доверием. Поскольку библиотека UIAutomationClient.dll не настроена для запуска в режиме частичного доверия, код поставщика не должен ссылаться эту сборку. Если это происходит, код может выполняться в среде с полным доверием, но в среде с частичным доверием произойдет сбой.

В частности, не используйте поля из классов в UIAutomationClient.dll, такие как в AutomationElement. Вместо этого используйте эквивалентные поля из классов в UIAutomationTypes.dll, такие как AutomationElementIdentifiers.

Реализация поставщика элементами Windows Presentation Foundation

Дополнительные сведения по этой теме см. в разделе Модель автоматизации пользовательского интерфейса пользовательского элемента управления WPF.

Реализация поставщика элементами, отличными от WPF

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

Проект поставщика модель автоматизации пользовательского интерфейса должен ссылаться на следующие сборки:

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Интерфейсы поставщика

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

Интерфейс Description
IRawElementProviderSimple Предоставляет функциональные возможности для простого элемента управления, размещенного в окне, включая поддержку для шаблонов и свойств элементов управления.
IRawElementProviderFragment Наследует от IRawElementProviderSimple. Добавляет функциональные возможности для элемента в сложном элементе управления, включая навигацию внутри фрагмента, установку фокуса и возврат ограничивающего прямоугольника элемента.
IRawElementProviderFragmentRoot Наследует от IRawElementProviderFragment. Добавляет функциональные возможности для корневого элемента в сложном элементе управления, включая поиск дочернего элемента по указанным координатам и установку состояния фокуса для всего элемента управления.

Следующие интерфейсы поддерживают добавленные функциональные возможности, но необязательно должны быть реализованы.

Интерфейс Description
IRawElementProviderAdviseEvents Позволяет поставщику отслеживать запросы событий.
IRawElementProviderHwndOverride Включает изменение положения элементов на основе окна в дереве модель автоматизации пользовательского интерфейса фрагмента.

Все другие интерфейсы в пространстве имен System.Windows.Automation.Provider используются для поддержки шаблона элемента управления.

Требования для поставщиков, отличных от WPF

Чтобы взаимодействовать с модель автоматизации пользовательского интерфейса, элемент управления должен реализовать следующие основные области функциональности:

Функция Внедрение
Предоставление поставщику модель автоматизации пользовательского интерфейса В ответ на сообщение WM_GETOBJECT, отправленное окну элемента управления, возвращается объект, реализующий IRawElementProviderSimple (или производный интерфейс). Для фрагментов это должен быть поставщик для корневого фрагмента.
Указание значений свойств Реализуйте GetPropertyValue для предоставления или переопределения значений.
Включение клиента для взаимодействия с элементом управления Реализуйте интерфейсы, поддерживающие шаблоны элементов управления, такие как IInvokeProvider. Верните эти поставщики шаблонов в реализации GetPatternProvider.
Создание событий Вызовите один из статических методов AutomationInteropProvider , чтобы создать событие, которое клиент может прослушивать.
Включение навигации и установка фокуса внутри фрагмента Реализуйте IRawElementProviderFragment для каждого элемента в фрагменте. (Необязательно для элементов, которые не являются частью фрагмента.)
Включение установки фокуса и поиска дочерних элементов в фрагменте Реализуйте расширение IRawElementProviderFragmentRoot. (Необязательно для корневых элементов фрагмента.)

Значения свойств в поставщиках, отличных от WPF

модель автоматизации пользовательского интерфейса поставщики пользовательских элементов управления должны поддерживать определенные свойства, которые могут использоваться системой автоматизации, а также клиентскими приложениями. Для элементов, размещенных в окнах (HWND), модель автоматизации пользовательского интерфейса может получить некоторые свойства из поставщика окон по умолчанию, но получить другие из пользовательского поставщика.

Поставщикам для элементов управления на основе HWND обычно не требуется предоставлять следующие свойства (определяется значениями полей):

Примечание.

Простой элемент RuntimeIdProperty или корневой элемент фрагмента, размещенного в окне, извлекается из окна. Однако элементам фрагмента ниже корневого элемента (например, элементы списка в поле со списком) необходимо предоставлять собственные идентификаторы. Дополнительные сведения см. в разделе GetRuntimeId.

Возвращается IsKeyboardFocusableProperty для поставщиков, размещенных в элементе управления Windows Forms. В этом случае поставщику окна по умолчанию может не удастся получить правильное значение.

NameProperty обычно предоставляется поставщиком главного окна. Например, если пользовательский элемент управления является производным от Control, имя будет производным от свойства Text элемента управления.

Пример кода см. в разделе Return Properties from a UI Automation Provider.

События в поставщиках, отличных от WPF

модель автоматизации пользовательского интерфейса поставщики должны вызывать события для уведомления клиентских приложений о изменениях в состоянии пользовательского интерфейса. Для создания событий используются следующие методы.

Метод Description
RaiseAutomationEvent Создает различные события, включая события, вызываемые шаблонами элементов управления.
RaiseAutomationPropertyChangedEvent Вызывает событие при изменении свойства модель автоматизации пользовательского интерфейса.
RaiseStructureChangedEvent Вызывает событие при изменении структуры дерева модель автоматизации пользовательского интерфейса, например путем удаления или добавления элемента.

Цель события — уведомить клиента о том, что происходит в пользовательском интерфейсе( пользовательском интерфейсе), независимо от того, активируется ли действие самой системой модель автоматизации пользовательского интерфейса. Например, событие, обозначенное InvokedEvent , должно инициироваться при каждом вызове элемента управления, например когда пользователь вводит данные или клиентское приложение вызывает Invoke.

Для оптимизации производительности поставщик можно выборочно вызывать события или вообще не создавать события, если отсутствует клиентское приложение, зарегистрированное для их получения. Для оптимизации используются следующие методы.

Метод Description
ClientsAreListening Это статическое свойство указывает, подписаны ли клиентские приложения на события модель автоматизации пользовательского интерфейса.
IRawElementProviderAdviseEvents Реализация поставщика этого интерфейса в корневом элементе фрагмента позволяет ему знать, когда клиенты регистрируют и отменяют регистрацию обработчиков событий для событий в фрагменте.

Навигация в поставщике, отличном от WPF

Поставщики простых элементов управления, такие как пользовательская кнопка, размещенная в окне (HWND), не должны поддерживать навигацию в дереве модель автоматизации пользовательского интерфейса. Переход между элемент обрабатывается поставщиком по умолчанию для главного окна, который указывается в реализации HostRawElementProvider. Однако при реализации поставщика сложного пользовательского элемента управления необходимо поддерживать навигацию между корневым узлом фрагмента и его потомками, а также между одноуровневыми узлами.

Примечание.

Элементы фрагмента, отличные от корневого, должны возвращать ссылку null из HostRawElementProvider, так как они размещаются не непосредственно в окне, а никакой поставщик по умолчанию не может поддерживать переходы между ними.

Структура фрагмента определяется реализацией Navigate. Для каждого возможного направления из каждого фрагмента этот метод возвращает объект поставщика для элемента в указанном направлении. Если в этом направлении нет элемента, метод возвращает ссылку null .

Корневой элемент фрагмента поддерживает переход только к дочерним элементам. Например, поле со списком возвращает первый элемент в списке, если задано направление FirstChild, и последний элемент, если задано направление LastChild. Корневой элемент фрагмента не поддерживает переход к родительскому элементу или одноуровневым элементам. Этим управляет поставщик главного окна.

Элементы фрагмента, отличные от корневого, должны поддерживать переходы к родительскому элементу, а также любым одноуровневым и дочерним элементам.

Переподчинение поставщика, отличного от WPF

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

Переподчинение всплывающего окна:

  1. Создайте поставщик для всплывающего окна. Для этого класс всплывающего окна должен быть известен заранее.

  2. Реализуйте все свойства и шаблоны для всплывающего окна так, будто бы оно является элементом управления.

  3. Реализуйте свойство HostRawElementProvider , возвращающее значение, полученное от HostProviderFromHandle, где параметр — это дескриптор всплывающего окна.

  4. Реализуйте Navigate для всплывающего окна и его родительского элемента, чтобы переход от логического родительского элемента к логическим дочерних элементов, а также между одноуровневыми потомками обрабатывался правильно.

Когда модель автоматизации пользовательского интерфейса обнаруживает всплывающее окно, оно распознает переопределение навигации по умолчанию и пропускает всплывающее окно при обнаружении в качестве дочернего элемента рабочего стола. Вместо этого узел будет доступен только через фрагмент.

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

Изменение положения поставщика, отличного от WPF

модель автоматизации пользовательского интерфейса фрагменты могут содержать два или более элементов, содержащихся в окне (HWND). Так как каждый HWND имеет собственный поставщик по умолчанию, который считает HWND дочерним элементом содержащего HWND, дерево модель автоматизации пользовательского интерфейса по умолчанию отображает HWND в фрагменте как дочерние элементы родительского окна. В большинстве случаев это желательное поведение, но иногда это может привести к путанице, так как она не соответствует логической структуре пользовательского интерфейса.

Хорошим примером служит элемент управления главной панели. Элемент управления главной панели содержит зоны, каждая из которых в свою очередь может содержать элемент управления на основе HWND, например панель инструментов, текстовое поле или поле со списком. Поставщик окна по умолчанию для HWND главной панели видит дескрипторы HWND элемента управления зоны как дочерние элементы, а поставщик главной панели видит эти зоны как дочерние элементы. Поскольку поставщик HWND и поставщик главной панели работают совместно и объединяют свои дочерние элементы, зоны и элементы управления HWND отображаются как дочерние элементы главной панели. Но логически только зоны должны отображаться в качестве дочерних элементов главной панели, а каждый поставщик зоны должен быть связан с поставщиком HWND по умолчанию для элемента управления, который он содержит.

Для этого поставщик корневого элемента фрагмента главной панели предоставляет набор дочерних элементов, представляющих зоны. У каждой зоны один поставщик, который может предоставлять свойства и шаблоны. В своей реализации HostRawElementProviderпоставщик зоны возвращает поставщика окна по умолчанию для HWND элемента управления, который он получает путем вызова HostProviderFromHandle, передавая дескриптор окна элемента управления. Наконец, поставщик корневого элемента фрагмента главной панели реализует интерфейс IRawElementProviderHwndOverride и в своей реализации GetOverrideProviderForHwnd возвращает соответствующий внешний поставщик для элемента управления, размещенного в указанном HWND.

См. также