UI 自动化如何公开嵌入对象
本主题介绍 Microsoft UI 自动化如何使用 Text 和 TextRange 控件模式公开在文本文档或容器中嵌入的对象(子/后代元素)。
对于 UI 自动化,嵌入对象是具有非文本边界的任何元素,例如图像、超链接、表格或文档类型(Microsoft Excel 电子表格、Microsoft Windows Media 文件等)。
注意
这不同于组件对象模型 (COM) OLE 定义(请参阅嵌入式对象),其中元素在一个应用程序中创建,并在另一个应用程序中嵌入或链接。 是否可以在对象的原始应用程序中编辑对象与 UI 自动化的上下文无关。
嵌入对象和 UI 自动化树
在 UI 自动化树的控制视图中,嵌入对象被视为独立元素。 由于它们都是作为文本容器的子级公开的,因此可以通过与 UI 自动化中的其他控件相同的对象模型进行访问。
下表为容器和非容器元素的示例。
容器元素
非容器元素
- 日历
- 组合框
- 数据网格
- Document
- 编辑
- 组
- 头文件
- HeaderItem
- 列出
- 菜单
- MenuBar
- 窗格
- SplitButton
- Tab
- 表
- 工具栏
- 树
- TreeItem
- 窗口
- 链接。
- CheckBoxes
- 按钮
下图显示了包含嵌入表和图像的文本容器(文档)。
下图显示了上一文档中的 UI 自动化内容视图。
“兼容”和“不兼容”嵌入对象
某些 UI 自动化提供程序对它们包含的每个 TextPattern 对象使用相同的文本存储。 与容器相同的文本存储支持的对象被称为“兼容”嵌入对象。 这些对象本身可以是 TextPattern 对象,在这种情况下,其文本范围与从其容器获取的文本范围相当。 这使提供程序能够公开有关单个 TextPattern 对象的客户端信息,就像它们是一个大型文本提供程序一样。
但是,提供程序可以为嵌入在 TextPattern 容器中的不同 TextPattern 对象使用不同的文本存储。 没有容器文本存储支持的对象被称为“不兼容”嵌入对象。 这些类型的嵌入对象可能是基于 TextPattern 的对象,也可能不是。
下表列出了兼容和非兼容嵌入对象的一些示例。
对象 | 兼容的嵌入对象 | 不兼容的嵌入对象 |
---|---|---|
非 TextPattern 嵌入对象 | Microsoft Edge 中的按钮 Microsoft Edge 中的数据表 |
Microsoft XAML 框架中 RichTextBlock 的按钮 Microsoft Edge 中使用替换文字的图像 Microsoft XAML 框架中 RichTextBlock 中具有 ListItems 的 ListView |
TextPattern 嵌入对象 | Microsoft Edge 中类型为“text”的输入控件 Word 文档中的表格 |
Microsoft Word 文档中的 TextBox 元素 |
公开嵌入的对象
Text and TextRange 控制模式公开了便于导航和查询嵌入对象的属性和方法。
文本容器和嵌入对象(如超链接或表格单元格)的文本内容(或内部文本)在 UI 自动化树的控件视图和内容视图中作为单个连续文本流公开,对象边界被忽略。 如果 UI 自动化客户端正在检索文本,以便以某种方式进行背诵、解释或分析,则应检查文本范围中的特殊情况,例如含有文本内容或其他嵌入对象的表格。 调用 IUIAutomationTextRange::GetChildren 以获取每个嵌入对象的 IUIAutomationElement 接口,然后调用 IUIAutomationTextPattern::RangeFromChild 以获取每个元素的文本范围。 以递归方式完成操作,直到检索到所有文本内容。
注意
退化(或折叠)范围是起始终结点和结束终结点的相同位置。 退化范围通常用于通过 ITextProvider GetSelection 和 GetCaretRange 方法表示文本游标位置。
下图显示了包含嵌入对象及其范围跨度的文本流。
嵌入对象和 TextUnit
一个 ITextProvider 对象可被指定的 TextUnit 遍历。 包含嵌入对象的提供程序可通过大致相同的方式遍历,但嵌入对象确实会影响遍历。 以下是需要了解的内容:
- 任何不兼容的嵌入对象都会在容器元素 TextPattern 的文本存储中的替换字符 U+FFFC 表示。 它还被视为字符单元和单词单元。
- 兼容的嵌入对象可能包含多个字符和单词。
- 封闭元素是跨整个文本范围的最底部元素。
- 范围的子元素也是容器元素的子元素,该元素部分或完全包含在该范围内。
- 理想情况下(尤其是在表等容器元素的情况下),字边界不会超出对象边界。 在下面的示例中,单词单元“Bar”不包含标记外部
</td>
的任何文本位置(<br \>
不是“Bar”一词的一部分)。
<table style="width:100%">
<tr>
<th>Name</th>
<th>Notes</th>
</tr>
<tr>
<td>Eve Jackson</td>
<td>Foo Bar</td>
</tr>
</table>
<br/>
- 一般情况下,
<br \>
被视为单个单词,这样它就不会超出线边界。 - 上一规则的例外情况是 Word 文本单元本身包含完整的对象。 例如,
<p>Hello <a href="#">link</a> here.</p>
包含内联容器的单词“Hello”、“link”和“here”。其中,“link”具有 TextPattern 对象作为封闭元素,链接对象作为其子对象。 - 对于 Character 单元,对象是封闭元素(类似此类的文本单元不应有子元素)。
- 不应将批注对象表示为嵌入对象。 例如,共同创作文档中存在其他 Author 说明符。
- 嵌入对象至少占用一个光标位置,批注只是元数据。
- 每个对象边界(开始和结束)由 TextPattern 文档范围中的格式分隔符表示。
- 对于 HTML,每个 html 标记不一定会导致 UI 自动化对象。 例如,强调标记中的内容不需要表示为元素,而是文本流,其中 UIA_IsItalicAttributeId 返回 TRUE。
- 启动终结点是非独占的首选终结点,而结束终结点是独占终结点。 当范围退化并且开始终结点和结束终结点属于该范围的相同位置时,这非常有用。
比较嵌入对象
具有类似子关系且共享相同支持文本存储的嵌套 TextPattern 对象称为可比较的。 在这种情况下,可以使用 ITextRangeProvider::Compare 和 ITextRangeProvider::CompareEndpoints 比较其中任一 TextPattern 对象的范围。 这两者都会产生指定其相对位置的有效数值。
如果对象在 TextPattern(ITextProvider::RangeFromChild)中具有有效范围,则嵌入在 TextPattern 对象中的非 TextPattern 对象与 TextPattern 相当,同时文本范围后面的内容不为空,并且不是替换字符。
Embedded TextPattern 对象和 Document TextUnit
对于嵌入的 TextPattern 对象,Document 单元仅识别该元素中包含的内容。
Word TextPattern 元素层次结构
- 文档元素实现 TextPattern,Document 返回整个 Word 文档范围。
- 文档的各个页面实现 TextPattern 和 Document 返回这些各个页面的内容(即使页面与整个文档 TextPattern 共享相同的文本存储)。
Edge 中的网页和文本输入控件
- 主网页窗格元素实现 TextPattern 并公开整个网页内容。
- 单个文本输入控件支持 TextPattern,其中文档范围表示每个输入字段中包含的文本(即使它们与整个网页共享相同的文本存储)。
常见方案
本部分提供了涉及嵌入对象的常见方案的示例:超链接、图像和表。 在以下示例中,左大括号({)表示文本范围的开始终结点,右大括号(})表示结束终结点。
超链接示例 1:包含嵌入文本超链接的文本范围
以下文本范围包含嵌入的文本超链接。
{URL https://www.microsoft.com 内嵌在文本中。}
调用 IUIAutomationTextRange::GetText、GetEnclosingElement、GetChildren 和 IUIAutomationTextPattern::RangeFromChild 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
IUIAutomationTextRange::GetText | 返回字符串"The URL https://www.microsoft.com is embedded in text"。 |
IUIAutomationTextRange::GetEnclosingElement | 返回结束文本范围的最内层 UI 自动元素。在本例中,即为表示文本提供程序本身的自动元素。 |
IUIAutomationTextRange::GetChildren | 返回表示超链接控件的 UI 自动化元素。 |
IUIAutomationTextPattern::RangeFromChild,其中UI 自动化元素由以前的 IUIAutomationTextRange::GetChildren 方法返回。 | 返回表示 https://www.microsoft.com" 的范围; |
超链接示例 2:部分跨越嵌入文本超链接的文本范围
以下文本范围部分跨越嵌入的文本超链接。
URL https://{www} 内嵌在文本中。
调用 IUIAutomationTextRange::GetText、GetEnclosingElement 和 GetChildren 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
IUIAutomationTextRange::GetText | 返回字符串“www”。 |
IUIAutomationTextRange::GetEnclosingElement | 返回结束文本范围的最内层 UI 自动元素。在本例中,即为超链接控件。 |
IUIAutomationTextRange::GetChildren | 由于文本范围未跨越整个 URL 字符串,因此返回 NULL。 |
超链接示例 3:部分跨越文本容器内容的文本范围
以下文本范围部分跨越文本容器的内容。 文本容器包含不属于文本范围一部分的嵌入文本超链接。
{URL} https://www.microsoft.com 内嵌在文本中。
调用 IUIAutomationTextRange::GetText、GetEnclosingElement 和 Move 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
IUIAutomationTextRange::GetText | 返回字符串“The URL”。 |
IUIAutomationTextRange::GetEnclosingElement | 返回结束文本范围的最内层 UI 自动元素。在本例中,即为表示文本提供程序本身的元素。 |
IUIAutomationTextRange::Move | 将文本范围跨度移到“https://”,因为该超链接的文本由独立单词组成。 在本例中,不将超链接视为单个对象。 URL {http} 内嵌在文本中。 |
图片示例 1:包含嵌入图像的文本范围
以下文本范围包含航天飞机的嵌入图像。
{图像 内嵌在文本中}。
调用 IUIAutomationTextRange::GetText、GetEnclosingElement、GetChildren 和 IUIAutomationTextPattern::RangeFromChild 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
IUIAutomationTextRange::GetText | 返回字符串"The image is embedded in text"。 文本流中不包含任何与图像相关的 ALT 文本。 |
IUIAutomationTextRange::GetEnclosingElement | 返回结束文本范围的最内层 UI 自动元素。在本例中,即为表示文本提供程序本身的元素。 |
IUIAutomationTextRange::GetChildren | 返回表示图像控件的 UI 自动化元素。 |
IUIAutomationTextPattern::RangeFromChild,其中UI 自动化元素由以前的 IUIAutomationTextRange::GetChildren 方法返回。 | 返回退化的范围。 |
图像超链接示例 2:部分跨越文本容器内容的文本范围
以下文本范围部分跨越文本容器的内容。 文本容器包含不属于文本范围的一部分的嵌入图像。
{图像} 内嵌在文本中。
调用 IUIAutomationTextRange::GetText、GetEnclosingElement 和 Move 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
IUIAutomationTextRange::GetText | 返回字符串“The image”。 |
IUIAutomationTextRange::GetEnclosingElement | 返回结束文本范围的最内层 UI 自动元素。在本例中,即为表示文本提供程序本身的元素。 |
IUIAutomationTextRange::Move with parameters of (TextUnit_Word, 2). | 将文本范围跨度移到“is ”。 由于只有基于文本的嵌入对象被视为文本流的一部分,因此本示例中的图像不影响 IUIAutomationTextRange::Move 或其返回值(在本例中为 2)。 |
表
表格示例 1:从单元格的内容获取文本容器。
下表从单元格的内容获取文本容器。
带图像的单元格 | 带文本的单元格 |
---|---|
X | |
Y | |
Z |
调用 IUIAutomationGridPattern::GetItem、IUIAutomationTextPattern::RangeFromChild、和 IUIAutomationTextRange::GetEnclosingElement 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
具有参数 (0, 0) 的 IUIAutomationGridPattern::GetItem。 | 返回表示表格单元格内容的 UI 自动元素。在本例中,该元素是文本控件。 |
iuiautomationtextpattern::rangefromchild | 返回图像的范围。 |
上一个 IUIAutomationTextPattern::RangeFromChild 方法返回的对象 GetEnclosingElement。 | 返回表示表单元格的 UI 自动化元素。 在这种情况下,该元素是支持 TableItem 控件模式的文本控件。 |
上一 GetEnclosingElement 方法返回的对象 IUIAutomationTextRangellGetEnclosingElement。 | 返回表示表的 UI 自动化元素。 |
上一 GetEnclosingElement 方法返回的对象 IUIAutomationTextRangellGetEnclosingElement。 | 返回表示文本提供程序本身的 UI 自动化元素。 |
表格示例 2:获取单元格的文本内容
上例中的表获取单元格的文本内容。
调用 IUIAutomationGridPattern::GetItem 和 IUIAutomationTextPattern::RangeFromChild 方法会导致下表中所述的行为。
调用方法 | 结果 |
---|---|
具有参数 (1,1) 的 IUIAutomationGridPattern::GetItem。 | 返回表示表单元格内容的 UI 自动化元素。 在这种情况下,元素是文本控件。 |
IUIAutomationTextPattern::RangeFromChild,其中UI 自动化元素是上一个 IUIAutomationGridPattern::GetItem 方法返回的对象。 | 返回“Y”。 |
通过 TextUnit_Line 在文档中移动时,如果文本范围输入嵌入表格,则单元格中的每个文本行都应视为一行。