UI 自动化和 Microsoft Active Accessibility
更新:2007 年 11 月
Microsoft Active Accessibility 是使应用程序具备辅助功能的早期解决方案。Microsoft UI 自动化是用于 Microsoft Windows 的新辅助功能模型,旨在满足辅助技术产品和自动化测试工具的需求。与 Active Accessibility 相比,UI 自动化在许多方面都有所改进。
本主题包括 UI 自动化的主要功能,并说明了这些功能与 Active Accessibility 有何不同。
本主题包括下列各节。
- 编程语言
- Windows Presentation Foundation 中的支持
- 服务器和客户端
- UI 元素
- 树视图和导航
- 角色和控件类型
- 状态和属性
- 事件
- 安全性
- 相关主题
编程语言
Active Accessibility 基于支持双重接口的 组件对象模型 (COM),因此可用 C/C++、Microsoft Visual Basic 6.0 和脚本语言进行编程。UI 自动化(包括标准控件的客户端提供程序库)是用托管代码编写的,并且使用 Microsoft Visual C# 或 Microsoft Visual Basic .NET 可以非常轻松地编制 UI 自动化客户端应用程序。UI 自动化提供程序是一些接口实现,可用托管代码或 C/C++ 编写。
Windows Presentation Foundation 中的支持
Windows Presentation Foundation (WPF) 是用于创建用户界面的新模型。WPF 元素本身不支持 Active Accessibility;但这些元素支持 UI 自动化,后者包括对 Active Accessibility 客户端的桥接支持。只有专门针对 UI 自动化编写的客户端才能完全利用 WPF 的辅助功能,比如对文本的丰富支持。
服务器和客户端
在 Active Accessibility 中,服务器和客户端主要通过服务器的 IAccessible 实现直接进行通信。
在 UI 自动化中,核心服务位于服务器(称为提供程序)和客户端之间。核心服务调用提供程序实现的接口并提供附加服务,比如为元素生成唯一的运行库标识符。客户端应用程序使用库函数来调用 UI 自动化服务。
UI 自动化提供程序可向 Active Accessibility 客户端提供信息,Active Accessibility 服务器可向 UI 自动化客户端应用程序提供信息。但是,由于 Active Accessibility 公开的信息没有 UI 自动化公开的信息那么多,因此这两个模块并不完全兼容。
UI 元素
Active Accessibility 以 IAccessible 接口或子标识符的形式呈现 UI 元素。很难比较两个 IAccessible 指针来确定它们是否引用同一元素。
在 UI 自动化中,每个元素都由一个 AutomationElement 对象表示。将使用相等运算符或 Equals 方法来进行比较,这两种方式都会比较元素的唯一运行库标识符。
树视图和导航
可以将屏幕上的 用户界面 (UI) 元素视为将桌面作为根节点、应用程序窗口作为直接子项并将应用程序内的元素作为深一层子代的树结构。
在 Active Accessibility 中,许多与最终用户无关的自动化元素都公开在树中。客户端应用程序必须查看所有元素来确定哪些元素是有意义的。
UI 自动化客户端应用程序通过筛选过的视图查看 UI。该视图只包含重要的元素:即那些可为用户提供信息并能够进行交互的元素。只提供了控件元素和内容元素的预定义视图;除此之外,应用程序还可以定义自定义视图。UI 自动化简化了向用户描述 UI 和帮助用户与应用程序交互的任务。
在 Active Accessibility 中,元素间的导航要么是空间上的(例如,移到位于屏幕左边的元素),要么是逻辑上的(例如,移到下一个菜单项,或移到对话框内选项卡顺序中的下一项),要么就是分层的(例如,移动容器中的第一个子项,或从子项移到其父项)。由于子元素并不一直是实现 IAccessible 的对象,因此分层导航非常复杂。
在 UI 自动化中,所有 UI 元素都是支持相同基本功能的 AutomationElement 对象。(从提供程序的观点来看,它们是实现从 IRawElementProviderSimple 中继承的接口的对象。) 导航主要是分层导航:从父项到子项,以及从一个同级项到下一个同级项。(同级项之间的导航具有逻辑元素,因为它可能是按选项卡顺序进行的。) 通过使用 TreeWalker 类,您可以使用任何筛选的树视图从任何起点进行导航。您也可以通过使用 FindFirst 和 FindAll 导航到特定子项或子代;例如,可以在支持指定控件模式的对话框内非常轻松地检索所有元素。
与 Active Accessibility 相比,UI 自动化中的导航更为一致。某些元素(如下拉列表和弹出窗口)在 Active Accessibility 树中会出现两次,从这些元素中进行的导航可能会出现意外的结果。对于 rebar 控件,实际上不可能正常实现 Active Accessibility。UI 自动化允许重定父项和重新定位,因此可以将元素放在树中的任何位置,而不管窗口所属权所限制的层次结构。
角色和控件类型
Active Accessibility 使用 accRole 属性 (IAccessible::get_actRole) 来检索元素的角色在 UI 中的说明,比如 ROLE_SYSTEM_SLIDER 或 ROLE_SYSTEM_MENUITEM。元素的角色是确定其可用功能的主要线索。与控件的交互是通过使用固定方法(如 IAccessible::accSelect 和 IAccessible::accDoDefaultAction)实现的。客户端应用程序和 UI 之间的交互仅限于可通过 IAccessible 完成的交互。
相比之下,UI 自动化很大程度上将元素的控件类型(由 ControlType 属性描述)与其预期功能相分离。功能由提供程序通过实现其专用接口而支持的控件模式确定。可以结合控件模式来描述特定 UI 元素支持的完整功能集。某些提供程序需要支持特定控件模式;例如,复选框的提供程序必须支持 Toggle 控件模式。其他提供程序需要支持一组控件模式中的一个或多个;例如,按钮必须支持 Toggle 或 Invoke。仍然有一些其他提供程序根本不支持控件模式;例如,无法移动、调整大小或停靠的窗格没有任何控件模式。
UI 自动化支持自定义控件,这些控件由 Custom 属性标识,并且可由 LocalizedControlTypeProperty 属性描述。
下表显示了 Active Accessibility 角色到 UI 自动化控件类型的映射。
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 优先。 |
|
get_accName |
||
get_accRole |
有关角色到控件类型的映射,请参见上表。 |
|
get_accValue |
仅对于支持 ValuePattern 或 RangeValuePattern 的控件类型有效。RangeValue 的规范化值为 0-100,使之与 MSAA 行为保持一致。值项使用字符串。 |
|
get_accHelp |
||
accLocation |
||
get_accDescription |
UI 自动化中不支持 |
accDescription 在 MSAA 内没有清楚的规范,这导致提供程序会在此属性中放置不同的信息段。 |
get_accHelpTopic |
UI 自动化中不支持 |
下表显示了哪些 UI 自动化属性与 Active Accessibility 状态常量相对应。
Active Accessibility 状态 |
UI 自动化属性 |
是否触发状态更改? |
---|---|---|
STATE_SYSTEM_CHECKED |
对于复选框为 ToggleStateProperty 对于单选按钮为 IsSelectedProperty |
Y |
STATE_SYSTEM_COLLAPSED |
Y |
|
STATE_SYSTEM_EXPANDED |
Y |
|
STATE_SYSTEM_FOCUSABLE |
N |
|
STATE_SYSTEM_FOCUSED |
N |
|
STATE_SYSTEM_HASPOPUP |
对于菜单项为 ExpandCollapsePattern |
N |
STATE_SYSTEM_INVISIBLE |
IsOffscreenProperty 为 True,并且 GetClickablePoint 导致 NoClickablePointException |
N |
STATE_SYSTEM_LINKED |
N |
|
STATE_SYSTEM_MIXED |
N |
|
STATE_SYSTEM_MOVEABLE |
N |
|
STATE_SYSTEM_MUTLISELECTABLE |
N |
|
STATE_SYSTEM_OFFSCREEN |
IsOffscreenProperty 为 True |
N |
STATE_SYSTEM_PROTECTED |
N |
|
STATE_SYSTEM_READONLY |
RangeValuePattern.IsReadOnlyProperty 和 ValuePattern.IsReadOnlyProperty |
N |
STATE_SYSTEM_SELECTABLE |
N |
|
STATE_SYSTEM_SELECTED |
N |
|
STATE_SYSTEM_SIZEABLE |
N |
|
STATE_SYSTEM_UNAVAILABLE |
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 WinEvent 和 UI 自动化事件的对应关系。
WinEvent |
UI 自动化事件标识符 |
---|---|
EVENT_OBJECT_ACCELERATORCHANGE |
|
EVENT_OBJECT_CONTENTSCROLLED |
关联滚动条上的 VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_OBJECT_CREATE |
|
EVENT_OBJECT_DEFACTIONCHANGE |
无等效项 |
EVENT_OBJECT_DESCRIPTIONCHANGE |
无完全等效项;可能为 HelpTextProperty 或 LocalizedControlTypeProperty 属性更改 |
EVENT_OBJECT_DESTROY |
|
EVENT_OBJECT_FOCUS |
|
EVENT_OBJECT_HELPCHANGE |
|
EVENT_OBJECT_HIDE |
|
EVENT_OBJECT_LOCATIONCHANGE |
|
EVENT_OBJECT_NAMECHANGE |
NameProperty 属性更改 |
EVENT_OBJECT_PARENTCHANGE |
|
EVENT_OBJECT_REORDER |
在 Active Accessibility 中的使用方式不一致。UI 自动化中未定义直接对应的事件。 |
EVENT_OBJECT_SELECTION |
|
EVENT_OBJECT_SELECTIONADD |
|
EVENT_OBJECT_SELECTIONREMOVE |
|
EVENT_OBJECT_SELECTIONWITHIN |
无等效项 |
EVENT_OBJECT_SHOW |
|
EVENT_OBJECT_STATECHANGE |
各种 property-changed 事件 |
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 |
|
EVENT_SYSTEM_DIALOGSTART |
|
EVENT_SYSTEM_DRAGDROPEND |
无等效项 |
EVENT_SYSTEM_DRAGDROPSTART |
无等效项 |
EVENT_SYSTEM_FOREGROUND |
|
EVENT_SYSTEM_MENUEND |
|
EVENT_SYSTEM_MENUPOPUPEND |
|
EVENT_SYSTEM_MENUPOPUPSTART |
|
EVENT_SYSTEM_MENUSTART |
|
EVENT_SYSTEM_MINIMIZEEND |
|
EVENT_SYSTEM_MINIMIZESTART |
|
EVENT_SYSTEM_MOVESIZEEND |
|
EVENT_SYSTEM_MOVESIZESTART |
|
EVENT_SYSTEM_SCROLLINGEND |
VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_SYSTEM_SCROLLINGSTART |
VerticalScrollPercentProperty 或 HorizontalScrollPercentProperty 属性更改 |
EVENT_SYSTEM_SOUND |
无等效项 |
EVENT_SYSTEM_SWITCHEND |
无等效项,但 AutomationFocusChangedEvent 事件发出信号,指出新应用程序已获得焦点 |
EVENT_SYSTEM_SWITCHSTART |
无等效项 |
无等效项 |
CurrentViewProperty 属性更改 |
无等效项 |
ValueProperty 属性更改 |
无等效项 |
|
无等效项 |
|
无等效项 |
|
无等效项 |
|
无等效项 |
|
无等效项 |
|
无等效项 |
ToggleStateProperty 属性更改 |
无等效项 |
ValueProperty 属性更改 |
无等效项 |
|
无等效项 |
|
无等效项 |
安全性
某些 IAccessible 自定义方案需要封装一个基本 IAccessible 并与其连接。这样会对安全性产生影响,因为部分受信任的组件不应作为代码路径上的中间项。
UI 自动化模型不再需要提供程序连接到其他提供程序代码。UI 自动化核心服务将进行所有必要的聚合。