伺服器端 UI 自動化提供者實作
注意事項 |
---|
這份文件適用於想要使用 System.Windows.Automation 命名空間中定義之 Managed UI Automation 類別的 .NET Framework 開發人員。如需 UI Automation 的最新資訊,請參閱 Windows Automation API:使用者介面自動化 (英文)。 |
本節說明如何實作自訂控制項的伺服器端 UI 自動化提供者。
Windows Presentation Foundation (WPF) 項目和非 WPF 項目 (例如專為 Windows Forms 設計的項目) 的實作本質上並不相同。 WPF 項目透過衍生自 AutomationPeer 的類別為 UI Automation提供支援。 非 WPF 項目會透過提供者介面的實作來提供支援。
這個主題包含下列章節。
- 安全性考量
- Windows Presentation Foundation 項目執行的提供者實作
- 非 WPF 項目的提供者實作
- 相關主題
安全性考量
寫入提供者時,要寫成讓其能在部分信任的環境下運作。 因為 UIAutomationClient.dll 並非設定成在部分信任下執行,因此您的提供者程式碼不應參考這個組件。 否則,程式碼可能可以在完全信任的環境下執行,但無法在部分信任的環境下執行。
尤其是不得使用 UIAutomationClient.dll 內 (如 AutomationElement) 類別的欄位。 而應使用 UIAutomationTypes.dll 內 (如 AutomationElementIdentifiers) 類別的對等欄位。
Windows Presentation Foundation 項目執行的提供者實作
如需關於此主題的詳細資訊,請參閱 WPF 自訂控制項的 UI 自動化。
非 WPF 項目的提供者實作
自訂控制項並不是 WPF 架構的一部分,而是以 Managed 程式碼撰寫而成 (大部分的情況下,這些是 Windows Forms 控制項),會藉由實作介面來提供對 UI Automation的支援。 每各項目必須至少實作下節第一個表格中列出的一個介面。 此外,如果項目支援一個或多個控制項模式,則必須針對每個控制項模式實作適當的介面。
您的 UI Automation提供者專案必須參考下列組件:
UIAutomationProviders.dll
UIAutomationTypes.dll
WindowsBase.dll
這個章節包含下列子章節。
- 提供者介面
- 非 WPF 提供者的需求
- 非 WPF 提供者中的屬性值
- 非 WPF 提供者中的事件
- 非 WPF 提供者巡覽
- 非 WPF 提供者重新進行父代設定
- 非 WPF 提供者重新調整位置
提供者介面
每個 UI Automation提供者必須實作下列其中一個介面。
介面 |
說明 |
---|---|
提供視窗所裝載之簡易控制項的功能,包含對控制項模式和屬性的支援。 |
|
繼承自 IRawElementProviderSimple。 爲複雜控制項中的項目加入功能,包括在片段中進行瀏覽、設定字型及傳回項目的週框 (Bounding Rectangle)。 |
|
繼承自 IRawElementProviderFragment。 將根項目的功能加入至複雜控制項,包含找到位於特定座標的子項目以及設定整個控制項的焦點狀態。 |
下列介面提供新增功能,但不一定要進行實作。
介面 |
說明 |
---|---|
讓提供者追蹤事件的要求。 |
|
可在片段的 UI Automation樹狀目錄中重新調整以視窗為基礎的項目。 |
System.Windows.Automation.Provider 命名空間中的其他所有介面都適用於控制項模式支援。
非 WPF 提供者的需求
爲了與 UI Automation通訊,您的控制項必須實作下列功能的主要區域:
功能 |
實作 |
---|---|
將控制項公開給 UI Automation |
為了回應傳送到控制項視窗的 WM_GETOBJECT 訊息,請傳回實作 IRawElementProviderSimple 的物件 (或衍生介面)。 對於片段,這必須是片段根項目的提供者。 |
提供屬性值 |
實作 GetPropertyValue 以提供或覆寫值。 |
讓用戶端與控制項互動 |
實作支援控制項模式的介面,例如 IInvokeProvider。 傳回 GetPatternProvider 實作中的模式提供者。 |
引發事件 |
呼叫其中一個 AutomationInteropProvider 的靜態方法,以引發用戶端可接聽的事件。 |
在片段中進行巡覽和設定焦點 |
針對片段中的每個項目實作 IRawElementProviderFragment (項目不一定是片段的一部分)。 |
啟用片段中子項目的焦點和位置 |
實作 IRawElementProviderFragmentRoot (項目不一定是片段根項目的一部分)。 |
非 WPF 提供者中的屬性值
自訂控制項的 UI Automation提供者必須支援特定屬性,這些屬性可供自動化系統和用戶端應用程式使用。 對於裝載於視窗 (HWND) 中的項目,UI Automation可從預設的視窗提供者擷取某些屬性,但必須從自訂提供者取得其他屬性。
以 HWND 為基礎之控制項的提供者通常不必提供下列屬性 (由欄位值識別):
注意事項 |
---|
簡單項目的 RuntimeIdProperty 或裝載於視窗的片段根項目都是由視窗取得,但是根項目以下的片段項目 (例如清單方塊出的清單項目) 則必須提供他們擁有的識別項。如需詳細資訊,請參閱 GetRuntimeId。 會為裝載於 Windows Forms 控制項的提供者傳回 IsKeyboardFocusableProperty。這個時候,預設的視窗提供者可能無法擷取正確值。 NameProperty 通常是由主提供者提供。例如,如果自訂控制項衍生自 Control,名稱則會衍生自 Text 控制項的屬性。 |
如需程式碼範例,請參閱從 UI 自動化提供者傳回屬性。
非 WPF 提供者中的事件
UI Automation提供者會引發事件,通知用戶端應用程式 UI 狀態有所變更。 下列方法會用於引發事件。
方法 |
說明 |
---|---|
引發各種事件,包含由控制項觸發的事件。 |
|
變更 UI Automation屬性時引發事件。 |
|
UI Automation樹狀目錄的結構變更時 (例如,移除或新增項目) 引發事件。 |
事件的目的是通知用戶端user interface (UI) 正在發生某事件,無論該活動是否由 UI Automation系統本身所觸發。 例如,無論是透過直接的使用者輸入或經由用戶端應用程式呼叫 Invoke,都會在叫用控制項時引發由 InvokedEvent 識別的事件。
若要最佳化效能,提供者可以選擇性地引發事件,或是在沒有用戶端應用程式註冊接收事件時,選擇不引發任何事件。 下列方法會用於引發事件。
方法 |
說明 |
---|---|
這個靜態屬性會指定是否有任何用戶端應用程式訂閱 UI Automation事件。 |
|
片段根項目上此介面的提供者實作可在用戶端註冊和取消註冊片段上事件的事件處理常式時,讓使用者接到通知。 |
非 WPF 提供者巡覽
簡單控制項的提供者 (例如裝載於視窗的自訂按鈕 (HWND)) 不一定要支援在 UI Automation樹狀目錄中的巡覽功能。 項目之間的巡覽是由主視窗預設提供者所處理,會在 HostRawElementProvider 的實作中加以指定。 當您將提供者實作於複雜自訂控制項時,您必須支援在片段根節點、其子代 (Descendant) 和同層級 (Sibling) 節點之間進行巡覽。
注意事項 |
---|
根目錄以外之片段的項目必須從 HostRawElementProvider 傳回 null 參考,因為他們並非直接裝載於視窗中,而且沒有任何預設提供者可以支援這些項目之間的巡覽功能。 |
片段的結構是由 Navigate 的實作判斷的。 如需每個片段的每個可能方向,這個方法便會傳回該方向中的提供者物件。 如果該方向中沒有任何項目,方法則會傳回 null 參考。
片段根目錄只支援巡覽子項目的功能。 例如,當方向為 FirstChild 時,清單方塊會傳回清單中的第一個項目,而在方向為 LastChild 時,傳回最後一個項目。 片段根目錄不支援在父代或同層級的巡覽功能,此功能是由主視窗提供者處理。
不是根目錄的片段項目必須支援在父代以及其所有之任何同層級和子系的巡覽功能。
非 WPF 提供者重新進行父代設定
快顯視窗實際上是最上層視窗,因此,預設會在 UI Automation樹狀目錄中顯示為桌面的子系。 但是,在許多情況下,快顯視窗在邏輯上是其他某些控制項的子系。 例如,下拉式方塊的下拉式清單在邏輯上是下拉式方塊的子系。 同樣地,功能表快顯視窗邏輯上來說是功能表的子項目。 UI Automation支援重新進行快顯視窗的父代設定,讓這些視窗可以顯示為關聯控制項的子系。
若要重新設定快顯視窗的父代設定:
建立快顯視窗的提供者。 必須事先知道快顯視窗的類別,才能進行此作業。
以一般用於快顯的方式實作所有屬性和模式,如同控制項該有的方式。
實作 HostRawElementProvider 屬性,讓它傳回自 HostProviderFromHandle 取得的值,其中參數是快顯視窗的視窗處理常式。
實作快顯視窗及其父代 Navigate,以便可以從邏輯父代適當地在邏輯子系和同層級子系之間進行巡覽。
當 UI Automation遇到快顯視窗時,它會辨識巡覽已經從預設值進行覆寫,並在遇到桌面子系時,略過快顯視窗。 節點只能透過片段取得。
當控制項裝載任何類別的視窗時,則不適用重新進行父代設定。 例如,Rebar 只可以裝載其群組列任何類型的 HWND。 若要處理這些情形,UI Automation會支援其他形式的 HWND 重新配置,如下節所示。
非 WPF 提供者重新調整位置
UI Automation 片段可能包含兩個以上的項目,而每個項目都包含在視窗 (HWND) 中。 因為每個 HWND 都有自己的預設提供者,而此提供者會將 HWND 視為包含 HWND 的子系,因此,UI Automation樹狀目錄預設會在片段中,將 HWND 顯示為父視窗的子系。 在大部分情形中,這屬於不想要有的行為,但有時候則會造成混淆,因為它無法符合 UI 的邏輯結構。
範例之一就是 Rebar 控制項。 Rebar 包含群組列,每個群組列會依序包含以 HWND 為基礎的控制項,例如工具列、編輯方塊或下拉式方塊。 Rebar HWND 的預設視窗提供者會將群組列控制項 HWND 視為子系,其他 Rebar 提供者則會將群組列視為子系。 因為 HWND 提供者和 Rebar 提供者會串聯作業並結合其子系,所以,群組列和以 HWND 為基礎的控制項都會顯示為 Rebar 的子系。 但是,就邏輯上而言,只有群組列才會顯示為 Rebar 群組列的子系,且每個群組列提供者都會與其包含之控制項的預設 HWND 提供者結合。
若要完成這項作業,Rebar 的片段根目錄提供者會公開一組代表群組列的子系。 每個群組列都有公開屬性和模式的單一提供者。 在其 HostRawElementProvider 的實作中,群組列提供者會傳回控制項 HWND 的預設視窗提供者,取得方法是透過呼叫 HostProviderFromHandle,傳遞於控制項的視窗處理常式。 最後,Rebar 會實作 IRawElementProviderHwndOverride 介面,且在其 GetOverrideProviderForHwnd 實作中,會傳回包含於指定之 HWND 的適當控制項群組列提供者。