Implementacja dostawcy automatyzacji interfejsu użytkownika po stronie serwera

Uwaga / Notatka

Ta dokumentacja jest przeznaczona dla deweloperów programu .NET Framework, którzy chcą używać zarządzanych klas automatyzacji interfejsu użytkownika zdefiniowanych w przestrzeni nazw System.Windows.Automation. Aby uzyskać najnowsze informacje na temat automatyzacji interfejsu użytkownika, zobacz Windows Automation API: Automatyzacja interfejsu użytkownika.

W tej sekcji opisano sposób implementowania dostawcy automatyzacji interfejsu użytkownika po stronie serwera dla kontrolki niestandardowej.

Implementacja elementów windows Presentation Foundation (WPF) i elementów innych niż WPF (takich jak te przeznaczone dla windows Forms) jest zasadniczo inna. Elementy WPF zapewniają obsługę automatyzacji interfejsu użytkownika za pośrednictwem klasy wywodzącej się z AutomationPeer. Elementy inne niż WPF zapewniają obsługę za pośrednictwem implementacji interfejsów dostawcy.

Zagadnienia związane z zabezpieczeniami

Dostawcy powinni być napisani, aby mogli działać w środowisku z częściowym zaufaniem. Ponieważ UIAutomationClient.dll nie jest skonfigurowany do uruchamiania w ramach częściowego zaufania, kod dostawcy nie powinien odwoływać się do tego zestawu. Jeśli tak się stanie, kod może być uruchamiany w środowisku o pełnym zaufaniu, ale następnie kończy się niepowodzeniem w środowisku częściowego zaufania.

W szczególności nie należy używać pól z klas w UIAutomationClient.dll, takich jak te w .AutomationElement Zamiast tego użyj równoważnych pól z klas w UIAutomationTypes.dll, takich jak AutomationElementIdentifiers.

Implementacja dostawcy za pomocą elementów Windows Presentation Foundation

Aby uzyskać więcej informacji na ten temat, proszę zobaczyć Automatyzację interfejsu użytkownika niestandardowej kontrolki WPF.

Implementacja dostawcy z użyciem elementów nie będących elementami WPF

Kontrolki niestandardowe, które nie są częścią struktury WPF, ale są napisane w kodzie zarządzanym (najczęściej są to kontrolki windows Forms), zapewniają obsługę automatyzacji interfejsu użytkownika przez implementowanie interfejsów. Każdy element musi zaimplementować co najmniej jeden z interfejsów wymienionych w pierwszej tabeli w następnej sekcji. Ponadto jeśli element obsługuje co najmniej jeden wzorzec sterowania, musi zaimplementować odpowiedni interfejs dla każdego wzorca kontrolki.

Projekt dostawcy automatyzacji interfejsu użytkownika musi odwoływać się do następujących zestawów:

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Interfejsy dostawcy

Każdy dostawca automatyzacji interfejsu użytkownika musi zaimplementować jeden z następujących interfejsów.

Interfejs Opis
IRawElementProviderSimple Udostępnia funkcje prostej kontrolki hostowanej w oknie, w tym obsługę wzorców i właściwości kontrolek.
IRawElementProviderFragment Dziedziczy z obiektu IRawElementProviderSimple. Dodaje funkcjonalność dla elementu w złożonej kontrolce, w tym nawigację w ramach fragmentu, ustawianie fokusu i zwracanie prostokąta obwiedni elementu.
IRawElementProviderFragmentRoot Dziedziczy po IRawElementProviderFragment. Dodaje funkcje elementu głównego w złożonej kontrolce, w tym lokalizowanie elementu podrzędnego na określonych współrzędnych i ustawianie stanu koncentracji uwagi dla całej kontrolki.

Następujące interfejsy zapewniają dodatkowe funkcje, ale nie są wymagane do zaimplementowania.

Interfejs Opis
IRawElementProviderAdviseEvents Umożliwia dostawcy śledzenie żądań dotyczących zdarzeń.
IRawElementProviderHwndOverride Umożliwia zmianę położenia elementów okiennych w drzewie automatyzacji interfejsu użytkownika we fragmencie.

Wszystkie inne interfejsy w przestrzeni nazw System.Windows.Automation.Provider służą wsparciu wzorca sterowania.

Wymagania dotyczące dostawców innych niż WPF

Aby móc komunikować się z automatyzacją interfejsu użytkownika, kontrolka musi implementować następujące główne obszary funkcjonalności:

Funkcjonalność Implementacja
Udostępnianie dostawcy dla Automatyzacji interfejsu użytkownika W przypadku komunikatu WM_GETOBJECT wysłanego do okna sterowania należy zwrócić obiekt, który implementuje IRawElementProviderSimple (lub interfejs pochodny). W przypadku fragmentów, musi to być dostawca korzenia fragmentu.
Podaj wartości właściwości Zaimplementuj GetPropertyValue , aby podać lub zastąpić wartości.
Umożliwia klientowi interakcję z kontrolką Zaimplementuj interfejsy obsługujące wzorce sterowania, takie jak IInvokeProvider. Zwróć tych dostawców wzorców w implementacji programu GetPatternProvider.
Zgłaszanie zdarzeń Wywołaj jedną ze statycznych metod AutomationInteropProvider, aby zgłosić zdarzenie, na które klient może nasłuchiwać.
Włączanie nawigacji i koncentracji uwagi w obrębie fragmentu Zaimplementuj IRawElementProviderFragment dla każdego elementu w obrębie fragmentu. (Nie jest to konieczne w przypadku elementów, które nie są częścią fragmentu).
Włącz wyszukiwanie i namierzanie elementu podrzędnego w fragmencie Zaimplementuj IRawElementProviderFragmentRoot. (Nie jest to konieczne w przypadku elementów, które nie są fragmentami korzeni).

Wartości właściwości w dostawcach innych niż WPF

Dostawcy automatyzacji interfejsu użytkownika dla kontrolek niestandardowych muszą obsługiwać pewne właściwości, które mogą być używane przez system automatyzacji, a także przez aplikacje klienckie. W przypadku elementów hostowanych w systemie Windows (HWNDs) automatyzacja interfejsu użytkownika może pobrać niektóre właściwości od domyślnego dostawcy okien, ale musi uzyskać inne od dostawcy niestandardowego.

Dostawcy kontrolek opartych na HWND zwykle nie muszą udostępniać następujących właściwości (zidentyfikowanych przez wartości pól):

Uwaga / Notatka

Element RuntimeIdProperty prosty lub korzeń fragmentu hostowany w oknie jest uzyskiwany z okna; jednak elementy fragmentu znajdujące się poniżej korzenia (takie jak elementy listy w polu listy) muszą same mieć swoje identyfikatory. Aby uzyskać więcej informacji, zobacz GetRuntimeId.

Element IsKeyboardFocusableProperty powinien zostać zwrócony dla dostawców hostowanych w kontrolce Windows Forms. W takim przypadku domyślny dostawca okien może nie być w stanie pobrać poprawnej wartości.

Element NameProperty jest zwykle dostarczany przez dostawcę hosta. Jeśli na przykład niestandardowa kontrolka pochodzi z Control, nazwa pochodzi z Text właściwości kontrolki.

Przykładowy kod można znaleźć w temacie Zwracanie właściwości od dostawcy automatyzacji interfejsu użytkownika.

Zdarzenia u dostawców niezwiązanych z WPF

Dostawcy automatyzacji interfejsu użytkownika powinni zgłaszać zdarzenia w celu powiadamiania aplikacji klienckich o zmianach w stanie interfejsu użytkownika. Następujące metody służą do zgłaszania zdarzeń.

Metoda Opis
RaiseAutomationEvent Wywołuje różne zdarzenia, w tym zdarzenia wyzwalane przez schematy sterowania.
RaiseAutomationPropertyChangedEvent Zgłasza zdarzenie, gdy właściwość automatyzacji interfejsu użytkownika uległa zmianie.
RaiseStructureChangedEvent Zgłasza zdarzenie, gdy struktura drzewa automatyzacji interfejsu użytkownika uległa zmianie; na przykład przez usunięcie lub dodanie elementu.

Celem zdarzenia jest powiadomienie klienta o czymś, co ma miejsce w interfejsie użytkownika, niezależnie od tego, czy działanie jest wyzwalane przez sam system automatyzacji interfejsu użytkownika. Na przykład zdarzenie zidentyfikowane przez InvokedEvent powinno być zgłaszane za każdym razem, gdy kontrolka jest wywoływana, za pośrednictwem bezpośredniego wprowadzania danych przez użytkownika lub przez aplikację kliencką wywołującą Invoke.

Aby zoptymalizować wydajność, dostawca może selektywnie zwiększać zdarzenia lub w ogóle ich nie zwiększać, jeśli żadna aplikacja kliencka nie jest zarejestrowana do ich odbierania. Poniższe metody są używane do optymalizacji.

Metoda Opis
ClientsAreListening Ta właściwość statyczna określa, czy wszystkie aplikacje klienckie mają subskrybowane zdarzenia automatyzacji interfejsu użytkownika.
IRawElementProviderAdviseEvents Implementacja tego interfejsu przez dostawcę w głównym węźle fragmentu umożliwia powiadamianie go, gdy klienci rejestrują i wyrejestrowują programy obsługi zdarzeń dla zdarzeń w fragmencie.

Nawigacja dostawcy niezależna od WPF

Dostawcy prostych kontrolek, takich jak przycisk niestandardowy hostowany w oknie (HWND), nie muszą obsługiwać nawigacji w drzewie automatyzacji interfejsu użytkownika. Nawigacja do i z elementu jest obsługiwana przez domyślnego dostawcę dla okna hosta, który jest określony w implementacji programu HostRawElementProvider. Podczas implementowania dostawcy dla złożonej kontrolki niestandardowej należy jednak obsługiwać nawigację między węzłem głównym fragmentu i jego elementami podrzędnymi oraz między węzłami równorzędnymi.

Uwaga / Notatka

Elementy fragmentu innego niż korzeń muszą zwracać null odwołanie z HostRawElementProvider, ponieważ nie są bezpośrednio hostowane w oknie, a żaden domyślny dostawca nie obsługuje nawigacji do nich i z nich.

Struktura fragmentu jest określana przez twoją implementację Navigate. Dla każdego możliwego kierunku z każdego fragmentu ta metoda zwraca obiekt dostawcy dla elementu w tym kierunku. Jeśli w tym kierunku nie ma żadnego elementu, metoda zwraca odwołanie null.

Katalog główny fragmentu obsługuje nawigację tylko do elementów podrzędnych. Na przykład pole listy zwraca pierwszy element na liście, gdy kierunek to FirstChild, a ostatni element, gdy kierunek to LastChild. Katalog główny fragmentu nie obsługuje nawigacji do elementu nadrzędnego lub równorzędnego; Jest to obsługiwane przez dostawcę okna hosta.

Elementy fragmentu, które nie są elementem głównym, muszą obsługiwać nawigację do elementu nadrzędnego oraz do wszystkich swoich elementów równorzędnych i podrzędnych.

Ponowne przypisanie usługi innej niż WPF

Okna podręczne są w rzeczywistości oknami najwyższego poziomu, dlatego domyślnie są wyświetlane w drzewie automatyzacji UI jako elementy podrzędne pulpitu. W wielu przypadkach okna podręczne są jednak logicznie dziećmi innych kontrolek. Na przykład lista rozwijana w polu kombi jest logicznie elementem podrzędnym pola kombi. Podobnie, okno podręczne menu jest logicznie podrzędnym elementem menu. Automatyzacja interfejsu użytkownika zapewnia obsługę ponownego uruchamiania wyskakujących okienek tak, aby wydawały się być elementami podrzędnych skojarzonej kontrolki.

Aby powtórzyć okno podręczne:

  1. Utwórz dostawcę dla okna podręcznego. Wymaga to wcześniejszego poznania klasy okna podręcznego.

  2. Zaimplementuj wszystkie właściwości i wzorce jak zwykle dla tego wyskakującego okienka, tak jakby była to kontrolka we własnym zakresie.

  3. Zaimplementuj właściwość HostRawElementProvider tak, aby zwracała wartość uzyskaną z HostProviderFromHandle klasy, gdzie parametr jest uchwytem okna podręcznego.

  4. Zaimplementuj mechanizm Navigate dla okna podręcznego i jego elementu nadrzędnego, aby nawigacja była prawidłowo obsługiwana z logicznego rodzica do logicznych dzieci oraz między dziećmi równorzędnymi.

Gdy usługa Automatyzacja interfejsu użytkownika napotka okno podręczne, rozpoznaje, że nawigacja jest zastępowana z domyślnego ustawienia, i pomija je, gdy jest ono napotkane jako element podrzędny pulpitu. Zamiast tego węzeł będzie dostępny tylko za pośrednictwem fragmentu.

Reparenting nie jest odpowiedni w przypadkach, w których kontrolka może hostować okno dowolnej klasy. Na przykład rebar może pomieścić dowolny typ HWND w swoich pasmach. Aby obsłużyć te przypadki, UI Automation obsługuje alternatywną formę relokacji HWND, jak opisano w następnej sekcji.

Zmiana położenia dostawcy spoza WPF

Fragmenty automatyzacji interfejsu użytkownika mogą zawierać dwa lub więcej elementów, z których każdy jest zawarty w oknie (HWND). Ponieważ każdy HWND ma własnego domyślnego dostawcę, który uważa, że HWND jest elementem podrzędnym zawierającego HWND, drzewo automatyzacji interfejsu użytkownika będzie domyślnie pokazywać HWND w fragmentze jako elementy podrzędne okna nadrzędnego. W większości przypadków jest to pożądane zachowanie, ale czasami może prowadzić do nieporozumień, ponieważ nie pasuje do logicznej struktury interfejsu użytkownika.

Dobrym przykładem jest kontrolka paska pomocniczego. Pasek nawigacyjny zawiera paski, z których każda może z kolei zawierać kontrolkę opartą na HWND, taką jak pasek narzędzi, pole edycji lub pole kombi. Domyślny dostawca okien dla paska ponownego HWND widzi kontrolki pasma HWND jako elementów podrzędnych, a dostawca paska pomocniczego widzi pasma jako elementy podrzędne. Ponieważ dostawca HWND i dostawca paska narzędziowego pracują w tandemie i łączą swoje elementy podrzędne, zarówno zespoły, jak i kontrolki oparte na HWND pojawiają się jako elementy podrzędne paska narzędziowego. Logicznym jednak jest, że tylko pasma powinny pojawiać się jako elementy podrzędne rebar, a każdy dostawca pasm powinien być powiązany z domyślnym dostawcą HWND dla kontrolki zawartej w nim.

W tym celu dostawca główny fragmentu paska pomocniczego uwidacznia zestaw elementów podrzędnych reprezentujących pasma. Każde pasmo ma jednego dostawcę, który może ujawniać właściwości i wzorce. W implementacji dostawcy pasma HostRawElementProvider zwraca domyślnego dostawcę okien dla kontrolki typu HWND, który uzyskuje przez wywołanie metody HostProviderFromHandle, przekazując uchwyt okna kontrolki. Na koniec główny dostawca fragmentów dla rebar implementuje interfejs IRawElementProviderHwndOverride, a w swojej implementacji GetOverrideProviderForHwnd zwraca odpowiedniego dostawcę pasm dla kontrolki określonej przez HWND.

Zobacz także