Implementierung eines serverseitigen Benutzeroberflächenautomatisierungs-Anbieters
Hinweis |
---|
Diese Dokumentation ist für .NET Framework-Entwickler vorgesehen, die die verwalteten UI Automation-Klassen verwenden möchten, die im System.Windows.Automation-Namespace definiert sind.Aktuelle Informationen zu UI Automation finden Sie unter Windows Automation API: UI Automation. |
In diesem Abschnitt wird beschrieben, wie ein serverseitiger Benutzeroberflächenautomatisierungs-Anbieter für ein benutzerdefiniertes Steuerelement implementiert wird.
Die Implementierungen für Windows Presentation Foundation (WPF)-Elemente und Nicht-WPF-Elemente (z. B. für Windows Forms entworfene Elemente) unterscheiden sich grundlegend. WPF-Elemente unterstützen UI Automation über eine von AutomationPeer abgeleitete Klasse. Nicht-WPF-Elemente stellen die Unterstützung durch Implementierungen von Anbieterschnittstellen bereit.
Dieses Thema enthält folgende Abschnitte.
- Sicherheitsüberlegungen
- Anbieterimplementierung durch Windows Presentation Foundation-Elemente
- Anbieterimplementierung durch Nicht-WPF-Elemente
- Verwandte Abschnitte
Sicherheitsüberlegungen
Anbieter sollten so geschrieben werden, dass sie in einer teilweise vertrauenswürdigen Umgebung funktionieren können. Da UIAutomationClient.dll nicht für die Ausführung mit teilweiser Vertrauenswürdigkeit konfiguriert ist, sollte der Anbietercode nicht auf diese Assembly verweisen. Wenn dies der Fall ist, kann der Code in einer voll vertrauenswürdigen Umgebung ausgeführt werden, während in einer teilweise vertrauenswürdigen Umgebung Fehler auftreten.
Verwenden insbesondere keine Felder von Klassen in UIAutomationClient.dll, z. B. die Felder in AutomationElement. Verwenden Sie stattdessen die entsprechenden Felder der Klassen in UIAutomationTypes.dll, z. B. AutomationElementIdentifiers.
Anbieterimplementierung durch Windows Presentation Foundation-Elemente
Weitere Informationen zu diesem Thema finden Sie unter Benutzeroberflächenautomatisierung eines benutzerdefinierten WPF-Steuerelements.
Anbieterimplementierung durch Nicht-WPF-Elemente
Benutzerdefinierte Steuerelemente, die nicht Teil des WPF-Frameworks, jedoch in verwaltetem Code geschrieben sind (hierbei handelt es sich meist um Windows Forms-Steuerelemente), unterstützen UI Automation durch das Implementieren von Schnittstellen. Jedes Element muss mindestens eine der in der ersten Tabelle des nächsten Abschnitts aufgeführten Schnittstellen implementieren. Außerdem muss ein Element, das ein oder mehrere Steuerelementmuster unterstützt, für jedes Steuerelementmuster die entsprechende Schnittstelle implementieren.
Das UI Automation-Anbieterprojekt muss auf die folgenden Assemblys verweisen:
UIAutomationProviders.dll
UIAutomationTypes.dll
WindowsBase.dll
Dieser Abschnitt enthält folgende Unterabschnitte.
- Anbieterschnittstellen
- Anforderungen für Nicht-WPF-Anbieter
- Eigenschaftswerte in Nicht-WPF-Anbietern
- Ereignisse in Nicht-WPF-Anbietern
- Navigation für Nicht-WPF-Anbieter
- Neuzuordnung des übergeordneten Elements für Nicht-WPF-Anbieter
- Neupositionieren für Nicht-WPF-Anbieter
Anbieterschnittstellen
Jeder UI Automation-Anbieter muss eine der folgenden Schnittstellen implementieren.
Schnittstelle |
Beschreibung |
---|---|
Stellt Funktionalität für ein einfaches in einem Fenster gehostetes Steuerelement bereit, einschließlich der Unterstützung für Steuerelementmuster und Eigenschaften. |
|
Erbt von IRawElementProviderSimple. Fügt Funktionalität für ein Element in einem komplexen Steuerelement hinzu, einschließlich Navigation im Fragment, Festlegen des Fokus und Zurückgeben des umschließenden Rechtecks des Elements. |
|
Erbt von IRawElementProviderFragment. Fügt Funktionalität für das Stammelement in einem komplexen Steuerelement hinzu, einschließlich Suchen eines untergeordneten Elements an angegebenen Koordinaten und Festlegen des Fokuszustands für das gesamte Steuerelement. |
Die folgenden Schnittstellen stellen weitere Funktionen bereit, müssen jedoch nicht implementiert werden.
Schnittstelle |
Beschreibung |
---|---|
Ermöglicht dem Anbieter, Anforderungen für Ereignisse zu verfolgen. |
|
Ermöglicht das Neupositionieren von fensterbasierten Elementen innerhalb der UI Automation-Struktur eines Fragments. |
Alle anderen Schnittstellen im System.Windows.Automation.Provider-Namespace dienen der Unterstützung von Steuerelementmustern.
Anforderungen für Nicht-WPF-Anbieter
Um mit UI Automation zu kommunizieren, muss ein Steuerelement die folgenden Hauptfunktionalitätsbereiche implementieren:
Funktionalität |
Implementierung |
---|---|
Verfügbarmachen des Anbieters für UI Automation |
Antworten Sie auf eine an das Steuerelementfenster gesendete WM_GETOBJECT-Nachricht, indem Sie das Objekt zurückgeben, das IRawElementProviderSimple (oder eine abgeleitete Schnittstelle) implementiert. Für Fragmente muss dies der Anbieter für den Fragmentstamm sein. |
Bereitstellen von Eigenschaftswerten |
Implementieren Sie GetPropertyValue, um Werte bereitzustellen oder zu überschreiben. |
Ermöglichen der Interaktion des Clients mit dem Steuerelement |
Implementieren Sie Schnittstellen, die Steuerelementmuster unterstützen, z. B. IInvokeProvider. Geben Sie diese Musteranbieter in der Implementierung von GetPatternProvider zurück. |
Auslösen von Ereignissen |
Rufen Sie eine der statischen Methoden von AutomationInteropProvider auf, um ein Ereignis auszulösen, das ein Client überwachen kann. |
Ermöglichen der Navigation und Fokussierung in einem Fragment |
Implementieren Sie IRawElementProviderFragment für jedes Element innerhalb des Fragments. (Nicht für Elemente erforderlich, die kein Teil eines Fragments sind.) |
Ermöglichen der Fokussierung und Positionierung eines untergeordneten Elements in einem Fragment |
Sie können IRawElementProviderFragmentRoot implementieren. (Nicht für Elemente erforderlich, die keine Fragmentstämme sind.) |
Eigenschaftswerte in Nicht-WPF-Anbietern
UI Automation-Anbieter für benutzerdefinierte Steuerelemente müssen bestimmte Eigenschaften unterstützen, die sowohl vom Automatisierungssystem als auch von Clientanwendungen verwendet werden können. Bei in Fenstern gehosteten Elementen (HWNDs) kann die UI Automation einige Eigenschaften vom Standardfensteranbieter abrufen, andere müssen jedoch vom benutzerdefinierten Anbieter bezogen werden.
Anbieter für HWND-basierte Steuerelemente müssen die folgenden Eigenschaften (identifiziert nach Feldwerten) normalerweise nicht bereitstellen:
Hinweis |
---|
Die RuntimeIdProperty eines in einem Fenster gehosteten einfachen Elements oder Fragmentstamms wird vom Fenster bezogen. Fragmentelemente unterhalb des Stamms (wie Listeneinträge in einem Listenfeld) müssen jedoch eigene Bezeichner bereitstellen.Weitere Informationen finden Sie unter GetRuntimeId. Die IsKeyboardFocusableProperty sollte für Anbieter zurückgegeben werden, die in einem Windows Forms-Steuerelement gehostet werden.In diesem Fall ist der Standardfensteranbieter möglicherweise nicht in der Lage, den richtigen Wert abzurufen. Die NameProperty wird in der Regel vom Hostanbieter bereitgestellt.Wenn ein benutzerdefiniertes Steuerelement beispielsweise von Control abgeleitet ist, wird der Name von der Text-Eigenschaft des Steuerelements abgeleitet. |
Beispielcode finden Sie unter Zurückgeben von Eigenschaften aus einem Benutzeroberflächenautomatisierungs-Anbieter.
Ereignisse in Nicht-WPF-Anbietern
UI Automation-Anbieter sollten Ereignisse auslösen, um Clientanwendungen über Zustandsänderungen der Benutzeroberfläche zu benachrichtigen. Ereignisse werden mit den folgenden Methoden ausgelöst.
Methode |
Beschreibung |
---|---|
Löst verschiedene Ereignisse aus, einschließlich Ereignissen, die von Steuerelementmustern ausgelöst werden. |
|
Löst ein Ereignis aus, wenn sich eine UI Automation-Eigenschaft geändert hat. |
|
Löst ein Ereignis aus, wenn sich der Aufbau der UI Automation-Struktur geändert hat, z. B. durch Entfernen oder Hinzufügen eines Elements. |
Der Zweck eines Ereignisses liegt im Benachrichtigen des Clients über Vorgänge in der user interface (UI), unabhängig davon, ob eine Aktion vom UI Automation-System selbst ausgelöst wird. Beispielsweise sollte das von InvokedEvent identifizierte Ereignis immer ausgelöst werden, wenn das Steuerelement aufgerufen wird, unabhängig davon, ob durch eine direkte Benutzereingabe oder durch die Invoke aufrufende Clientanwendung.
Zum Optimieren der Leistung kann ein Anbieter Ereignisse selektiv auslösen oder keine Ereignisse auslösen, wenn für deren Empfang keine Clientanwendung registriert ist. Die folgenden Methoden werden zur Optimierung verwendet.
Methode |
Beschreibung |
---|---|
Diese statische Eigenschaft gibt an, ob es Clientanwendungen gibt, die UI Automation-Ereignisse abonniert haben. |
|
Durch die Implementierung dieser Schnittstelle durch den Anbieter auf einem Fragmentstamm kann kommuniziert werden, wenn Clients Registrierungen von Ereignishandlern für Ereignisse im Fragment vornehmen bzw. aufheben. |
Navigation für Nicht-WPF-Anbieter
Anbieter für einfache Steuerelemente, z. B. eine benutzerdefinierte Schaltfläche, die in einem Fenster (HWND) gehostet wird, müssen die Navigation innerhalb der UI Automation-Struktur nicht unterstützen. Die Navigation zum und vom Element wird vom Standardanbieter für das Hostfenster verarbeitet, der in der Implementierung von HostRawElementProvider angegeben ist. Wenn Sie jedoch einen Anbieter für ein komplexes benutzerdefiniertes Steuerelement implementieren, müssen Sie die Navigation zwischen dem Stammknoten des Fragments und seinen Nachfolgern sowie zwischen nebengeordneten Knoten unterstützen.
Hinweis |
---|
Die Nicht-Stammelemente eines Fragments müssen einen null-Verweis von HostRawElementProvider zurückgeben, da sie nicht direkt in einem Fenster gehostet werden und die Navigation zu und von ihnen von keinem Standardanbieter unterstützt werden kann. |
Die Struktur des Fragments wird durch Ihre Implementierung von Navigate festgelegt. Diese Methode gibt für jedes Fragment und jede mögliche Richtung das Anbieterobjekt für das in dieser Richtung liegende Element zurück. Wenn in einer Richtung kein Element vorhanden ist, gibt die Methode einen null-Verweis zurück.
Der Fragmentstamm unterstützt die Navigation nur zu untergeordneten Elementen. Beispielsweise gibt ein Listenfeld für die Richtung FirstChild den ersten Eintrag und für die Richtung LastChild den letzten Eintrag in der Liste zurück. Der Fragmentstamm unterstützt keine Navigation zu einem übergeordneten oder nebengeordneten Element, diese wird vom Hostfensteranbieter verarbeitet.
Die Nicht-Stammelemente eines Fragments müssen die Navigation zum übergeordneten Element sowie zu allen vorhandenen nebengeordneten und untergeordneten Elementen unterstützen.
Neuzuordnung des übergeordneten Elements für Nicht-WPF-Anbieter
Genau genommen sind Popupfenster Fenster oberster Ebene und werden in der UI Automation-Struktur standardmäßig als untergeordnete Elemente des Desktops angezeigt. Eigentlich sind Popupfenster in vielen Fällen jedoch untergeordnete Elemente anderer Steuerelemente. Beispielsweise ist die Dropdownliste eines Kombinationsfelds logischerweise ein untergeordnetes Element des Kombinationsfelds. Dementsprechend ist ein Menüpopupfenster logischerweise ein untergeordnetes Element des Menüs. Die UI Automation unterstützt für Popupfenster das Neuzuordnen des übergeordneten Elements, sodass sie als untergeordnete Elemente des zugehörigen Steuerelements angezeigt werden.
So ordnen Sie ein Popupfenster einem neuen übergeordneten Element zu
Erstellen Sie einen Anbieter für das Popupfenster. Hierfür muss die Klasse des Popupfensters im Voraus bekannt sein.
Implementieren Sie für das Popupfenster alle Eigenschaften und Muster, als ob es ein vollkommen eigenständiges Steuerelement ist.
Implementieren Sie die HostRawElementProvider-Eigenschaft, sodass sie den mit HostProviderFromHandle abgerufenen Wert zurückgibt. Der Parameter ist hierbei der Fensterhandle des Popupfensters.
Implementieren Sie für das Popupfenster und das übergeordnete Element Navigate, sodass die Navigation vom logischen übergeordneten Element zum logischen untergeordneten Element sowie zwischen den nebengeordneten Elementen ordnungsgemäß verarbeitet wird.
Wenn die UI Automation auf das Popupfenster als untergeordnetes Element des Desktops stößt, wird erkannt, dass die Standardnavigation überschrieben wurde, und das Popupfenster wird übersprungen. Stattdessen ist der Knoten nur über das Fragment erreichbar.
Das Neuzuordnen des übergeordneten Elements ist nicht geeignet, wenn ein Steuerelement ein Fenster einer beliebigen Klasse hosten kann. Beispielsweise kann in den Bändern einer Infoleiste jeder HWND-Typ gehostet werden. Für solche Fälle unterstützt die UI Automation eine alternative Form der HWND-Umsetzung. Diese wird im nächsten Abschnitt beschrieben.
Neupositionieren für Nicht-WPF-Anbieter
UI Automation-Fragmente enthalten möglicherweise zwei oder mehr Elemente, die jeweils in einem Fenster (HWND) enthalten sind. Da jedes HWND über einen eigenen Standardanbieter verfügt, der das HWND als ein untergeordnetes Element eines enthaltenden HWND ansieht, werden in der UI Automation-Struktur die HWNDs im Fragment standardmäßig als untergeordnete Elemente des übergeordneten Fensters angezeigt. Dies ist in den meisten Fällen erwünscht. Manchmal kann es jedoch zu Verwirrung führen, da es nicht der logischen Struktur der UI entspricht.
Ein gutes Beispiel hierfür ist ein Infoleistensteuerelement. Eine Infoleiste enthält Bänder, die jeweils ein HWND-basiertes Steuerelement wie eine Symbolleiste, ein Eingabefeld oder ein Kombinationsfeld enthalten können. Für den Standardfensteranbieter für das Infoleisten-HWND sind die Bandsteuerelement-HWNDs untergeordnete Elemente, und für den Infoleistenanbieter sind die Bänder untergeordnete Elemente. Da der HWND-Anbieter und der Infoleistenanbieter zusammenarbeiten und ihre untergeordneten Elemente kombinieren, werden sowohl die Bänder als auch die HWND-basierten Steuerelemente als untergeordnete Elemente der Infoleiste angezeigt. Logisch sollten jedoch nur die Bänder als untergeordnete Elemente der Infoleiste angezeigt werden, und jeder Bandanbieter sollte mit dem Standard-HWND-Anbieter für das enthaltene Steuerelement verbunden werden.
Hierfür stellt der Fragmentstammanbieter für die Infoleiste einen Satz an untergeordneten Elementen zur Verfügung, die die Bänder repräsentieren. Jedes Band verfügt über einen einzelnen Anbieter, der Eigenschaften und Muster zur Verfügung stellen kann. In dessen Implementierung von HostRawElementProvider gibt der Bandanbieter den Standardfensteranbieter für das Steuerelement-HWND zurück, den er unter Übergabe des Fensterhandles des Steuerelements mithilfe von HostProviderFromHandle abruft. Abschließend implementiert der Fragmentstammanbieter für die Infoleiste die IRawElementProviderHwndOverride-Schnittstelle, und gibt in seiner Implementierung von GetOverrideProviderForHwnd den geeigneten Bandanbieter für das im angegebenen HWND enthaltene Steuerelement zurück.
Siehe auch
Aufgaben
Verfügbarmachen eines serverseitigen Benutzeroberflächenautomatisierungs-Anbieters
Zurückgeben von Eigenschaften aus einem Benutzeroberflächenautomatisierungs-Anbieter
Auslösen von Ereignissen aus einem Benutzeroberflächenautomatisierungs-Anbieter
Aktivieren der Navigation in einem Benutzeroberflächenautomatisierungs-Fragmentanbieter
Unterstützung von Steuerelementmustern in einem Benutzeroberflächenautomatisierungs-Anbieter
Konzepte
Übersicht über die Benutzeroberflächenautomatisierungs-Anbieter