Implémentation de fournisseur UI Automation côté serveur

Mise à jour : novembre 2007

Cette section explique comment implémenter un fournisseur UI Automation côté serveur pour un contrôle personnalisé.

L'implémentation pour les éléments Windows Presentation Foundation (WPF) et les éléments non WPF (tels que ceux conçus pour Windows Forms) est fondamentalement différente. Les éléments WPF assurent la prise en charge de UI Automation par le biais d'une classe dérivée de AutomationPeer. Les éléments non WPF fournissent une prise en charge via l'implémentation d'interfaces de fournisseurs.

Cette rubrique comprend les sections suivantes.

  • Considérations sur la sécurité
  • Implémentation de fournisseur par les éléments Windows Presentation Foundation
  • Implémentation de fournisseur par des éléments non WPF
  • Rubriques connexes

Considérations sur la sécurité

Vous devez écrire aux fournisseurs afin qu'ils puissent travailler dans un environnement de confiance partielle. Étant donné que UIAutomationClient.dll n'est pas configuré pour s'exécuter avec un niveau de confiance partielle, le code de votre fournisseur ne doit pas référencer cet assembly. Dans ce cas, le code peut s'exécuter dans un environnement de confiance totale mais il échoue dans un environnement de confiance partielle.

Surtout, n'utilisez pas de champs de classes, tels que ceux de l'AutomationElement, dans UIAutomationClient.dll. Utilisez plutôt les champs de classes équivalents, tels que les AutomationElementIdentifiers, dans UIAutomationTypes.dll.

Implémentation de fournisseur par les éléments Windows Presentation Foundation

Pour plus d'informations sur cette rubrique, consultez UI Automation d'un contrôle personnalisé WPF.

Implémentation de fournisseur par des éléments non WPF

Les contrôles personnalisés qui ne font pas partie de l'infrastructure WPF, mais qui sont rédigés en code managé (le plus souvent, ce sont des contrôles Windows Forms), fournissent une prise en charge pour UI Automation en implémentant des interfaces. Chaque élément doit implémenter au moins une des interfaces répertoriées dans le premier tableau de la section suivante. De plus, si l'élément prend en charge un ou plusieurs modèles de contrôle, il doit implémenter l'interface appropriée pour chaque modèle de contrôle.

Le projet de votre fournisseur UI Automation doit référencer les assemblys suivants :

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Cette section comprend les sous-sections suivantes.

  • Interfaces de fournisseur
  • Spécifications pour les fournisseurs non WPF
  • Valeurs de la propriété dans les fournisseurs non WPF
  • Événements chez les fournisseurs non WPF
  • Navigation d'un fournisseur non WPF
  • Définition de l'état de parent d'un fournisseur non WPF
  • Repositionnement d'un fournisseur non WPF

Interfaces de fournisseur

Chaque fournisseur UI Automation doit implémenter l'une des interfaces suivantes.

Interface

Description

IRawElementProviderSimple

Fournit les fonctionnalités pour un contrôle simple hébergé dans une fenêtre, y compris une prise en charge pour les modèles de contrôle et les propriétés.

IRawElementProviderFragment

Hérite de IRawElementProviderSimple. Ajoute des fonctionnalités à l'élément d'un contrôle complexe, y compris les fonctionnalités permettant de naviguer dans le fragment, de définir le focus et de retourner le rectangle englobant de l'élément.

IRawElementProviderFragmentRoot

Hérite de IRawElementProviderFragment. Ajoute des fonctionnalités à l'élément racine d'un contrôle complexe, y compris la localisation d'un élément enfant à des coordonnées spécifiées et la définition de l'état du focus pour l'ensemble du contrôle.

Les interfaces suivantes fournissent des fonctionnalités supplémentaires mais leur implémentation n'est pas obligatoire.

Interface

Description

IRawElementProviderAdviseEvents

Permet au fournisseur de suivre des demandes pour des événements.

IRawElementProviderHwndOverride

Active le repositionnement d'éléments basés sur une fenêtre dans l'arborescence UI Automation d'un fragment.

Toutes les autres interfaces de l'espace de noms System.Windows.Automation.Provider concernent la prise en charge du modèle de contrôle.

Spécifications pour les fournisseurs non WPF

Pour communiquer avec UI Automation, votre contrôle doit implémenter les principaux domaines de fonctionnalités répertoriés dans le tableau ci-dessous :

Fonctionnalité

Implémentation

Exposer le fournisseur à UI Automation

En réponse à un message WM_GETOBJECT envoyé à la fenêtre de contrôle, retournez l'objet qui implémente IRawElementProviderSimple (ou une interface dérivée). Pour les fragments, il doit s'agir du fournisseur pour la racine du fragment.

Fournir des valeurs de propriété

Implémentez GetPropertyValue pour fournir ou substituer des valeurs.

Permettre au client d'interagir avec le contrôle

Implémentez des interfaces qui prennent en charge des modèles de contrôle, tels que IInvokeProvider. Retournez ces fournisseurs de modèles dans votre implémentation de GetPatternProvider.

Déclencher des événements

Appelez l'une des méthodes statiques de AutomationInteropProvider pour déclencher un événement que le client pourra écouter.

Activer la navigation et le focus dans un fragment

Implémentez IRawElementProviderFragment pour chaque élément du fragment (sauf pour les éléments qui ne font pas partie d'un fragment).

Activer le focus et l'emplacement d'un élément enfant dans un fragment

Implémentez IRawElementProviderFragmentRoot. (Sauf pour les éléments qui ne sont pas des racines de fragment.)

Valeurs de la propriété dans les fournisseurs non WPF

Les fournisseurs UI Automation pour les contrôles personnalisés doivent prendre en charge certaines propriétés qui peuvent être utilisées aussi bien par le système d'automatisation que par les applications clientes. Pour les éléments hébergés dans des fenêtres (HWND), UI Automation peut récupérer certaines propriétés depuis un fournisseur de fenêtre par défaut, mais elle doit en obtenir d'autres depuis le fournisseur personnalisé.

Habituellement, les fournisseurs de contrôles basés sur HWND n'ont pas besoin de fournir les propriétés suivantes (identifiées par des valeurs de champ) :

Remarque :

La RuntimeIdProperty d'un simple élément ou d'une racine de fragment hébergée dans une fenêtre est obtenue depuis la fenêtre ; toutefois, les éléments fragments sous la racine (tels que des éléments de liste dans une zone de liste) doivent fournir leurs propres identificateurs. Pour plus d'informations, consultez GetRuntimeId.

La IsKeyboardFocusableProperty doit être retournée pour les fournisseurs hébergés dans un contrôle Windows Forms. Dans ce cas, le fournisseur de fenêtre par défaut ne pourra peut-être pas récupérer la bonne valeur.

La NameProperty est habituellement fournie par le fournisseur hôte. Par exemple, si un contrôle personnalisé est dérivé de Control, le nom est dérivé de la propriété Text du contrôle.

Pour obtenir un exemple de code, consultez Retourner les propriétés d'un fournisseur UI Automation.

Événements chez les fournisseurs non WPF

Les fournisseurs UI Automation doivent déclencher des événements pour informer les applications clientes de la modification de l'état de l'interface utilisateur. Les méthodes suivantes sont utilisées pour déclencher des événements.

Méthode

Description

RaiseAutomationEvent

Déclenche différents événements, y compris les événements déclenchés par les modèles de contrôle.

RaiseAutomationPropertyChangedEvent

Déclenche un événement lorsqu'une propriété UI Automation a été modifiée.

RaiseStructureChangedEvent

Déclenche un événement lorsque la structure de l'arborescence UI Automation a été modifiée ; par exemple, en ajoutant ou en supprimant un élément.

Le but d'un événement est d'informer le client que quelque chose est en train de se passer dans l'interface utilisateur (UI), que l'activité soit ou non déclenchée par le système UI Automation lui-même. Par exemple, l'événement identifié par InvokedEvent doit être déclenché chaque fois que le contrôle est appelé, via l'entrée d'utilisateur direct ou par l'application cliente appelant Invoke.

Pour optimiser les performances, un fournisseur peut déclencher des événements de manière sélective ou ne pas en déclencher du tout si aucune application cliente n'est enregistrée pour les recevoir. Les méthodes suivantes sont utilisées pour l'optimisation.

Méthode

Description

ClientsAreListening

Cette propriété statique spécifie si des applications clientes se sont abonnées à des événements UI Automation.

IRawElementProviderAdviseEvents

Le fait que l'implémentation de cette interface soit effectuée par le fournisseur sur une racine de fragment lui permet d'être avertie lorsque des clients enregistrent et annulent l'enregistrement de gestionnaires d'événements pour les événements situés sur le fragment.

Les fournisseurs de simples contrôles tels qu'un bouton personnalisé hébergé dans une fenêtre (HWND) n'ont pas besoin de prendre en charge la navigation dans l'arborescence UI Automation. La navigation vers et depuis l'élément est contrôlée par le fournisseur par défaut de la fenêtre hôte, ce qui est spécifié dans l'implémentation de HostRawElementProvider. Lorsque vous implémentez un fournisseur pour un contrôle personnalisé complexe, vous devez toutefois prendre en charge la navigation entre le nœud racine du fragment et ses descendants, et entre nœuds frères.

Remarque :

Les éléments d'un fragment autre que la racine doivent retourner une référence null depuis HostRawElementProvider car ils ne sont pas hébergés directement dans une fenêtre et aucun fournisseur par défaut ne peut prendre en charge la navigation vers et depuis ces éléments.

La structure du fragment est déterminée par votre implémentation de Navigate. Pour chaque direction possible à partir de chaque fragment, cette méthode retourne l'objet de fournisseur pour l'élément dans cette direction. S'il n'y a aucun élément dans cette direction, la méthode retourne une référence null.

La racine du fragment prend uniquement en charge la navigation des éléments enfants. Par exemple, une zone de liste retourne le premier élément de la liste lorsque la direction est FirstChild et le dernier élément lorsque la direction est LastChild. La racine du fragment ne prend pas en charge la navigation vers un parent ou des frères ; cela est contrôlé par le fournisseur de fenêtre hôte.

Les éléments d'un fragment qui ne sont pas la racine doivent prendre en charge la navigation vers le parent et tous ses frères et enfants.

Définition de l'état de parent d'un fournisseur non WPF

Les fenêtres indépendantes sont en fait des fenêtres de niveau supérieur et elles apparaissent par défaut dans l'arborescence UI Automation en tant qu'enfants du bureau. Toutefois, dans la plupart des cas, les fenêtres indépendantes sont logiquement enfants d'autres contrôles. Par exemple, la liste déroulante d'une zone de liste déroulante est logiquement enfant de la zone de liste déroulante. De la même façon, une fenêtre indépendante de menu est logiquement enfant du menu. UI Automation fournit une prise en charge pour définir l'état de changement de parent des fenêtres indépendantes afin qu'elles apparaissent comme des enfants du contrôle associé.

Pour définir l'état de changement de parent d'une fenêtre indépendante :

  1. Créez un fournisseur pour la fenêtre indépendante. Pour cela, il faut que la classe de la fenêtre indépendante soit connue à l'avance.

  2. Implémentez toutes les propriétés et tous les modèles habituels pour ce menu contextuel, comme s'il s'agissait d'un contrôle.

  3. Implémentez la propriété HostRawElementProvider afin qu'elle retourne la valeur obtenue depuis HostProviderFromHandle, où le paramètre est le handle de fenêtre de la fenêtre indépendante.

  4. Implémentez Navigate pour la fenêtre indépendante et son parent afin que la navigation soit correctement contrôlée du parent logique aux enfants logiques, et entre enfants de mêmes parents.

Lorsque UI Automation rencontre la fenêtre indépendante, elle reconnaît que cette navigation est substituée à la valeur par défaut et elle ignore la fenêtre indépendante lorsqu'elle est rencontrée en tant qu'enfant du bureau. À la place, le nœud sera accessible uniquement via le fragment.

La définition de l'état de parent n'est pas appropriée lorsqu'un contrôle peut héberger une fenêtre de n'importe quelle classe. Par exemple, un rebar peut héberger tout type de fenêtre HWND dans ses bandes. Pour gérer ces cas, UI Automation prend en charge une autre forme de réadressage HWND, comme décrit dans la section suivante.

Repositionnement d'un fournisseur non WPF

Les fragments UI Automation peuvent contenir deux éléments ou plus, tous contenus dans une fenêtre (HWND). Comme chaque HWND possède son propre fournisseur par défaut qui considère le HWND comme l'enfant d'un HWND contenant, l'arborescence UI Automation affiche, par défaut, les HWND dans le fragment en tant qu'enfants de la fenêtre parente. Dans la plupart des cas, ce comportement est conseillé, mais il peut parfois porter à confusion car il ne correspond pas à la structure logique de l'interface utilisateur.

Le contrôle rebar en est l'exemple parfait. Un rebar contient des bandes, qui peuvent, elles aussi, contenir un contrôle basé sur HWND, tel qu'une barre d'outils, une zone d'édition ou une zone de liste déroulante. Le fournisseur de fenêtre par défaut du HWND rebar affiche les HWND du contrôle de bandes comme des enfants et le fournisseur rebar affiche les bandes comme des enfants. Étant donné que le fournisseur HWND et le fournisseur rebar travaillent en tandem et qu'ils mélangent leurs enfants, les bandes et les contrôles basés sur HWND apparaissent comme les enfants du rebar. Toutefois, seules les bandes devraient apparaître comme les enfants du rebar et chaque fournisseur de bandes devrait être associé au fournisseur HWND par défaut pour le contrôle qu'il contient.

Pour cela, le fournisseur de la racine du fragment pour le rebar expose un jeu d'enfants représentant les bandes. Chaque bande possède un seul fournisseur qui peut exposer des propriétés et des modèles. Dans son implémentation de HostRawElementProvider, le fournisseur de bandes retourne le fournisseur de fenêtre par défaut pour le HWND de contrôle qu'il obtient en appelant HostProviderFromHandle, en passant le handle de fenêtre du contrôle. Pour finir, le fournisseur de la racine du fragment pour le rebar implémente l'interface IRawElementProviderHwndOverride et, dans son implémentation de GetOverrideProviderForHwnd, il retourne le fournisseur de bandes approprié pour le contrôle contenu dans le HWND spécifié.

Voir aussi

Tâches

Exposer un fournisseur UI Automation côté serveur

Retourner les propriétés d'un fournisseur UI Automation

Déclencher des événements à partir d'un fournisseur UI Automation

Activer la navigation dans un fournisseur de fragment UI Automation

Prendre en charge des modèles de contrôle dans un fournisseur UI Automation

Fournisseur simple, exemple

Fournisseur de fragment, exemple

Concepts

Vue d'ensemble des fournisseurs UI Automation