文字和 TextRange 控制件模式
說明實作 ITextProvider、ITextProvider2和 ITextRangeProvider的指導方針和慣例,包括屬性和方法的相關信息。 Text 控制樣式可讓應用程式和控件公開簡單的文字物件模型,讓用戶端可從文字型控件擷取文字內容、文字屬性和內嵌物件。
若要支援 Text 控件模式,控件會實作 ITextProvider 和 ITextProvider2 介面。 應該支援 文字 控制項模式的控件類型包括 編輯 和 檔案 控制項類型,以及任何其他可讓使用者輸入文字或選取唯讀文字的控件類型。
Text 控制項模式可以與其他Microsoft UI 自動化控制項模式搭配使用,以支援文字中的數種類型的內嵌物件,包括數據表、超連結和命令按鈕。
ITextProvider 和 ITextProvider2 介面包含一些取得文字範圍的方法。 文字範圍 是物件,代表文字容器中連續的文字範圍或多個脫離的文字範圍。 一個 ITextProvider 方法會取得代表整個文件的文字範圍,而其他則取得代表檔部分的文字範圍,例如選取的文字、可見文字或內嵌在文字中的物件。
文字範圍物件是由 TextRange 控件模式來表示,該模式是透過 ITextRangeProvider 介面實作。 TextRange 控件模式提供用來公開範圍中文字資訊的方法和屬性、移動範圍的端點、選取或取消選取文字、將範圍卷動到檢視中等等。
如需 文字 和 TextRange 控件模式的詳細資訊,請參閱 文字內容的 UI 自動化支援。
從 Windows 8.1 提供者開始,可以實作 ITextRangeProvider2 介面。 這可叫用與文字範圍相關聯的作功能表。 這支援文字自動更正或輸入法編輯器 (IME) 候選取等案例。
本主題包含下列各節。
實作指導方針和慣例
實作 文字 控件模式時,請注意下列指導方針和慣例:
- 任何允許存取文字的控件(例如輸入文字或選取只讀文字)都應該支援 文字 控件模式。
- 文字 控件模式可以與任何 UI 元素搭配使用,這些元素會呈現文字,甚至是標準按鈕控件上的靜態標籤。 不過,在無法選取或沒有插入點的靜態文字控件上,不需要它。
- 為了確保可完全存取文字,實作 ITextProvider 的控件也應該支援 IValueProvider 介面。 IValueProvider 藉由提供變更文字的程序設計方式,來補充 ITextProvider 。 它也提供與輔助技術用戶端應用程式的更大相容性,包括以舊版技術為基礎的應用程式,例如Microsoft Active Accessibility。 實作這兩種控件模式時,TextChanged 事件 (UIA_Text_TextChangedEventId) 和 AutomationPropertyChanged 事件 (UIA_AutomationPropertyChangedEventId) 相當於 Value 屬性 (UIA_ValueValuePropertyId)。 必須支援這兩個事件。
- Text 控制項模式僅支援一個文字數據流和每個控件的一個檢視區。 如果應用程式在窗格中提供多個文件檢視,則每個檢視(控件)都應該獨立支援 ITextProvider。
- ITextProvider::GetSelection 方法可能會傳回代表目前選取文字的單一文字範圍。 如果控件支持選取多個非連續的文字範圍,GetSelection 方法應該會傳回數位,其中包含每個選取文字範圍的一個 ITextRangeProvider 介面。
- 文字 控件模式會將插入點表示為變質(空白)文字範圍。 ITextProvider::GetSelection 方法應該會在插入點存在且未選取任何文字時傳回變質的文字範圍。 如需詳細資訊,請參閱 與系統插入號的互作性。
- ITextProvider::GetVisibleRanges 方法可能會傳回單一文字範圍,如果檢視區中可以看到連續的文字範圍,或可能會傳回代表多個部分可見文字的脫離文字範圍陣列。
- 如果子元素沒有文字,ITextProvider::RangeFromChild 方法應該傳回變質範圍。 因為內嵌物件可以包含文字,RangeFromChild 方法不一定會傳回變質的文字範圍。 如需詳細資訊,請參閱 UI 自動化如何公開內嵌物件。
- ITextProvider::RangeFromPoint 方法會使用指定的螢幕座標在檔案區域中執行點擊測試。 產生的文字範圍應該與插入點或選取範圍一致,因為按下指定之螢幕座標的位置。 例如,如果影像位於指定的螢幕座標,產生的文字範圍應該與 ITextProvider::RangeFromChild 方法取得的文字範圍相同。 同樣地,如果用戶端應用程式要求系統插入號中央位置的文字範圍(插入點),產生的文字範圍應該與系統插入號位置相同。
- ITextProvider::D ocumentRan ge 屬性應該一律提供一個文字範圍,其中包含對應 ITextProvider 實作所支援的所有文字。
- UIA_Text_TextChangedEventId 事件必須在任何文字變更發生之後引發,即使檢視區中看不到變更也一樣。 例如,即使使用者將完全相同的文字貼到選取的文字上,提供者也應該引發 事件。
- 每當取文字時,或每當插入點(插入點)在文字之間移動時,都必須引發 UIA_Text_TextSelectionChangedEventId。
實作 TextRange 控件模式時,請注意下列指導方針和慣例:
- 不論文字的可見性狀態為何,TextRange 控件模式的所有方法都應該執行文字作業。 文字範圍的可見性一律可以藉由查詢 IsHidden text 屬性來決定(UIA_IsHiddenAttributeId]。
- 可能的話,提供者應該確保任何文字變更,例如刪除、插入和移動,會反映在相關聯的文字範圍物件中(ITextRangeProvider 介面的實例),並引發 UIA_Text_TextChangedEventId 事件。 用戶端可以使用 事件作為提示,以確認對控件文字所做的編輯變更。
- ITextRangeProvider::Compare、CompareEndpoints和 MoveEndpointByRange 方法所使用的所有文字範圍物件,都必須是相同 Text 控件模式實作的對等。
- 雖然不需要,但 ITextRangeProvider::CompareEndpoints 方法所擷取的 pRetVal 值可以指出兩個端點之間的距離,以字元 (TextUnit_Character) 為單位。 不過,用戶端應用程式不應依賴 pRetVal 超出其正值或負值 的正確性。
- ITextRangeProvider::ExpandToEnclosingUnit、Move和 MoveEndpointByUnit 方法需要仔細考慮指定的文字單位。 如需詳細資訊,請參閱作 TextRange by Text Unit。
- 如需與 ITextRangeProvider::Select、AddToSelection和 RemoveFromSelection 方法相關的實作需求,請參閱選取文字範圍中的文字。
- ITextRangeProvider::FindText 和 FindAttribute 方法會向前或向後搜尋單一相符的文字字元串或文字屬性。 如果沒有找到相符專案,它們應該會傳回 NULL。
- ITextRangeProvider::GetAttributeValue 方法必須傳回從 UiaGetReservedMixedAttributeValue 取得的位址, 或 UiaGetReservedNotSupportedValue 函式,或者如果文字控件不支持屬性。 TextRange 控制項模式規格不允許新增文字屬性識別碼或變更現有屬性的定義方式。
- 可能的話,ITextRangeProvider::GetBoundingRectangles 方法應該傳回陣列,該數位會針對文字範圍中每個完整或部分可見的文字行傳回一個周框。 如果無法這樣做,提供者可以傳回數位列,該陣列只包含完全可見線條的周框;不過,這會限制用戶端應用程式能夠準確地描述螢幕上呈現文字的方式。
- ITextRangeProvider::GetChildren 方法應該傳回內嵌在文字範圍中的所有子專案,但不需要傳回子元素的任何子系。 例如,如果文字範圍包含一些子單元格的數據表,則 getChildren 方法 可能只傳回 table 元素,而不是單元格元素。 基於效能或架構考慮,提供者可能無法公開自動化樹狀結構中檔內裝載的所有內嵌物件。 在此情況下,提供者應該至少支援透過 getChildren 方法 列舉子物件,而且作為選項,支援 VirtualizedItem 控件模式以進行虛擬化支援。
- ITextRangeProvider::GetEnclosingElement 方法通常會傳回提供文字範圍的文字提供者。 不過,如果文字提供者支持數據表或超連結等子物件,封入專案可能是文字提供者的子系。 GetEnclosingElement 所傳回的專案 應該是最接近指定文字範圍的專案。 例如,如果文字範圍位於表格的單元格中,GetEnclosingElement 應該傳回包含的單元格,而不是 table 元素。
- ITextRangeProvider::GetText 方法應該會傳回範圍中的純文本。 如需詳細資訊,請參閱從文字範圍取得文字。
- 呼叫 ITextRangeProvider::ScrollIntoView 應該對齊 alignToTop 參數所指定之文字控件檢視區中的文字。 雖然水平對齊沒有需求,但文字範圍應該同時以水準和垂直方式顯示。 評估 alignToTop 參數時,提供者必須考慮文字控件的方向和文字的流程方向。 例如,如果 alignToTop 為 TRUE TRUE,則包含從右至左流動之文字的垂直方向文字控件,提供者應該會將文字範圍與檢視區右側對齊。
- 透過 TextUnit_Line移動檔時,如果文字範圍進入內嵌表格,則儲存格中的每個文字行都應該視為一行。
ITextProvider 的必要成員
實作 ITextProvider 介面需要下列屬性和方法。
必要成員 | 成員類型 | 筆記 |
---|---|---|
DocumentRange | 財產 | 沒有 |
SupportedTextSelection | 財產 | 沒有 |
GetSelection | 方法 | 沒有 |
GetVisibleRanges | 方法 | 沒有 |
RangeFromChild | 方法 | 沒有 |
RangeFromPoint | 方法 | 沒有 |
UIA_Text_TextChangedEventId | 事件 | 沒有 |
UIA_Text_TextSelectionChangedEventId | 事件 | 沒有 |
實作 ITextProvider2 介面需要下列其他屬性和方法。
必要成員 | 成員類型 | 筆記 |
---|---|---|
GetCaretRange | 方法 | 沒有 |
RangeFromAnnotation | 方法 | 沒有 |
ITextRangeProvider 的必要成員
實作 ITextRangeProvider 介面需要下列屬性和方法。
必要成員 | 成員類型 | 筆記 |
---|---|---|
AddToSelection | 方法 | 沒有 |
複製 | 方法 | 沒有 |
比較 | 方法 | 沒有 |
CompareEndpoints | 方法 | 沒有 |
ExpandToEnclosingUnit | 方法 | 沒有 |
FindAttribute | 方法 | 沒有 |
FindText | 方法 | 沒有 |
GetAttributeValue | 方法 | 沒有 |
GetBoundingRectangles | 方法 | 沒有 |
GetChildren | 方法 | 沒有 |
GetEnclosingElement | 方法 | 沒有 |
GetText | 方法 | 沒有 |
移動 | 方法 | 沒有 |
MoveEndpointByUnit | 方法 | 沒有 |
MoveEndpointByRange | 方法 | 沒有 |
選取 | 方法 | 沒有 |
ScrollIntoView | 方法 | 沒有 |
實作 ITextRangeProvider2 介面需要下列其他屬性和方法。
必要成員 | 成員類型 | 筆記 |
---|---|---|
ShowContextMenu | 方法 | 請參閱<實作 ShowContextMenu>一節 |
TextRange 控件模式沒有相關聯的事件。
支援文字範圍
本節說明提供者如何實作各種方法,ITextRangeProvider 和 ITextRangeProvider2 介面,以支援 TextRange 控件模式。
依文字單位作文字範圍
ITextRangeProvider 介面提供數種方法來作及巡覽文字型控件中的文字範圍。 ITextRangeProvider::Move、MoveEndpointByUnit,以及 ExpandToEnclosingUnit 方法會依指定的文字單位移動文字範圍或其中一個端點,例如字元、文字、段落等。 如需詳細資訊,請參閱 UI 自動化文字單位。
儘管名稱如此,ITextRangeProvider::ExpandToEnclosingUnit 方法不一定會展開文字範圍。 相反地,它會移動端點來「正規化」文字範圍,讓範圍包含指定的文字單位。 如果範圍小於指定的單位,則會展開範圍,如果範圍比指定的單位長,則會縮短。 ExpandToEnclosingUnit 方法一律以一致的方式正規化文字範圍非常重要:否則,文字單位所作文字範圍的其他層面將無法預測。 下圖顯示 ExpandToEnclosingUnit 移動範圍端點來正規化文字範圍的方式。
前後文字範圍端點位置的圖表
如果文字範圍從文字單位的開頭開始,並在 開頭結束,或之前,下一個文字單位界限,結束端點會移至下一個文字單位界限(請參閱上圖中的 1 和 2)。
如果文字範圍從文字單位的開頭開始,並在下一個單位界限或之後結束,結束端點會保持或向後移動至起始端點之後的下一個單位界限(請參閱上圖中的 3 和 4)。 如果開始和結束端點之間有多個文字單位界限,結束端點會在起始端點之後向後移至下一個單位界限,導致長度為一個文字單位的文字範圍。
如果文字範圍從文字單元中間開始,起始端點會向後移動至文字單元的開頭,並視需要往前或向後移動結束端點,移至開始端點之後的下一個單位界限(請參閱上圖中的 5 到 8)。
呼叫 ITextRangeProvider::Move 方法時,提供者會使用與 ExpandToEnclosingUnit 方法相同的正規化邏輯,將文字範圍正規化。 然後,提供者會依指定的文字單位數目往後或向前移動範圍。 移動範圍時,提供者應該忽略文字中任何內嵌物件的界限。 不過,單位界限本身可能會受到內嵌物件的存在所影響。 下圖示範 Move 方法如何跨內嵌物件和文字單位界限移動文字範圍、單位單位。
ITextRangeProvider::MoveEndpointByUnit 方法會將其中一個端點向前或向後移動指定的文字單位,如下圖所示。
顯示moveendpointbyunit如何移動範圍端點的圖表
ITextRangeProvider::MoveEndpointByRange 方法可讓用戶端應用程式將文字範圍的一個端點設定為與第二個文字範圍指定端點相同的位置。
選取文字範圍中的文字
ITextRangeProvider 介面包含數種方法,可用來控制文字型控件中的文字選取範圍。
ITextRangeProvider::Select 方法應該選取對應至文字範圍的文字,並從文字控件中移除先前的選取範圍。 如果 在變質的文字範圍上呼叫 Select,提供者應該將插入點移至文字範圍的位置,而不選取任何文字。
如果控件支持選取多個、不相鄰的文字範圍,ITextRangeProvider::AddToSelection 和 RemoveFromSelection 方法會將文字範圍新增至選取的文字範圍集合,並將其從中移除。 如果控件一次只支援一個選取的文字範圍,但是選取作業會導致選取多個不相鄰的文字範圍,提供者應該傳回 E_INVALIDOPERATION 錯誤,或者應該擴充或截斷目前的選取範圍。 ITextProvider::SupportedTextSelection 屬性應該指出控件是否支持選取單一或多個文字範圍,或完全不支援任何範圍。
如果文字型控件支援文字插入,則呼叫 ITextRangeProvider::AddToSelection 或 RemoveFromSelection 控件中變質的文字範圍應該移動插入點,但不應該選取任何文字。
從文字範圍取得文字
ITextRangeProvider::GetText 方法應該會傳回文字範圍的純文本。 純文本應該包含來源文字中找到的所有控制字元,例如歸位字元和 Unicode 由左至右標記 (LRM)。 純文本不應包含任何標記標記,例如可能存在於來源文字中的 HTML。 此外,來源文字中的任何逸出碼都應該轉換成純文本對等專案。 例如,“ 應該轉換成簡單的空格符。
如果內嵌物件跨越文字範圍,純文本應該包含對象的內部文字,但不應該包含替代文字(內嵌物件的名稱屬性),因為它可能與描述性內部文字不一致。 如需詳細資訊,請參閱 UI 自動化如何公開內嵌物件。
實作 ShowContextMenu
ITextRangeProvider2::ShowContextMenu 應該一律在範圍的起點顯示作功能表。 如果使用者按下作功能表鍵或SHIFT + F10 並在範圍開頭的插入點,這應該相當於會發生什麼情況。
如果顯示作功能表通常會導致插入點移至指定位置,則應該執行此動作,以程式設計方式叫用 showContextMenu ,以支援 UI 自動化。
與系統插入號的互作性
正確支援插入點對許多用戶端應用程式很重要,包括那些不是以UI自動化為基礎的用戶端應用程式。 在 文字 控件模式中,插入點會以系統插入號位置的變質(空白)文字範圍表示。 當插入點移動時,控件應該引發 TextSelectionChanged 事件 (UIA_Text_TextSelectionChangedEventId)。 某些用戶端應用程式相依於此事件來監視插入點的位置,以及追蹤文字選取專案。
當控件包含選取的文字時,目前 文字 控件模式的設計不會提供直接將插入點的位置與特定文字範圍產生關聯的方法。 提供者必須追蹤文字選取範圍,並適當地設定插入點的位置。 因為選取文字通常是藉由按住 SHIFT 鍵或 CTRL 鍵時移動插入點來完成,因此提供者可以在選取範圍變更時檢查這些索引鍵的狀態來追蹤文字選取範圍。
因為輔助功能架構會針對系統插入號提供內建支援,但不會支援自定義插入號,因此文字型控制項應盡可能使用系統插入號。 使用自定義插入號的控制項可以建立與自訂插入號相同的維度的系統插入號,並將系統插入號定位在控制項 UI 中與自定義插入點相同的位置,以確保插入號可以存取插入號。 或者,使用自定義插入號的控件可以實作 Microsoft Active Accessibility 提供者,以便 OBJID_CARET 直接提供自定義插入號的輔助功能資訊。
如需系統插入號的詳細資訊,請參閱 Carets。
若要測試控件是否適當地公開系統插入號的位置,請使用 Inspect 和 Accessible 事件監看員 工具。
系統插入點中央的螢幕座標應該一律符合插入點的位置。 如此一來,用戶端就可以在呼叫 ITextProvider::RangeFromPoint 中使用插入號螢幕座標,擷取準確表示插入點位置的文字範圍。
相關主題