Registrieren von benutzerdefinierten Eigenschaften, Ereignissen und Steuerelementmustern

Bevor ein benutzerdefiniertes Eigenschaften-, Ereignis- oder Steuerelementmuster verwendet werden kann, müssen sowohl der Anbieter als auch der Client die Eigenschaft, das Ereignis oder das Steuerelementmuster zur Laufzeit registrieren. Die Registrierung ist global innerhalb eines Anwendungsprozesses wirksam und bleibt wirksam, bis der Prozess geschlossen oder das letzte Microsoft Benutzeroberflächenautomatisierung-Elementobjekt (IUIAutomation oder IRawElementProviderSimple) innerhalb des Prozesses freigegeben wird.

Registation umfasst die Übergabe einer GUID an Benutzeroberflächenautomatisierung sowie detaillierte Informationen zum benutzerdefinierten Eigenschaften-, Ereignis- oder Steuerelementmuster. Der Versuch, dieselbe GUID ein zweites Mal mit denselben Informationen zu registrieren, ist erfolgreich, aber der Versuch, dieselbe GUID ein zweites Mal mit anderen Informationen zu registrieren (z. B. eine benutzerdefinierte Eigenschaft eines anderen Typs), schlägt fehl. Wenn die benutzerdefinierte Spezifikation in Zukunft akzeptiert und in den Benutzeroberflächenautomatisierung Kern integriert wird, überprüfen Benutzeroberflächenautomatisierung die benutzerdefinierten Registrierungsinformationen und verwenden den bereits registrierten Code anstelle der "offiziellen" Frameworkimplementierung, wodurch Anwendungskompatibilitätsprobleme minimiert werden. Sie können bereits registrierte Eigenschaften, Ereignisse oder Steuerelementmuster nicht entfernen.

Dieses Thema enthält folgende Abschnitte:

Registrieren benutzerdefinierter Eigenschaften und Ereignisse

Durch das Registrieren einer benutzerdefinierten Eigenschaft oder eines benutzerdefinierten Ereignisses können Anbieter und Client eine ID für die Eigenschaft oder das Ereignis abrufen, die dann an verschiedene API-Methoden übergeben werden können, die IDs als Parameter verwenden.

So registrieren Sie eine Eigenschaft oder ein Ereignis:

  1. Definieren Sie eine GUID für die benutzerdefinierte Eigenschaft oder das Benutzerdefinierte Ereignis.
  2. Füllen Sie eine UIAutomationPropertyInfo - oder UIAutomationEventInfo-Struktur mit Informationen über die Eigenschaft oder das Ereignis, einschließlich der GUID und einer nicht lokalisierbaren Zeichenfolge, die den Namen der benutzerdefinierten Eigenschaft oder des ereignisses enthält. Benutzerdefinierte Eigenschaften erfordern auch, dass der Datentyp der Eigenschaft angegeben wird, z. B. ob die Eigenschaft eine ganze Zahl oder eine Zeichenfolge enthält. Der Datentyp muss einer der folgenden Typen sein, die von der UIAutomationType-Aufzählung angegeben werden. Für benutzerdefinierte Eigenschaften werden keine anderen Datentypen unterstützt.
    • UIAutomationType_Bool
    • UIAutomationType_Double
    • UIAutomationType_Element
    • UIAutomationType_Int
    • UIAutomationType_Point
    • UIAutomationType_String
  3. Verwenden Sie die CoCreateInstance-Funktion, um eine instance des CUIAutomationRegistrar-Objekts zu erstellen und einen Zeiger auf die IUIAutomationRegistrar-Schnittstelle des Objekts abzurufen.
  4. Rufen Sie die IUIAutomationRegistrar::RegisterProperty - oder RegisterEvent-Methode auf, und übergeben Sie die Adresse der UIAutomationPropertyInfo-Struktur oder der UIAutomationEventInfo-Struktur .

Die IUIAutomationRegistrar::RegisterProperty- oder RegisterEvent-Methode gibt eine Eigenschafts-ID oder Ereignis-ID zurück, die eine Anwendung an jede Benutzeroberflächenautomatisierung-Methode übergeben kann, die einen solchen Bezeichner als Parameter verwendet. Beispielsweise können Sie eine registrierte Eigenschafts-ID an die IUIAutomationElement::GetCurrentPropertyValue-Methode oder an die IUIAutomation::CreatePropertyCondition-Methode übergeben.

Im folgenden Beispiel wird veranschaulicht, wie eine benutzerdefinierte Eigenschaft registriert wird.

// 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;
}

Die von den Methoden IUIAutomationRegistrar::RegisterProperty und RegisterEvent abgerufenen Eigenschaften- und Ereignisbezeichner sind nur im Kontext der Anwendung gültig, die sie abruft, und nur für die Dauer der Anwendungslebensdauer. Die Registrierungsmethoden können unterschiedliche ganzzahlige Werte für dieselbe GUID zurückgeben, wenn sie über verschiedene Laufzeitinstanzen derselben Anwendung aufgerufen wird.

Es gibt keine Methode, mit der die Registrierung einer benutzerdefinierten Eigenschaft oder eines Ereignisses aufgehoben wird. Stattdessen werden sie implizit nicht registriert, wenn das letzte Benutzeroberflächenautomatisierung -Objekt freigegeben wird.

Wichtig

Wenn Es sich bei Ihrem Code um einen MsAA-Client (Microsoft Active Accessibility) handelt, müssen Sie die NotifyWinEvent-Funktion aufrufen, wenn Sie den Wert einer benutzerdefinierten Eigenschaft ändern.

 

Implementieren benutzerdefinierter Steuerelementmuster

Ein benutzerdefiniertes Steuerelementmuster ist in der Benutzeroberflächenautomatisierung-API nicht enthalten, wird aber zur Laufzeit von einem Drittanbieter bereitgestellt. Entwickler von Client- und Anbieteranwendungen müssen zusammenarbeiten, um ein benutzerdefiniertes Steuerelementmuster zu definieren, einschließlich der Methoden, Eigenschaften und Ereignisse, die das Steuerelementmuster unterstützt. Nach dem Definieren des Steuerelementmusters müssen sowohl der Client als auch der Anbieter unterstützende COM-Objekte (Component Object Model) zusammen mit Code implementieren, um das Steuerelementmuster zur Laufzeit zu registrieren. Ein benutzerdefiniertes Steuerelementmuster erfordert die Implementierung von zwei COM-Objekten: einem Clientwrapper und einem Musterhandler.

Hinweis

Die Beispiele in den folgenden Themen veranschaulichen die Implementierung eines benutzerdefinierten Steuerelementmusters, das die Funktionalität des vorhandenen Value-Steuerelementmusters dupliziert. Diese Beispiele dienen nur zu Anweisungszwecken. Ein tatsächliches benutzerdefiniertes Steuerelementmuster sollte Funktionen bereitstellen, die nicht in den Standard-Benutzeroberflächenautomatisierung-Steuerelementmustern verfügbar sind.

 

Der Clientwrapper und der Musterhandler

Der Clientwrapper implementiert die API, die vom Client verwendet wird, um Eigenschaften abzurufen und Methoden aufzurufen, die vom benutzerdefinierten Steuerelementmuster verfügbar gemacht werden. Die API wird als COM-Schnittstelle implementiert, die alle Eigenschaftenanforderungen und Methodenaufrufe an den Benutzeroberflächenautomatisierung Kern übergibt, der dann die Anforderungen und Aufrufe an den Anbieter marshallt.

Der Code, der ein benutzerdefiniertes Steuerelementmuster registriert, muss eine Klassenfactory bereitstellen, die Benutzeroberflächenautomatisierung verwenden kann, um Instanzen des Clientwrapperobjekts zu erstellen. Wenn ein benutzerdefiniertes Steuerelementmuster erfolgreich registriert wurde, gibt Benutzeroberflächenautomatisierung einen IUIAutomationPatternInstance-Schnittstellenzeiger zurück, der vom Client verwendet wird, um Eigenschaftenanforderungen und Methodenaufrufe an den Benutzeroberflächenautomatisierung Core weiterzuleiten.

Auf Der Anbieterseite übernimmt der Benutzeroberflächenautomatisierung Core die Eigenschaftenanforderungen und Methodenaufrufe vom Client und übergibt sie an das Musterhandlerobjekt. Der Musterhandler ruft dann die entsprechenden Methoden für die Anbieterschnittstelle für das benutzerdefinierte Steuerelementmuster auf.

Der Code, der ein benutzerdefiniertes Steuerelementmuster registriert, erstellt das Musterhandlerobjekt und stellt beim Registrieren des Steuerelementmusters Benutzeroberflächenautomatisierung mit einem Zeiger auf die IUIAutomationPatternHandler-Schnittstelle des Objekts bereit.

Das folgende Diagramm zeigt, wie eine Clienteigenschaftsanforderung oder ein Methodenaufruf vom Clientwrapper über die Benutzeroberflächenautomatisierung Kernkomponenten zum Musterhandler und dann zur Anbieterschnittstelle fließt.

Diagramm: Fluss vom Clientwrapper zum Musterhandler und Anbieter

Die Objekte, die die Clientwrapper- und Musterhandlerschnittstellen implementieren, müssen Freithreads sein. Außerdem muss der Benutzeroberflächenautomatisierung Kern in der Lage sein, die Objekte direkt ohne zwischengeschalteten Marshallingcode aufzurufen.

Implementieren des Clientwrappers

Der Clientwrapper ist ein Objekt, das eine IXxxPattern-Schnittstelle verfügbar macht, die der Client zum Anfordern von Eigenschaften und Aufrufmethoden verwendet, die vom benutzerdefinierten Steuerelementmuster unterstützt werden. Die -Schnittstelle besteht aus einem Paar von "getter"-Methoden für jede unterstützte Eigenschaft (get_CurrentXxx und get_CachedXxx-Methode) und einer Aufrufermethode für jede unterstützte Methode. Wenn das Objekt instanziiert wird, empfängt der Objektkonstruktor einen Zeiger auf die IUIAutomationPatternInstance-Schnittstelle, die vom Benutzeroberflächenautomatisierung Kern implementiert wird. Die Methoden der IXxxPattern-Schnittstelle verwenden die Methoden IUIAutomationPatternInstance::GetProperty und CallMethod, um Eigenschaftenanforderungen und Methodenaufrufe an den Benutzeroberflächenautomatisierung Core weiterzuleiten.

Das folgende Beispiel zeigt, wie ein Clientwrapperobjekt für ein einfaches benutzerdefiniertes Steuerelementmuster implementiert wird, das eine einzelne Eigenschaft unterstützt. Ein komplexeres Beispiel finden Sie unter Beispielimplementierung eines benutzerdefinierten Steuerelementmusters.

// 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);
    }
};

Implementieren des Musterhandlers

Der Musterhandler ist ein Objekt, das die IUIAutomationPatternHandler-Schnittstelle implementiert. Diese Schnittstelle verfügt über zwei Methoden: IUIAutomationPatternHandler::CreateClientWrapper und Dispatch. Die CreateClientWrapper-Methode wird vom Benutzeroberflächenautomatisierung Kerns aufgerufen und empfängt einen Zeiger auf die IUIAutomationPatternInstance-Schnittstelle. CreateClientWrapper antwortet, indem das Clientwrapperobjekt instanziiert und der IUIAutomationPatternInstance-Schnittstellenzeiger an den Clientwrapperkonstruktor übergeben wird.

Die Dispatch-Methode wird vom Benutzeroberflächenautomatisierung Kern verwendet, um Eigenschaftenanforderungen und Methodenaufrufe für das benutzerdefinierte Steuerelementmuster an die Anbieterschnittstelle zu übergeben. Parameter enthalten einen Zeiger auf die Anbieterschnittstelle, den nullbasierten Index des aufgerufenen Eigenschafts-Getters oder der aufgerufenen Methode und ein Array von UIAutomationParameter-Strukturen , die die Parameter enthalten, die an den Anbieter übergeben werden sollen. Der Musterhandler antwortet, indem er den Indexparameter überprüft, um zu bestimmen, welche Anbietermethode aufgerufen werden soll, und ruft dann diese Anbieterschnittstelle auf, wobei die in den UIAutomationParameter-Strukturen enthaltenen Parameter übergeben werden.

Das Musterhandlerobjekt wird durch denselben Code instanziiert, der das benutzerdefinierte Steuerelementmuster registriert, bevor das Steuerelementmuster registriert wird. Der Code muss den IUIAutomationPatternHandler-Schnittstellenzeiger des Musterhandlerobjekts zum Zeitpunkt der Registrierung an den Benutzeroberflächenautomatisierung Kern übergeben.

Das folgende Beispiel zeigt, wie ein Musterhandlerobjekt für ein einfaches benutzerdefiniertes Steuerelementmuster implementiert wird, das eine einzelne Eigenschaft unterstützt. Ein komplexeres Beispiel finden Sie unter Beispielimplementierung eines benutzerdefinierten Steuerelementmusters.

// 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;
    }
};

Registrieren eines benutzerdefinierten Steuerelementmusters

Bevor es verwendet werden kann, muss ein benutzerdefiniertes Steuerelementmuster sowohl vom Anbieter als auch vom Client registriert werden. Die Registrierung stellt dem Benutzeroberflächenautomatisierung Kern detaillierte Informationen zum Steuerelementmuster bereit und stellt dem Anbieter oder Client die Steuerelementmuster-ID und IDs für die Eigenschaften und Ereignisse bereit, die vom Steuerelementmuster unterstützt werden. Auf Der Anbieterseite muss das benutzerdefinierte Steuerelementmuster registriert werden, bevor das zugeordnete Steuerelement die WM_GETOBJECT Nachricht verarbeitet, oder gleichzeitig.

Beim Registrieren eines benutzerdefinierten Steuerelementmusters stellt der Anbieter oder Client die folgenden Informationen bereit:

  • Die GUID des benutzerdefinierten Steuerelementmusters.
  • Eine nicht lokalisierbare Zeichenfolge, die den Namen des benutzerdefinierten Steuerelementmusters enthält.
  • Die GUID der Anbieterschnittstelle, die das benutzerdefinierte Steuerelementmuster unterstützt.
  • Die GUID der Clientschnittstelle, die das benutzerdefinierte Steuerelementmuster unterstützt.
  • Ein Array von UIAutomationPropertyInfo-Strukturen , die die vom benutzerdefinierten Steuerelementmuster unterstützten Eigenschaften beschreiben. Für jede Eigenschaft müssen die GUID, der Eigenschaftenname und der Datentyp angegeben werden.
  • Ein Array von UIAutomationMethodInfo-Strukturen , die die methoden beschreiben, die vom benutzerdefinierten Steuerelementmuster unterstützt werden. Für jede Methode enthält die -Struktur die folgenden Informationen: den Methodennamen, eine Anzahl von Parametern, eine Liste der Parameterdatentypen und eine Liste der Parameternamen.
  • Ein Array von UIAutomationEventInfo-Strukturen , die die vom benutzerdefinierten Steuerelementmuster ausgelösten Ereignisse beschreiben. Für jedes Ereignis müssen die GUID und der Ereignisname angegeben werden.
  • Die Adresse der IUIAutomationPatternHandler-Schnittstelle des Musterhandlerobjekts, das das benutzerdefinierte Steuerelementmuster für Clients verfügbar macht.

Um das benutzerdefinierte Steuerelementmuster zu registrieren, muss der Anbieter oder Clientcode die folgenden Schritte ausführen:

  1. Füllen Sie eine UIAutomationPatternInfo-Struktur mit den vorherigen Informationen.
  2. Verwenden Sie die CoCreateInstance-Funktion, um eine instance des CUIAutomationRegistrar-Objekts zu erstellen und einen Zeiger auf die IUIAutomationRegistrar-Schnittstelle des Objekts abzurufen.
  3. Rufen Sie die IUIAutomationRegistrar::RegisterPattern-Methode auf, und übergeben Sie dabei die Adresse der UIAutomationPatternInfo-Struktur .

Die RegisterPattern-Methode gibt eine Steuerelementmuster-ID zusammen mit einer Liste von Eigenschaften-IDs und Ereignis-IDs zurück. Eine Anwendung kann diese IDs an jede Benutzeroberflächenautomatisierung Methode übergeben, die einen solchen Bezeichner als Parameter verwendet. Sie können beispielsweise eine registrierte Muster-ID an die IUIAutomationElement::GetCurrentPattern-Methode übergeben, um einen Zeiger auf die Anbieterschnittstelle für das Steuerelementmuster abzurufen.

Es gibt keine Methode, mit der die Registrierung eines benutzerdefinierten Steuerelementmusters aufgehoben wird. Stattdessen wird die Registrierung implizit aufgehoben, wenn das letzte Benutzeroberflächenautomatisierung -Objekt freigegeben wird.

Ein Beispiel zum Registrieren eines benutzerdefinierten Steuerelementmusters finden Sie im folgenden Abschnitt.

Beispielimplementierung eines benutzerdefinierten Steuerelementmusters

Dieser Abschnitt enthält Beispielcode, der veranschaulicht, wie der Clientwrapper und die Musterhandlerobjekte für ein benutzerdefiniertes Steuerelementmuster implementiert werden. Im Beispiel wird ein benutzerdefiniertes Steuerelementmuster implementiert, das auf dem Value-Steuerelementmuster basiert.

// 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;
}

Konzept

Entwerfen benutzerdefinierter Eigenschaften, Ereignisse und Steuerelementmuster

Übersicht über die Benutzeroberflächenautomatisierungs-Eigenschaften

Übersicht über Benutzeroberflächenautomatisierungs-Ereignisse

Übersicht über Steuerelementmuster für Benutzeroberflächenautomatisierung