Dela via


Implementering av UI Automation-provider på serversidan

Kommentar

Den här dokumentationen System.Windows.Automation är avsedd för .NET Framework-utvecklare som vill använda de hanterade UI Automation-klasserna som definierats i namnområdet. Den senaste informationen om UI Automation finns i Windows Automation API: UI Automation.

I det här avsnittet beskrivs hur du implementerar en UI Automation-provider på serversidan för en anpassad kontroll.

Implementeringen av WPF-element (Windows Presentation Foundation) och icke-WPF-element (till exempel de som är utformade för Windows Forms) skiljer sig i grunden. WPF-element ger stöd för UI Automation via en klass som härleds från AutomationPeer. Icke-WPF-element ger stöd genom implementeringar av providergränssnitt.

Säkerhetsöverväganden

Leverantörer bör skrivas så att de kan arbeta i en partisk förtroendemiljö. Eftersom UIAutomationClient.dll inte har konfigurerats för att köras under partiellt förtroende bör providerkoden inte referera till den sammansättningen. Om den gör det kan koden köras i en miljö med fullständigt förtroende men misslyckas sedan i en partiell förtroendemiljö.

I synnerhet ska du inte använda fält från klasser i UIAutomationClient.dll som de i AutomationElement. Använd i stället motsvarande fält från klasser i UIAutomationTypes.dll, till exempel AutomationElementIdentifiers.

Providerimplementering av Windows Presentation Foundation-element

Mer information om det här avsnittet finns i UI Automation av en ANPASSAD WPF-kontroll.

Providerimplementering av icke-WPF-element

Anpassade kontroller som inte ingår i WPF-ramverket, men som är skrivna i hanterad kod (oftast är dessa Windows Forms-kontroller), ger stöd för UI Automation genom att implementera gränssnitt. Varje element måste implementera minst ett av de gränssnitt som anges i den första tabellen i nästa avsnitt. Om elementet dessutom stöder ett eller flera kontrollmönster måste det implementera rätt gränssnitt för varje kontrollmönster.

UI Automation-providerprojektet måste referera till följande sammansättningar:

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Providergränssnitt

Varje UI Automation-provider måste implementera något av följande gränssnitt.

Gränssnitt beskrivning
IRawElementProviderSimple Tillhandahåller funktioner för en enkel kontroll som finns i ett fönster, inklusive stöd för kontrollmönster och egenskaper.
IRawElementProviderFragment Ärver från IRawElementProviderSimple. Lägger till funktioner för ett element i en komplex kontroll, inklusive navigering i fragmentet, fokusering och returnering av avgränsningsrektangeln för elementet.
IRawElementProviderFragmentRoot Ärver från IRawElementProviderFragment. Lägger till funktioner för rotelementet i en komplex kontroll, inklusive att hitta ett underordnat element vid angivna koordinater och ange fokustillståndet för hela kontrollen.

Följande gränssnitt tillhandahåller ytterligare funktioner men behöver inte implementeras.

Gränssnitt beskrivning
IRawElementProviderAdviseEvents Gör det möjligt för providern att spåra begäranden om händelser.
IRawElementProviderHwndOverride Möjliggör ompositionering av fönsterbaserade element i UI Automation-trädet i ett fragment.

Alla andra gränssnitt i System.Windows.Automation.Provider namnområdet är för stöd för kontrollmönster.

Krav för icke-WPF-leverantörer

För att kunna kommunicera med UI Automation måste din kontroll implementera följande huvudsakliga funktioner:

Funktioner Implementering
Exponera providern för UI Automation Som svar på ett WM_GETOBJECT meddelande som skickas till kontrollfönstret returnerar du objektet som implementerar IRawElementProviderSimple (eller ett härlett gränssnitt). För fragment måste detta vara providern för fragmentroten.
Ange egenskapsvärden Implementera GetPropertyValue för att ange eller åsidosätta värden.
Aktivera klienten för att interagera med kontrollen Implementera gränssnitt som stöder kontrollmönster, till exempel IInvokeProvider. Returnera dessa mönsterprovidrar i implementeringen av GetPatternProvider.
Skapa händelser Anropa en av de statiska metoderna AutomationInteropProvider för att skapa en händelse som en klient kan lyssna efter.
Aktivera navigering och fokusering i ett fragment Implementera IRawElementProviderFragment för varje element i fragmentet. (Inte nödvändigt för element som inte ingår i ett fragment.)
Aktivera fokusering och plats för underordnade element i ett fragment Implementera IRawElementProviderFragmentRoot. (Inte nödvändigt för element som inte är fragmentrötter.)

Egenskapsvärden i icke-WPF-providers

Leverantörer av användargränssnittsautomatisering för anpassade kontroller måste ha stöd för vissa egenskaper som kan användas av automationssystemet och av klientprogram. För element som finns i windows (HWND: er) kan UI Automation hämta vissa egenskaper från standardfönsterprovidern, men måste hämta andra från den anpassade providern.

Leverantörer för HWND-baserade kontroller behöver vanligtvis inte ange följande egenskaper (identifieras med fältvärden):

Kommentar

Ett RuntimeIdProperty enkelt element eller en fragmentrot som finns i ett fönster hämtas från fönstret. Fragmentelement under roten (till exempel listobjekt i en listruta) måste dock ange sina egna identifierare. Mer information finns i GetRuntimeId.

IsKeyboardFocusableProperty Ska returneras för leverantörer som finns i en Windows Forms-kontroll. I det här fallet kanske standardfönsterprovidern inte kan hämta rätt värde.

NameProperty Tillhandahålls vanligtvis av värdprovidern. Om till exempel en anpassad kontroll härleds från Controlhärleds namnet från Text kontrollens egenskap.

Exempelkod finns i Returnera egenskaper från en UI Automation-provider.

Händelser i icke-WPF-leverantörer

UI Automation-leverantörer bör skapa händelser för att meddela klientprogram om ändringar i användargränssnittets tillstånd. Följande metoder används för att skapa händelser.

Metod beskrivning
RaiseAutomationEvent Genererar olika händelser, inklusive händelser som utlöses av kontrollmönster.
RaiseAutomationPropertyChangedEvent Skapar en händelse när en UI Automation-egenskap har ändrats.
RaiseStructureChangedEvent Genererar en händelse när strukturen för UI Automation-trädet har ändrats. till exempel genom att ta bort eller lägga till ett element.

Syftet med en händelse är att meddela klienten om något som äger rum i användargränssnittet (användargränssnittet), oavsett om aktiviteten utlöses av själva UI Automation-systemet. Till exempel bör händelsen som identifieras av InvokedEvent aktiveras när kontrollen anropas, antingen via direkt användarindata eller av klientprogrammet som anropar Invoke.

För att optimera prestanda kan en provider selektivt generera händelser eller inte generera några händelser alls om inget klientprogram har registrerats för att ta emot dem. Följande metoder används för optimering.

Metod beskrivning
ClientsAreListening Den här statiska egenskapen anger om några klientprogram har prenumererat på UI Automation-händelser.
IRawElementProviderAdviseEvents Providerns implementering av det här gränssnittet på en fragmentrot gör att det kan rekommenderas när klienter registrerar och avregistrerar händelsehanterare för händelser i fragmentet.

Icke-WPF-providernavigering

Leverantörer för enkla kontroller, till exempel en anpassad knapp som finns i ett fönster (HWND) behöver inte ha stöd för navigering i UI Automation-trädet. Navigering till och från -elementet hanteras av standardprovidern för värdfönstret, som anges i implementeringen av HostRawElementProvider. När du implementerar en provider för en komplex anpassad kontroll måste du dock ha stöd för navigering mellan rotnoden i fragmentet och dess underordnade noder och mellan syskonnoder.

Kommentar

Element i ett annat fragment än roten måste returnera en null referens från HostRawElementProvider, eftersom de inte finns direkt i ett fönster, och ingen standardprovider kan stödja navigering till och från dem.

Strukturen för fragmentet bestäms av implementeringen av Navigate. För varje möjlig riktning från varje fragment returnerar den här metoden providerobjektet för elementet i den riktningen. Om det inte finns något element i den riktningen returnerar metoden en null referens.

Fragmentroten stöder endast navigering till underordnade element. En listruta returnerar till exempel det första objektet i listan när riktningen är FirstChildoch det sista objektet när riktningen är LastChild. Fragmentroten stöder inte navigering till en överordnad eller syskon. detta hanteras av värdfönsterprovidern.

Element i ett fragment som inte är roten måste stödja navigering till den överordnade och till eventuella syskon och underordnade som de har.

Reparenting för icke-WPF-provider

Popup-fönster är faktiskt fönster på den översta nivån, så som standard visas de i UI Automation-trädet som underordnade på skrivbordet. I många fall är dock popup-fönster logiskt underordnade till någon annan kontroll. Listrutan i en kombinationsruta är till exempel logiskt underordnad kombinationsrutan. På samma sätt är ett popup-fönster logiskt ett underordnat menyfönster. UI Automation ger stöd för att reparent popup-fönster så att de verkar vara underordnade till den associerade kontrollen.

Så här återställer du ett popup-fönster:

  1. Skapa en provider för popup-fönstret. Detta kräver att popup-fönstrets klass är känd i förväg.

  2. Implementera alla egenskaper och mönster som vanligt för popup-fönstret, som om det vore en kontroll i sig.

  3. HostRawElementProvider Implementera egenskapen så att den returnerar värdet som hämtats från HostProviderFromHandle, där parametern är fönsterhandtaget för popup-fönstret.

  4. Implementera Navigate för popup-fönstret och dess överordnade fönster så att navigeringen hanteras korrekt från den logiska överordnad till de logiska underordnade och mellan underordnade syskon.

När UI Automation stöter på popup-fönstret ser det att navigeringen åsidosätts från standardinställningen och hoppar över popup-fönstret när det påträffas som ett underordnat skrivbord. I stället kan noden bara nås via fragmentet.

Reparenting är inte lämpligt för fall där en kontroll kan vara värd för ett fönster i vilken klass som helst. Till exempel kan en omliste vara värd för alla typer av HWND i sina band. För att hantera dessa fall stöder UI Automation en alternativ form av HWND-omlokalisering, enligt beskrivningen i nästa avsnitt.

Ompositionering av icke-WPF-provider

UI Automation-fragment kan innehålla två eller flera element som var och en finns i ett fönster (HWND). Eftersom varje HWND har en egen standardprovider som anser att HWND är ett underordnat till en innehållande HWND, visar UI Automation-trädet som standard HWND:erna i fragmentet som underordnade i det överordnade fönstret. I de flesta fall är detta önskvärt beteende, men ibland kan det leda till förvirring eftersom det inte matchar användargränssnittets logiska struktur.

Ett bra exempel på detta är en omlistekontroll. Ett rebar innehåller band, som var och en i sin tur kan innehålla en HWND-baserad kontroll, till exempel ett verktygsfält, en redigeringsruta eller en kombinationsruta. Standardfönsterprovidern för omstapel-HWND ser bandkontroll-HWND:er som underordnade, och rebarprovidern ser banden som underordnade. Eftersom HWND-providern och rebarprovidern arbetar tillsammans och kombinerar sina underordnade, visas både banden och de HWND-baserade kontrollerna som underordnade i ompanelen. Logiskt sett bör dock endast banden visas som underordnade till omstapeln, och varje bandprovider ska kopplas till standard-HWND-providern för den kontroll som den innehåller.

För att åstadkomma detta exponerar fragmentrotprovidern för omstaken en uppsättning underordnade som representerar banden. Varje band har en enda provider som kan exponera egenskaper och mönster. I implementeringen av HostRawElementProviderreturnerar bandprovidern standardfönsterprovidern för kontrollen HWND, som den hämtar genom att anropa HostProviderFromHandleoch skicka in kontrollens fönsterhandtag. Slutligen implementerar IRawElementProviderHwndOverride fragmentrotprovidern för ompanelen gränssnittet och i dess implementering av GetOverrideProviderForHwnd det returneras lämplig bandprovider för kontrollen som finns i den angivna HWND:en.

Se även