Partager via


Inscrire des propriétés, des événements et des modèles de contrôle personnalisés

Avant qu’une propriété, un événement ou un modèle de contrôle personnalisé puisse être utilisé, le fournisseur et le client doivent inscrire la propriété, l’événement ou le modèle de contrôle au moment de l’exécution. L’inscription est effective globalement au sein d’un processus d’application et reste effective jusqu’à ce que le processus se ferme ou que le dernier objet d’élément Microsoft UI Automation (IUIAutomation ou IRawElementProviderSimple) soit libéré dans le processus.

L’inscription implique de passer un GUID à UI Automation, ainsi que des informations détaillées sur la propriété, l’événement ou le modèle de contrôle personnalisés. La tentative d’inscription du même GUID une deuxième fois avec les mêmes informations réussit, mais la tentative d’inscription du même GUID une deuxième fois, mais avec des informations différentes (par exemple, une propriété personnalisée d’un type différent) échoue. À l’avenir, si la spécification personnalisée est acceptée et intégrée au UI Automation cœur, UI Automation validera les informations d’inscription personnalisées et utilisera le code déjà inscrit au lieu de l’implémentation de l’infrastructure « officielle », réduisant ainsi les problèmes de compatibilité des applications. Vous ne pouvez pas supprimer des propriétés, des événements ou des modèles de contrôle qui sont déjà inscrits.

Cette rubrique contient les sections suivantes :

Inscription de propriétés et d’événements personnalisés

L’inscription d’une propriété ou d’un événement personnalisé permet au fournisseur et au client d’obtenir un ID pour la propriété ou l’événement, qui peut ensuite être passé à différentes méthodes d’API qui prennent des ID en tant que paramètres.

Pour inscrire une propriété ou un événement :

  1. Définissez un GUID pour la propriété ou l’événement personnalisé.
  2. Remplissez une structure UIAutomationPropertyInfo ou UIAutomationEventInfo avec des informations sur la propriété ou l’événement, y compris le GUID et une chaîne non localisable qui contient le nom de la propriété ou de l’événement personnalisé. Les propriétés personnalisées nécessitent également que le type de données de la propriété soit spécifié, par exemple, si la propriété contient un entier ou une chaîne. Le type de données doit être l’un des types suivants spécifiés par l’énumération UIAutomationType . Aucun autre type de données n’est pris en charge pour les propriétés personnalisées.
    • UIAutomationType_Bool
    • UIAutomationType_Double
    • UIAutomationType_Element
    • UIAutomationType_Int
    • UIAutomationType_Point
    • UIAutomationType_String
  3. Utilisez la fonction CoCreateInstance pour créer un instance de l’objet CUIAutomationRegistrar et récupérer un pointeur vers l’interface IUIAutomationRegistrar de l’objet.
  4. Appelez la méthode IUIAutomationRegistrar::RegisterProperty ou RegisterEvent et transmettez l’adresse de la structure UIAutomationPropertyInfo ou de la structure UIAutomationEventInfo .

La méthode IUIAutomationRegistrar::RegisterProperty ou RegisterEvent retourne un ID de propriété ou un ID d’événement qu’une application peut passer à n’importe quelle méthode UI Automation qui prend un identificateur en tant que paramètre. Par exemple, vous pouvez passer un ID de propriété inscrit à la méthode IUIAutomationElement::GetCurrentPropertyValue ou à la méthode IUIAutomation::CreatePropertyCondition .

L’exemple suivant montre comment inscrire une propriété personnalisée.

// Declare a variable for holding the custom property ID.
PATTERNID g_MyCustomPropertyID;
// Define a GUID for the custom property.
GUID GUID_MyCustomProperty = { 0x82f383ff, 0x4b4d, 0x40d3, 
    { 0x8e, 0xd2, 0x90, 0xb5, 0x25, 0x8e, 0xaa, 0x19 } };

HRESULT RegisterProperty()
{
    // Fill the structure with the GUID, name, and data type.
    UIAutomationPropertyInfo MyCustomPropertyInfo = 
    {
        GUID_MyCustomProperty,
        L"MyCustomProp",
        UIAutomationType_String
    };

    // Create the registrar object and get the IUIAutomationRegistrar 
    // interface pointer. 
    IUIAutomationRegistrar * pUIARegistrar = NULL;
    CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER, 
            IID_IUIAutomationRegistrar, (void **)&pUIARegistrar);

    if (pUIARegistrar == NULL)
        return E_NOINTERFACE;

    // Register the property and retrieve the property ID. 
    HRESULT hr = pUIARegistrar->RegisterProperty(&MyCustomPropertyInfo, &g_MyCustomPropertyID);
    pUIARegistrar->Release();

    return hr;
}

Les identificateurs de propriété et d’événement récupérés par les méthodes IUIAutomationRegistrar::RegisterProperty et RegisterEvent sont valides uniquement dans le contexte de l’application qui les récupère, et uniquement pendant la durée de vie de l’application. Les méthodes d’inscription peuvent retourner différentes valeurs entières pour le même GUID lorsqu’il est appelé sur différentes instances d’exécution de la même application.

Il n’existe aucune méthode qui annule l’inscription d’une propriété ou d’un événement personnalisé. Au lieu de cela, ils sont implicitement désinscrits lorsque le dernier objet UI Automation est libéré.

Important

Si votre code est un client Microsoft Active Accessibility (MSAA), vous devez appeler la fonction NotifyWinEvent lorsque vous modifiez la valeur d’une propriété personnalisée.

 

Implémentation de modèles de contrôle personnalisés

Un modèle de contrôle personnalisé n’est pas inclus dans l’API UI Automation, mais est fourni par un tiers au moment de l’exécution. Les développeurs d’applications clientes et de fournisseurs doivent travailler ensemble pour définir un modèle de contrôle personnalisé, y compris les méthodes, les propriétés et les événements pris en charge par le modèle de contrôle. Après avoir défini le modèle de contrôle, le client et le fournisseur doivent implémenter des objets COM (Component Object Model) prenant en charge, ainsi que du code pour inscrire le modèle de contrôle au moment de l’exécution. Un modèle de contrôle personnalisé nécessite l’implémentation de deux objets COM : un wrapper client et un gestionnaire de modèle.

Notes

Les exemples des rubriques suivantes illustrent comment implémenter un modèle de contrôle personnalisé qui duplique les fonctionnalités du modèle de contrôle Valeur existant. Ces exemples sont fournis à des fins pédagogiques uniquement. Un modèle de contrôle personnalisé réel doit fournir des fonctionnalités qui ne sont pas disponibles à partir des modèles de contrôle UI Automation standard.

 

Wrapper client et gestionnaire de modèles

Le wrapper client implémente l’API utilisée par le client pour récupérer les propriétés et appeler les méthodes exposées par le modèle de contrôle personnalisé. L’API est implémentée en tant qu’interface COM qui transmet toutes les demandes de propriété et les appels de méthode au cœur UI Automation, qui marshale ensuite les demandes et les appels au fournisseur.

Le code qui inscrit un modèle de contrôle personnalisé doit fournir une fabrique de classes que UI Automation pouvez utiliser pour créer des instances de l’objet wrapper client. Lorsqu’un modèle de contrôle personnalisé est correctement inscrit, UI Automation retourne un pointeur d’interface IUIAutomationPatternInstance qui est utilisé par le client pour transférer les demandes de propriété et les appels de méthodes au cœur UI Automation.

Côté fournisseur, le cœur UI Automation prend les demandes de propriété et les appels de méthode du client et les transmet à l’objet de gestionnaire de modèle. Le gestionnaire de modèles appelle ensuite les méthodes appropriées sur l’interface du fournisseur pour le modèle de contrôle personnalisé.

Le code qui inscrit un modèle de contrôle personnalisé crée l’objet gestionnaire de modèles et, lors de l’inscription du modèle de contrôle, fournit UI Automation avec un pointeur vers l’interface IUIAutomationPatternHandler de l’objet.

Le diagramme suivant montre comment une demande de propriété cliente ou un appel de méthode circule à partir du wrapper client, à travers le UI Automation composants principaux vers le gestionnaire de modèles, puis vers l’interface du fournisseur.

diagramme montrant le flux du wrapper client vers le gestionnaire de modèles et le fournisseur

Les objets qui implémentent les interfaces du wrapper client et du gestionnaire de modèles doivent être à thread libre. En outre, le cœur UI Automation doit être en mesure d’appeler directement les objets sans code de marshaling intermédiaire.

Implémentation du wrapper client

Le wrapper client est un objet qui expose une interface IXxxPattern que le client utilise pour demander des propriétés et appeler des méthodes prises en charge par le modèle de contrôle personnalisé. L’interface se compose d’une paire de méthodes « getter » pour chaque propriété prise en charge (get_CurrentXxx et get_CachedXxx méthode) et d’une méthode « appelant » pour chaque méthode prise en charge. Lorsque l’objet est instancié, le constructeur d’objet reçoit un pointeur vers l’interface IUIAutomationPatternInstance, qui est implémentée par le cœur UI Automation. Les méthodes de l’interface IXxxPattern utilisent les méthodes IUIAutomationPatternInstance::GetProperty et CallMethod pour transférer les demandes de propriété et les appels de méthode au cœur UI Automation.

L’exemple suivant montre comment implémenter un objet wrapper client pour un modèle de contrôle personnalisé simple qui prend en charge une seule propriété. Pour obtenir un exemple plus complexe, consultez Exemple d’implémentation d’un modèle de contrôle personnalisé.

// Define the client interface.
interface __declspec(uuid("c78b266d-b2c0-4e9d-863b-e3f74a721d47"))
IMyCustomPattern : public IUnknown
{
    STDMETHOD (get_CurrentIsReadOnly)(BOOL * pIsReadOnly) = 0;
    STDMETHOD (get_CachedIsReadOnly)(BOOL * pIsReadOnly) = 0;
};

// Implement the client wrapper class.
class CMyValuePatternClientWrapper :
    public IMyCustomPattern
{
    IUIAutomationPatternInstance * _pInstance;
    
public:
    // Get IUIAutomationPatternInstance interface pointer from the
    // UI Automation core.
    CMyValuePatternClientWrapper(IUIAutomationPatternInstance * pInstance)
        : _pInstance(pInstance)
    {
        _pInstance->AddRef();
    }
    
    ~CMyValuePatternClientWrapper()
    {
        _pInstance->Release();
    }

    // Note: Put standard IUnknown implementation here.

    STDMETHODIMP get_CurrentIsReadOnly(BOOL * pIsReadOnly)
    {
        return _pInstance->GetProperty(0, FALSE, UIAutomationType_Bool, pIsReadOnly);
    }

    STDMETHODIMP get_CachedIsReadOnly(BOOL * pIsReadOnly)
    {
        return _pInstance->GetProperty(0, TRUE, UIAutomationType_Bool, pIsReadOnly);
    }
};

Implémentation du gestionnaire de modèles

Le gestionnaire de modèles est un objet qui implémente l’interface IUIAutomationPatternHandler . Cette interface a deux méthodes : IUIAutomationPatternHandler::CreateClientWrapper et Dispatch. La méthode CreateClientWrapper est appelée par le cœur UI Automation et reçoit un pointeur vers l’interface IUIAutomationPatternInstance. CreateClientWrapper répond en instanciant l’objet wrapper client et en passant le pointeur d’interface IUIAutomationPatternInstance au constructeur du wrapper client.

La méthode Dispatch est utilisée par le noyau UI Automation pour passer des demandes de propriété et des appels de méthode à l’interface du fournisseur pour le modèle de contrôle personnalisé. Les paramètres incluent un pointeur vers l’interface du fournisseur, l’index de base zéro de la propriété getter ou de la méthode appelée et un tableau de structures UIAutomationParameter qui contiennent les paramètres à passer au fournisseur. Le gestionnaire de modèles répond en vérifiant le paramètre d’index pour déterminer la méthode de fournisseur à appeler, puis en appelant cette interface de fournisseur, en passant les paramètres contenus dans les structures UIAutomationParameter .

L’objet de gestionnaire de modèle est instancié par le même code que celui qui inscrit le modèle de contrôle personnalisé, avant l’inscription du modèle de contrôle. Le code doit passer le pointeur d’interface IUIAutomationPatternHandler de l’objet de gestionnaire de modèles au UI Automation cœur au moment de l’inscription.

L’exemple suivant montre comment implémenter un objet de gestionnaire de modèle pour un modèle de contrôle personnalisé simple qui prend en charge une seule propriété. Pour obtenir un exemple plus complexe, consultez Exemple d’implémentation d’un modèle de contrôle personnalisé.

// Define the provider interface.
interface __declspec(uuid("9f5266dd-f0ab-4562-8175-c383abb2569e"))
IMyValueProvider : public IUnknown
{
    STDMETHOD (get_IsReadOnly)(BOOL * pIsReadOnly) = 0;
};            

// Index used by IUIAutomationPatternHandler::Dispatch.
const int MyValue_GetIsReadOnly = 0; 
            
// Define the pattern handler class.        
class CMyValuePatternHandler : public IUIAutomationPatternHandler
{
public:
    
    // Put standard IUnknown implementation here.

    STDMETHODIMP CreateClientWrapper(
            IUIAutomationPatternInstance * pPatternInstance, 
            IUnknown ** pClientWrapper)
    {
        *pClientWrapper = new CMyValuePatternClientWrapper(pPatternInstance);
        if (*pClientWrapper == NULL)
            return E_INVALIDARG;
        return S_OK;
    }
    
    STDMETHODIMP Dispatch (IUnknown * pTarget, UINT index, 
            const struct UIAutomationParameter *pParams, UINT cParams)
    {
        switch(index)
        {
        case MyValue_GetIsReadOnly:
            return ((IMyValueProvider*)pTarget)->get_IsReadOnly((BOOL*)pParams[0].pData);
        }
        return E_INVALIDARG;
    }
};

Inscription d’un modèle de contrôle personnalisé

Avant de pouvoir être utilisé, un modèle de contrôle personnalisé doit être inscrit par le fournisseur et le client. L’inscription fournit au UI Automation cœur des informations détaillées sur le modèle de contrôle, et fournit au fournisseur ou au client l’ID de modèle de contrôle et les ID pour les propriétés et les événements pris en charge par le modèle de contrôle. Côté fournisseur, le modèle de contrôle personnalisé doit être inscrit avant que le contrôle associé ne gère le message WM_GETOBJECT , ou en même temps.

Lors de l’inscription d’un modèle de contrôle personnalisé, le fournisseur ou le client fournit les informations suivantes :

  • GUID du modèle de contrôle personnalisé.
  • Chaîne non localisable contenant le nom du modèle de contrôle personnalisé.
  • GUID de l’interface du fournisseur qui prend en charge le modèle de contrôle personnalisé.
  • GUID de l’interface cliente qui prend en charge le modèle de contrôle personnalisé.
  • Tableau de structures UIAutomationPropertyInfo qui décrivent les propriétés prises en charge par le modèle de contrôle personnalisé. Pour chaque propriété, le GUID, le nom de la propriété et le type de données doivent être spécifiés.
  • Tableau de structures UIAutomationMethodInfo qui décrivent les méthodes prises en charge par le modèle de contrôle personnalisé. Pour chaque méthode, la structure inclut les informations suivantes : le nom de la méthode, un nombre de paramètres, une liste de types de données de paramètre et une liste des noms de paramètres.
  • Tableau de structures UIAutomationEventInfo qui décrivent les événements déclenchés par le modèle de contrôle personnalisé. Pour chaque événement, le GUID et le nom de l’événement doivent être spécifiés.
  • Adresse de l’interface IUIAutomationPatternHandler de l’objet de gestionnaire de modèles qui rend le modèle de contrôle personnalisé disponible pour les clients.

Pour inscrire le modèle de contrôle personnalisé, le code du fournisseur ou du client doit effectuer les étapes suivantes :

  1. Remplissez une structure UIAutomationPatternInfo avec les informations précédentes.
  2. Utilisez la fonction CoCreateInstance pour créer un instance de l’objet CUIAutomationRegistrar et récupérer un pointeur vers l’interface IUIAutomationRegistrar de l’objet.
  3. Appelez la méthode IUIAutomationRegistrar::RegisterPattern en passant l’adresse de la structure UIAutomationPatternInfo .

La méthode RegisterPattern retourne un ID de modèle de contrôle, ainsi qu’une liste d’ID de propriété et d’ID d’événement. Une application peut passer ces ID à n’importe quelle méthode UI Automation qui accepte un identificateur en tant que paramètre. Par exemple, vous pouvez passer un ID de modèle inscrit à la méthode IUIAutomationElement::GetCurrentPattern pour récupérer un pointeur vers l’interface du fournisseur pour le modèle de contrôle.

Il n’existe aucune méthode qui annule l’inscription d’un modèle de contrôle personnalisé. Au lieu de cela, il est implicitement désinscrit lorsque le dernier objet UI Automation est libéré.

Pour obtenir un exemple qui montre comment inscrire un modèle de contrôle personnalisé, consultez la section suivante.

Exemple d’implémentation d’un modèle de contrôle personnalisé

Cette section contient un exemple de code qui montre comment implémenter le wrapper client et les objets de gestionnaire de modèle pour un modèle de contrôle personnalisé. L’exemple implémente un modèle de contrôle personnalisé basé sur le modèle de contrôle Value .

// Step 1: Define the public provider and client interfaces using IDL. Interface 
// definitions are in C here to simplify the example.

// Define the provider interface.
interface __declspec(uuid("9f5266dd-f0ab-4562-8175-c383abb2569e"))
IMyValueProvider : public IUnknown
{
    STDMETHOD (get_Value)(BSTR * pValue) = 0;
    STDMETHOD (get_IsReadOnly)(BOOL * pIsReadOnly) = 0;
    STDMETHOD (SetValue)(LPCWSTR pNewValue) = 0;
    STDMETHOD (Reset)() = 0;
};

// Define the client interface.
interface __declspec(uuid("103b8323-b04a-4180-9140-8c1e437713a3"))
IUIAutomationMyValuePattern : public IUnknown
{
    STDMETHOD (get_CurrentValue)(BSTR * pValue) = 0;
    STDMETHOD (get_CachedValue)(BSTR * pValue) = 0;

    STDMETHOD (get_CurrentIsReadOnly)(BOOL * pIsReadOnly) = 0;
    STDMETHOD (get_CachedIsReadOnly)(BOOL * pIsReadOnly) = 0;

    STDMETHOD (SetValue)(LPCWSTR pNewValue) = 0;
    STDMETHOD (Reset)() = 0;
};

// Enumerate the properties and methods starting from 0, and placing the 
// properties first. 
enum
{
    MyValue_GetValue = 0,
    MyValue_GetIsReadOnly = 1,
    MyValue_SetValue = 2,
    MyValue_Reset = 3,
};

// Step 2: Implement the client wrapper class.
class CMyValuePatternClientWrapper :
    public IUIAutomationMyValuePattern
{
    IUIAutomationPatternInstance * _pInstance;

public:
    // Get IUIAutomationPatternInstance interface pointer.
    CMyValuePatternClientWrapper(IUIAutomationPatternInstance * pInstance)
    {
        _pInstance = pInstance;
        _pInstance->AddRef();
    }

    // Put standard IUnknown implementation here.

    STDMETHODIMP get_CurrentValue(BSTR * pValue)
    {
        return _pInstance->GetProperty(MyValue_GetValue, FALSE, 
                UIAutomationType_String, pValue);
    }

    STDMETHODIMP get_CachedValue(BSTR * pValue)
    {
        return _pInstance->GetProperty(MyValue_GetValue, TRUE, 
                UIAutomationType_String, pValue);
    }

    STDMETHODIMP get_CurrentIsReadOnly(BOOL * pIsReadOnly)
    {
        return _pInstance->GetProperty(MyValue_GetIsReadOnly, FALSE, 
                UIAutomationType_Bool, pIsReadOnly);
    }

    STDMETHODIMP get_CachedIsReadOnly(BOOL * pIsReadOnly)
    {
        return _pInstance->GetProperty(MyValue_GetIsReadOnly, TRUE, 
                UIAutomationType_Bool, pIsReadOnly);
    }

    STDMETHODIMP SetValue(LPCWSTR pValue)
    {
        UIAutomationParameter SetValueParams[] = 
                { UIAutomationType_String, &pValue };
        return _pInstance->CallMethod(MyValue_SetValue,  SetValueParams, 
                ARRAYSIZE(SetValueParams));
    }

    STDMETHODIMP Reset()
    {
        return _pInstance->CallMethod(MyValue_Reset, NULL, 0);
    }
};

// Step 3: Implement the pattern handler class.
class CMyValuePatternHandler : public IUIAutomationPatternHandler
{
public:

    // Put standard IUnknown implementation here.
    
    STDMETHODIMP CreateClientWrapper(
            IUIAutomationPatternInstance * pPatternInstance, 
            IUnknown ** pClientWrapper)
    {
        *pClientWrapper = new CMyValuePatternClientWrapper(pPatternInstance);
        if (*pClientWrapper == NULL)
            return E_INVALIDARG;
        return S_OK;
    }
    
    STDMETHODIMP Dispatch (IUnknown * pTarget, UINT index, 
            const struct UIAutomationParameter *pParams, 
            UINT cParams)
    {
        switch(index)
        {
        case MyValue_GetValue:
            return ((IMyValueProvider*)pTarget)->get_Value((BSTR*)pParams[0].pData);

        case MyValue_GetIsReadOnly:
            return ((IMyValueProvider*)pTarget)->get_IsReadOnly((BOOL*)pParams[0].pData);

        case MyValue_SetValue:
            return ((IMyValueProvider*)pTarget)->SetValue(*(LPCWSTR*)pParams[0].pData);

        case MyValue_Reset:
            return ((IMyValueProvider*)pTarget)->Reset();
        }
        return E_INVALIDARG;
    }
};

CMyValuePatternHandler g_MyValuePatternHandler;

// Step 4: Declare information about the properties and methods supported
// by the custom control pattern.

// Define GUIDs for the custom control pattern and each of its properties 
// and events.
static const GUID MyValue_Pattern_Guid = { 0xa49aa3c0, 0xe413, 0x4ecf, 
        { 0xa1, 0xc3, 0x37, 0x42, 0xa7, 0x86, 0x67, 0x3f } };
static const GUID MyValue_Value_Property_Guid = { 0xe58f3f67, 0x22c7, 0x44f0, 
        { 0x83, 0x55, 0xd8, 0x76, 0x14, 0xa1, 0x10, 0x81 } };
static const GUID MyValue_IsReadOnly_Property_Guid = { 0x480540f2, 0x9829, 0x4acd, 
        { 0xb8, 0xea, 0x6e, 0x2a, 0xdc, 0xe5, 0x3a, 0xfb } };
static const GUID MyValue_Reset_Event_Guid = { 0x5b80edd3, 0x67f, 0x4a70, 
        { 0xb0, 0x7, 0x4, 0x12, 0x85, 0x11, 0x1, 0x7a } };

// Declare information about the properties, in the same order as the
// previously defined "MyValue_" enumerated type.
UIAutomationPropertyInfo g_MyValueProperties[] = 
{
    // GUID, name, data type.
    { MyValue_Value_Property_Guid, L"MyValuePattern.Value", 
                                                    UIAutomationType_String },
    { MyValue_IsReadOnly_Property_Guid, L"MyValuePattern.IsReadOnly", 
                                                    UIAutomationType_Bool },
};

// Declare information about the event.
UIAutomationEventInfo g_MyValueEvents [] =
{
    { MyValue_Reset_Event_Guid,  L"MyValuePattern.Reset" },
};

// Declare the data type and name of the SetValue method parameter. 
UIAutomationType g_SetValueParamTypes[] = { UIAutomationType_String };
LPCWSTR g_SetValueParamNames[] = {L"pNewValue"};

// Declare information about the methods.
UIAutomationMethodInfo g_MyValueMethods[] =
{
    // Name, focus flag, count of in parameters, count of out parameters, types, parameter names.
    { L"MyValuePattern.SetValue", TRUE, 1, 0, g_SetValueParamTypes, g_SetValueParamNames },
    { L"MyValuePattern.Reset", TRUE, 0, 0, NULL, NULL },
};

// Declare the custom control pattern using the previously defined information.
UIAutomationPatternInfo g_ValuePatternInfo =
{
    MyValue_Pattern_Guid,
    L"MyValuePattern",
    __uuidof(IMyValueProvider),
    __uuidof(IUIAutomationMyValuePattern),
    ARRAYSIZE(g_MyValueProperties), g_MyValueProperties, // properties
    ARRAYSIZE(g_MyValueMethods), g_MyValueMethods,       // methods
    ARRAYSIZE(g_MyValueEvents), g_MyValueEvents,         // events 
    &g_MyValuePatternHandler
};

// Step 5: Register the custom control pattern and retrieve the control pattern and property 
// identifiers.

// Control pattern, property, and event IDs.
PATTERNID  g_MyValue_PatternID;
PROPERTYID g_MyValue_Value_PropertyID;
PROPERTYID g_MyValue_IsReadOnly_PropertyID;
EVENTID    g_MyValueReset_EventID;

// ID used by the client to determine whether the custom control pattern is available.
PROPERTYID g_IsMyValuePatternAvailable_PropertyID;

HRESULT RegisterPattern()
{
    // Create the registrar object and get the IUIAutomationRegistrar interface pointer. 
    IUIAutomationRegistrar * pUIARegistrar;
    CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER, 
            IID_IUIAutomationRegistrar, (void **)&pUIARegistrar);

    if (pUIARegistrar == NULL)
        return E_NOINTERFACE;

    PROPERTYID propIDs[2]; // Array for property IDs.

    // Register the control pattern.
    HRESULT hr = pUIARegistrar->RegisterPattern(
        &g_ValuePatternInfo,
        &g_MyValue_PatternID,
        &g_IsMyValuePatternAvailable_PropertyID,
        ARRAYSIZE(propIDs), 
        propIDs,
        1,
        &g_MyValueReset_EventID);
            
    if (hr == S_OK)
    {
        // Copy the property IDs.
        g_MyValue_Value_PropertyID = propIDs[0];
        g_MyValue_IsReadOnly_PropertyID = propIDs[1];
    }

    pUIARegistrar->Release();
    return hr;
}

Conceptuel

Conception de propriétés, d’événements et de modèles de contrôle personnalisés

Vue d'ensemble des propriétés UI Automation

Vue d'ensemble des événements UI Automation

Vue d'ensemble des modèles de contrôle UI Automation