实现Client-Side (代理) UI 自动化提供程序

Microsoft UI 自动化为大多数标准控件(例如 Microsoft Win32、Windows 窗体 和 Windows Presentation Foundation (WPF) 应用程序中使用的控件)提供一组代理。 但是,许多自定义控件和第三方控件不实现本机UI 自动化提供程序。 若要使UI 自动化客户端应用程序可访问,这些控件必须提供客户端提供程序(也称为代理提供程序代理)。

本主题介绍如何为不受支持的控件编写代理提供程序,并将其添加到客户端应用程序使用的代理列表中。 它包括以下主题:

有关演示如何实现代理提供程序的代码示例,请参阅UI 自动化提供程序的操作说明主题

什么是代理?

客户端提供程序或代理是一个对象,它代表没有 其自己的 IRawElementProviderSimple 实现的控件实现 IRawElementProviderSimple 接口。 如果没有代理,此类控件对UI 自动化基本上是不透明的,它只能从窗口句柄 (HWND) 提供基本信息,例如控件位置。

什么是代理工厂?

每个代理都需要相应的 代理工厂,该工厂是公开 IUIAutomationProxyFactory 接口的对象。 UI 自动化维护代理工厂条目的内部表,其中每个条目都包含对每个代理的代理工厂的引用,以及一组条件。 当UI 自动化遇到没有本机 IRawElementProviderSimple 实现的控件时,它会搜索其条件指示它支持控件的代理工厂条目。 UI 自动化从头开始搜索表,当它找到匹配的条目时,UI 自动化调用工厂的 IUIAutomationProxyFactory::CreateProvider 方法。 如果成功创建匹配的代理,UI 自动化将停止搜索并使用新创建的代理对象;否则,UI 自动化继续搜索。

客户端应用程序使用 IUIAutomation::CreateProxyFactoryEntry 方法创建代理工厂条目的实例,该方法返回 IUIAutomationProxyFactoryEntry 接口指针。 客户端使用 IUIAutomationProxyFactoryEntry 公开的方法指定代理工厂用于创建代理的条件集。

调用 IUIAutomationProxyFactory::CreateProvider 时,UI 自动化传递代理工厂对象可用于确定代理是否充分支持自定义控件的参数。 如果是这样,代理工厂将创建代理的实例并返回 IRawElementProviderSimple 接口指针;否则,它将返回 NULL 指针。

代理工厂映射

默认情况下,UI 自动化按以下顺序搜索代理工厂表。

订单 代理 说明
1 Microsoft:非控制代理 对于具有确切类名或基类名称“ComboBoxEx32”的窗口。
2 Microsoft:非控制代理 对于具有确切类名或基类名称“WorkerW”的窗口。
3 Microsoft:非控制代理 对于具有确切类名或基类名称“SHELLDLL_DefView”的窗口。
4 Microsoft:容器代理 对于具有确切类名或基类名称“#32770”的窗口。
5 Microsoft:容器代理 对于类名或基类名称包含“AfxControlBar”的窗口。
6 Microsoft:TreeView 代理 对于类名或基类名称包含“SysTreeView32”的窗口。
7 Microsoft:ListView 代理 对于类名或基类名称包含“SysListView32”的窗口, (1) 。
8 Microsoft:ListView 代理 对于类名或基类名称包含“SysListView32”的窗口, (2) 。
9 Microsoft:MSAA 代理 对于任何窗口。

 

代理 7 和代理 8 是 SysListView32 控件的重复条目。 如果不进行修改,代理 7 将始终用于 SysListView32 控件,并且永远不会使用代理 8。 代理 8 仅用于可见列表项,通常由仅处理可见元素或具有严格性能要求的客户端应用程序使用。 这些客户端可以删除代理 7。

代理 9(Microsoft Active Accessibility to UI 自动化 代理)应始终是表中的最后一个条目。 这为实现 Microsoft Active Accessibility 但不UI 自动化的控件启用 Microsoft Active Accessibility 回退功能。

修改代理工厂表中的条目时,应仔细评估条目的新位置。 我们建议将自定义代理的条目放在非控件代理和容器代理之后,但放在 Microsoft Active Accessibility 之前,以UI 自动化代理。 此外,虽然在 CreateProvider 调用中可以有代码确定它是否应支持给定的窗口句柄 (HWND) ,但让UI 自动化基于类名选择代理,并将 CreateProvider 方法中的条件代码保持在最低水平会更有效。

UI 自动化为每个客户端维护单独的代理工厂表。 当客户端更改其代理表时,更改仅影响客户端本身;其他客户端不受影响。

管理默认代理

当客户端应用程序创建 CUIAutomation 对象时,代理工厂表最初仅包含标准控件的默认代理提供程序的条目。 通过使用 IUIAutomationProxyFactoryMapping 接口,客户端可以添加新条目、删除不需要的条目、更改条目顺序等。 客户端可以通过调用 IUIAutomation::P roxyFactoryMapping 方法检索 IUIAutomationProxyFactoryMapping 接口指针。

可用代理表包含每个代理的 IUIAutomationProxyFactoryEntry 接口。 每个 IUIAutomationProxyFactoryEntry 指定 IUIAutomationProxyFactory 和代理服务的控件类,并定义如何处理事件。

代理表由 IUIAutomationProxyFactoryMapping 接口表示,该接口可从 IUIAutomation::P roxyFactoryMapping 属性获取。 应用程序可以使用 IUIAutomationProxyFactoryMapping 方法来添加和删除代理。 若要创建要添加到此表的新条目,请使用 IUIAutomation::CreateProxyFactoryEntry 获取接口,然后使用 IUIAutomationProxyFactoryEntry 方法定义适用的控件类和代理的行为。

如何创建Client-Side (代理) UI 自动化提供程序

UI 自动化提供程序程序员指南