注释
本文档适用于想要使用 System.Windows.Automation 命名空间中定义的托管 UI 自动化类的 .NET Framework 开发人员。 有关 UI 自动化的最新信息,请参阅 Windows 自动化 API:UI 自动化。
Microsoft活动辅助功能是使应用程序易于访问的早期解决方案。 Microsoft UI 自动化是适用于 Microsoft Windows 的新辅助功能模型,旨在满足辅助技术产品和自动化测试工具的需求。 UI 自动化相较于 Active Accessibility 带来了许多改进。
本主题包括 UI 自动化的主要功能,并介绍了这些功能与活动辅助功能有何不同。
编程语言
主动辅助功能基于支持双接口的组件对象模型(COM),因此在 C/C++、Microsoft Visual Basic 6.0 和脚本语言中是可编程的。 UI 自动化(包括标准控件的客户端提供程序库)是用托管代码编写的,UI 自动化客户端应用程序使用 C# 或 Visual Basic .NET 轻松编程。 UI 自动化提供程序(即接口实现)可以用托管代码或 C/C++编写。
Windows Presentation Foundation 中的支持
Windows Presentation Foundation(WPF)是用于创建用户界面的新模型。 WPF 元素不包含对 Active Accessibility 的本机支持;但是,它们支持 UI 自动化,这包括对 Active Accessibility 客户端的桥接支持。 只有专为 UI 自动化编写的客户端才能充分利用 WPF 的辅助功能,例如对文本的丰富支持。
服务器和客户端
在 Active Accessibility 中,服务器和客户端主要通过服务器的 IAccessible
实现进行直接通信。
在 UI 自动化中,核心服务位于服务器(称为提供程序)和客户端之间。 核心服务对提供程序实现的接口进行调用,并提供其他服务,例如为元素生成唯一的运行时标识符。 客户端应用程序使用库函数调用 UI 自动化服务。
UI 自动化提供程序可以向活动辅助功能客户端提供信息,活动辅助功能服务器可以向 UI 自动化客户端应用程序提供信息。 但是,由于 Active Accessibility 不公开与 UI 自动化一样多的信息,因此这两个模型不完全兼容。
UI 元素
Active Accessibility 以 IAccessible
接口或子标识符的形式呈现 UI 元素。 很难比较两个 IAccessible
指针以确定它们是否引用同一元素。
在 UI 自动化中,每个元素都表示为一个 AutomationElement 对象。 比较是使用相等运算符或 Equals 方法完成的,这两者都比较元素的唯一运行时标识符。
树视图和导航
屏幕上的用户界面(UI)元素可以作为树结构,桌面作为根、应用程序窗口作为直接子级,以及应用程序中的元素作为进一步后代。
在 Active Accessibility 中,许多与最终用户不相关的自动化元素都公开在树中。 客户端应用程序必须查看所有元素,以确定哪些元素有意义。
UI 自动化客户端应用程序通过筛选视图查看 UI。 该视图仅包含感兴趣的元素:向用户提供信息或启用交互的元素。 仅控件元素和内容元素的预定义视图可用;此外,应用程序还可以定义自定义视图。 UI 自动化简化了向用户描述 UI 以及帮助用户与应用程序交互的任务。
在活动辅助功能中,元素之间的导航可以是空间性的(例如,移动到屏幕上左侧的元素)、逻辑性的(例如,移动到下一个菜单项或对话框中选项卡顺序的下一项),或者是层次性的(例如,移动到容器中的第一个子元素,或从子元素移动到父元素)。 分层导航很复杂,因为子元素并不总是实现 IAccessible
的对象。
在 UI 自动化中,所有 UI 元素都是 AutomationElement 支持相同基本功能的对象。 (从提供程序的角度来看,它们是实现从 IRawElementProviderSimple.继承的接口的对象)导航主要是分层的:从父级到子级,从一个同级到下一个。 (同级之间的导航具有一个逻辑元素,因为它可能遵照的是 Tab 键顺序。)通过使用 TreeWalker 类,你可以使用树的任何筛选视图从任何起点进行导航。 您还可以使用 FindFirst 和 FindAll 导航到特定的子级或后代;例如,检索对话框中支持指定控件模式的所有元素非常简单。
用户界面自动化中的导航比 Active Accessibility 更一致。 某些元素(如下拉列表和弹出窗口)在活动辅助功能树中出现两次,并且从它们进行导航可能会产生意外的结果。 其实就是无法对 rebar 控件正确实现 Active Accessibility。 UI 自动化能够重排根目录并进行重新布置,因此可以在树的任何位置放置元素,不必考虑窗口所有者构建的层次结构。
角色和控件类型
主动辅助功能使用 accRole
属性(IAccessible::get_actRole
)来获取有关 UI 中元素角色的描述,例如 ROLE_SYSTEM_SLIDER 或 ROLE_SYSTEM_MENUITEM。 元素的角色是确定其可用功能的主要线索。 使用固定方法(如 IAccessible::accSelect
和 IAccessible::accDoDefaultAction
)实现与控件的交互。 客户端应用程序和用户界面之间的交互仅限于可以通过IAccessible
实现的功能。
相比之下,UI 自动化在很大程度上将元素(由 ControlType 属性描述)的控件类型与其预期功能分离。 功能由通过实现其特殊化接口的提供程序支持的控件模式来确定。 可以组合控件模式来描述特定 UI 元素支持的完整功能集。 某些提供程序需要支持特定控件模式;例如,复选框的提供程序必须支持切换控件模式。 其他提供程序需要支持一组控件模式中的一项或多项;例如,按钮必须支持切换或调用功能。 还有一些人根本不支持控制模式;例如,无法移动、调整大小或停靠的窗格没有任何控件模式。
UI 自动化支持自定义控件,这些控件由 Custom 属性标识,并且可以通过 LocalizedControlTypeProperty 属性描述。
下表显示了 Active Accessibility 角色到用户界面自动化控件类型的映射。
Active Accessibility 角色 | UI 自动化控件类型 |
---|---|
ROLE_SYSTEM_PUSHBUTTON | 按钮 |
ROLE_SYSTEM_CLIENT | 日历 |
ROLE_SYSTEM_CHECKBUTTON | 复选框 |
ROLE_SYSTEM_COMBOBOX | 组合框 |
ROLE_SYSTEM_CLIENT | 习惯 |
ROLE_SYSTEM_LIST | 数据网格 |
ROLE_SYSTEM_LISTITEM | 数据项 |
ROLE_SYSTEM_DOCUMENT | 文档 |
ROLE_SYSTEM_TEXT | 编辑 |
ROLE_SYSTEM_GROUPING | 组 |
ROLE_SYSTEM_LIST | 标题 |
ROLE_SYSTEM_COLUMNHEADER | 标头项 |
ROLE_SYSTEM_LINK | 超链接 |
ROLE_SYSTEM_GRAPHIC | 图片 |
ROLE_SYSTEM_LIST | 列表 |
ROLE_SYSTEM_LISTITEM | 列表项 |
ROLE_SYSTEM_MENUPOPUP | 菜单 |
ROLE_SYSTEM_MENUBAR | 菜单栏 |
ROLE_SYSTEM_MENUITEM | 菜单项 |
ROLE_SYSTEM_PANE | 面板 |
ROLE_SYSTEM_PROGRESSBAR | 进度栏 |
ROLE_SYSTEM_RADIOBUTTON | 单选按钮 |
ROLE_SYSTEM_SCROLLBAR | 滚动条 |
ROLE_SYSTEM_SEPARATOR | 分隔符 |
ROLE_SYSTEM_SLIDER | 滑 块 |
ROLE_SYSTEM_SPINBUTTON | 旋转图标 |
ROLE_SYSTEM_SPLITBUTTON | “拆分”按钮 |
ROLE_SYSTEM_STATUSBAR | 状态栏 |
ROLE_SYSTEM_PAGETABLIST | 选项卡 |
ROLE_SYSTEM_PAGETAB | 选项卡项 |
ROLE_SYSTEM_TABLE | 表 |
ROLE_SYSTEM_STATICTEXT | 文本 |
ROLE_SYSTEM_INDICATOR | 拇指 |
ROLE_SYSTEM_TITLEBAR | 标题栏 |
ROLE_SYSTEM_TOOLBAR | 工具栏 |
ROLE_SYSTEM_TOOLTIP | 工具提示 |
ROLE_SYSTEM_OUTLINE | 树 |
ROLE_SYSTEM_OUTLINEITEM | 树形项目 |
ROLE_SYSTEM_WINDOW | 窗口 |
有关不同控件类型的详细信息,请参阅 UI 自动化控件类型。
状态和属性
在 Active Accessibility 中,元素支持一组常见的属性,某些属性(例如 accState
)必须根据元素的角色描述非常不同的内容。 服务器必须实现IAccessible
中所有返回属性的方法,包括那些与元素无关的方法。
UI 自动化定义更多属性,其中一些属性对应于 Active Accessibility 中的状态。 有些元素很常见,但其他元素特定于控件类型和控件模式。 属性通过唯一标识符进行区分,大多数属性都可以使用单个方法进行检索, GetCurrentPropertyValue 或者 GetCachedPropertyValue。 许多属性也可以从 Current 和 Cached 属性访问器中轻松检索。
UI 自动化提供程序不必实现不相关的属性,但只需为它不支持的任何属性返回一个 null
值。 此外,UI 自动化核心服务可以从默认窗口提供程序获取某些属性,这些属性与提供程序显式实现的属性合并。
除了支持更多属性外,UI 自动化还允许通过单个跨进程调用检索多个属性来提供更好的性能。
下表显示了两个模型中的属性之间的对应关系。
Active Accessibility 属性访问器 | UI 自动化属性 ID | 注解 |
---|---|---|
get_accKeyboardShortcut |
AccessKeyProperty 或 AcceleratorKeyProperty |
AccessKeyProperty 如果两者都存在,则优先。 |
get_accName |
NameProperty | |
get_accRole |
ControlTypeProperty | 请参阅上表,了解如何将角色映射到控制类型。 |
get_accValue |
ValuePattern.ValueProperty RangeValuePattern.ValueProperty |
仅适用于支持 ValuePattern 或 RangeValuePattern 的控件类型。 RangeValue 值规范化为 0-100,与 MSAA 行为保持一致。 值项使用字符串。 |
get_accHelp |
HelpTextProperty | |
accLocation |
BoundingRectangleProperty | |
get_accDescription |
在 UI 自动化中不支持 |
accDescription MSAA 中没有明确的规范,这导致提供程序在此属性中放置不同的信息片段。 |
get_accHelpTopic |
在 UI 自动化中不支持 |
下表显示了哪些 UI 自动化属性对应于活动辅助功能状态常量。
Active Accessibility 状态 | UI 自动化属性 | 是否触发状态更改? |
---|---|---|
STATE_SYSTEM_CHECKED | 对于复选框, ToggleStateProperty 对于单选按钮, IsSelectedProperty |
Y |
STATE_SYSTEM_COLLAPSED | ExpandCollapseState = Collapsed | Y |
STATE_SYSTEM_EXPANDED | ExpandCollapseState = Expanded 或 PartiallyExpanded | Y |
STATE_SYSTEM_FOCUSABLE | IsKeyboardFocusableProperty | N |
STATE_SYSTEM_FOCUSED | HasKeyboardFocusProperty | N |
STATE_SYSTEM_HASPOPUP | 针对菜单项的 ExpandCollapsePattern | N |
STATE_SYSTEM_INVISIBLE | IsOffscreenProperty = True 且 GetClickablePoint 导致 NoClickablePointException | N |
STATE_SYSTEM_LINKED | ControlTypeProperty = Hyperlink |
N |
STATE_SYSTEM_MIXED | ToggleState = Indeterminate | N |
STATE_SYSTEM_MOVEABLE | CanMoveProperty | N |
STATE_SYSTEM_MUTLISELECTABLE | CanSelectMultipleProperty | N |
STATE_SYSTEM_OFFSCREEN | IsOffscreenProperty = 真 | N |
STATE_SYSTEM_PROTECTED | IsPasswordProperty | N |
STATE_SYSTEM_READONLY | RangeValuePattern.IsReadOnlyProperty 和 ValuePattern.IsReadOnlyProperty | N |
STATE_SYSTEM_SELECTABLE | SelectionItemPattern 已被支持 | N |
STATE_SYSTEM_SELECTED | IsSelectedProperty | N |
STATE_SYSTEM_SIZEABLE | CanResize | N |
STATE_SYSTEM_UNAVAILABLE | IsEnabledProperty | Y |
以下状态要么没有被大多数 Active Accessibility 控制服务器实现,要么在 UI 自动化中没有等效项。
Active Accessibility 状态 | 注解 |
---|---|
STATE_SYSTEM_BUSY | 在 UI 自动化中不可用 |
STATE_SYSTEM_DEFAULT | 在 UI 自动化中不可用 |
STATE_SYSTEM_ANIMATED | 在 UI 自动化中不可用 |
STATE_SYSTEM_EXTSELECTABLE | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_MARQUEED | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_SELFVOICING | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_TRAVERSED | 在 UI 自动化中不可用 |
STATE_SYSTEM_ALERT_HIGH | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_ALERT_MEDIUM | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_ALERT_LOW | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_FLOATING | 未通过 Active Accessibility 服务器广泛实现 |
STATE_SYSTEM_HOTTRACKED | 在 UI 自动化中不可用 |
STATE_SYSTEM_PRESSED | 在 UI 自动化中不可用 |
有关 UI 自动化属性标识符的完整列表,请参阅 UI 自动化属性概述。
事件
UI 自动化中的事件机制与 Active Accessibility 中的事件机制不同,它不依赖于 Windows 事件路由(与窗口句柄紧密绑定),并且不需要客户端应用程序设置挂钩。 可以对事件订阅进行微调,不仅能订阅特定事件,甚至还能订阅树的特定部分。 通过跟踪所侦听的事件,提供程序也可微调其事件的引发。
客户端还可以更轻松地检索引发事件的元素,因为这些元素直接传递给事件回调。 如果客户端订阅事件时缓存请求处于活动状态,则会自动预提取元素的属性。
下表显示了 Active Accessibility WinEvents 和 UI 自动化事件的对应关系。
WinEvent | UI 自动化事件标识符 |
---|---|
EVENT_OBJECT_ACCELERATORCHANGE | AcceleratorKeyProperty 属性更改 |
EVENT_OBJECT_CONTENTSCROLLED | 相关联的滚动条上的 VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_OBJECT_CREATE | StructureChangedEvent |
EVENT_OBJECT_DEFACTIONCHANGE | 无等效项 |
EVENT_OBJECT_DESCRIPTIONCHANGE | 没有确切的等效项;也许 HelpTextProperty 或 LocalizedControlTypeProperty 属性更改 |
EVENT_OBJECT_DESTROY | StructureChangedEvent |
EVENT_OBJECT_FOCUS | AutomationFocusChangedEvent |
EVENT_OBJECT_HELPCHANGE | HelpTextProperty 更改 |
EVENT_OBJECT_HIDE | StructureChangedEvent |
EVENT_OBJECT_LOCATIONCHANGE | BoundingRectangleProperty 属性更改 |
EVENT_OBJECT_NAMECHANGE | NameProperty 属性更改 |
EVENT_OBJECT_PARENTCHANGE | StructureChangedEvent |
EVENT_OBJECT_REORDER | 在 Active Accessibility 中使用不一致。 在 UI 自动化中没有定义直接对应的事件。 |
事件对象选择 | ElementSelectedEvent |
EVENT_OBJECT_SELECTIONADD | ElementAddedToSelectionEvent |
EVENT_OBJECT_SELECTIONREMOVE | ElementRemovedFromSelectionEvent |
EVENT_OBJECT_SELECTIONWITHIN | 无等效项 |
EVENT_OBJECT_SHOW | StructureChangedEvent |
EVENT_OBJECT_STATECHANGE | 各种属性更改事件 |
EVENT_OBJECT_VALUECHANGE | RangeValuePattern.ValueProperty 和 ValuePattern.ValueProperty 已更改 |
EVENT_SYSTEM_ALERT | 无等效项 |
EVENT_SYSTEM_CAPTUREEND | 无等效项 |
EVENT_SYSTEM_CAPTURESTART | 无等效项 |
EVENT_SYSTEM_CONTEXTHELPEND | 无等效项 |
EVENT_SYSTEM_CONTEXTHELPSTART | 无等效项 |
EVENT_SYSTEM_DIALOGEND | WindowClosedEvent |
EVENT_SYSTEM_DIALOGSTART | WindowOpenedEvent |
EVENT_SYSTEM_DRAGDROPEND | 无等效项 |
EVENT_SYSTEM_DRAGDROPSTART | 无等效项 |
EVENT_SYSTEM_FOREGROUND | AutomationFocusChangedEvent |
EVENT_SYSTEM_MENUEND | MenuClosedEvent |
EVENT_SYSTEM_MENUPOPUPEND | MenuClosedEvent |
EVENT_SYSTEM_MENUPOPUPSTART | MenuOpenedEvent |
EVENT_SYSTEM_MENUSTART | MenuOpenedEvent |
EVENT_SYSTEM_MINIMIZEEND | WindowVisualStateProperty 属性更改 |
EVENT_SYSTEM_MINIMIZESTART | WindowVisualStateProperty 属性更改 |
EVENT_SYSTEM_MOVESIZEEND | BoundingRectangleProperty 属性更改 |
EVENT_SYSTEM_MOVESIZESTART | BoundingRectangleProperty 属性更改 |
EVENT_SYSTEM_SCROLLINGEND | VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_SYSTEM_SCROLLINGSTART | VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_SYSTEM_SOUND | 无等效项 |
EVENT_SYSTEM_SWITCHEND | 没有等效项,但事件 AutomationFocusChangedEvent 指示新应用程序获得了焦点 |
EVENT_SYSTEM_SWITCHSTART | 无等效项 |
无等效项 | CurrentViewProperty 属性更改 |
无等效项 | HorizontallyScrollableProperty 属性更改 |
无等效项 | VerticallyScrollableProperty 属性更改 |
无等效项 | HorizontalScrollPercentProperty 属性更改 |
无等效项 | VerticalScrollPercentProperty 属性更改 |
无等效项 | HorizontalViewSizeProperty 属性更改 |
无等效项 | VerticalViewSizeProperty 属性更改 |
无等效项 | ToggleStateProperty 属性更改 |
无等效项 | WindowVisualStateProperty 属性更改 |
无等效项 | AsyncContentLoadedEvent 事件 |
无等效项 | ToolTipOpenedEvent |
安全
某些 IAccessible
自定义场景需要将基础 IAccessible
封装起来并进行调用。 这会产生安全影响,因为部分受信任的组件不应是代码路径上的中介。
UI 自动化模型消除了提供者需要调用其他提供者代码的需求。 UI 自动化核心服务执行所有必要的聚合。