다음을 통해 공유


사용자 지정 속성, 이벤트 및 컨트롤 패턴 등록

사용자 지정 속성, 이벤트 또는 컨트롤 패턴을 사용하려면 공급자와 클라이언트가 런타임에 속성, 이벤트 또는 컨트롤 패턴을 등록해야 합니다. 등록은 애플리케이션 프로세스 내에서 전역적으로 유효하며 프로세스가 닫히거나 프로세스 내에서 마지막 Microsoft UI 자동화 요소 개체(IUIAutomation 또는 IRawElementProviderSimple)가 해제될 때까지 유효합니다.

등록에는 사용자 지정 속성, 이벤트 또는 컨트롤 패턴에 대한 자세한 정보와 함께 GUID를 UI 자동화 전달해야 합니다. 동일한 정보를 사용하여 동일한 GUID를 두 번째로 등록하려고 하면 성공하지만 동일한 GUID를 두 번째로 등록하려고 시도하지만 다른 정보(예: 다른 형식의 사용자 지정 속성)가 있는 경우 실패합니다. 나중에 사용자 지정 사양이 수락되어 UI 자동화 코어에 통합되면 UI 자동화 사용자 지정 등록 정보의 유효성을 검사하고 "공식" 프레임워크 구현 대신 이미 등록된 코드를 사용하여 애플리케이션 호환성 문제를 최소화합니다. 이미 등록된 속성, 이벤트 또는 컨트롤 패턴을 제거할 수 없습니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

사용자 지정 속성 및 이벤트 등록

사용자 지정 속성 또는 이벤트를 등록하면 공급자와 클라이언트가 속성 또는 이벤트에 대한 ID를 가져올 수 있습니다. 그러면 ID를 매개 변수로 사용하는 다양한 API 메서드에 전달할 수 있습니다.

속성 또는 이벤트를 등록하려면 다음을 수행합니다.

  1. 사용자 지정 속성 또는 이벤트에 대한 GUID를 정의합니다.
  2. UIAutomationPropertyInfo 또는 UIAutomationEventInfo 구조체를 GUID 및 사용자 지정 속성 또는 이벤트의 이름을 포함하는 로컬화할 수 없는 문자열을 포함하여 속성 또는 이벤트에 대한 정보로 채웁니다. 사용자 지정 속성에는 속성의 데이터 형식을 지정해야 합니다(예: 속성에 정수 또는 문자열이 있는지 여부). 데이터 형식은 UIAutomationType 열거형에 지정된 다음 형식 중 하나여야 합니다. 사용자 지정 속성에 대해 지원되는 다른 데이터 형식은 없습니다.
    • UIAutomationType_Bool
    • UIAutomationType_Double
    • UIAutomationType_Element
    • UIAutomationType_Int
    • UIAutomationType_Point
    • UIAutomationType_String
  3. CoCreateInstance 함수를 사용하여 CUIAutomationRegistrar 개체의 instance 만들고 개체의 IUIAutomationRegistrar 인터페이스에 대한 포인터를 검색합니다.
  4. IUIAutomationRegistrar::RegisterProperty 또는 RegisterEvent 메서드를 호출하고 UIAutomationPropertyInfo 구조체 또는 UIAutomationEventInfo 구조체의 주소를 전달합니다.

IUIAutomationRegistrar::RegisterProperty 또는 RegisterEvent 메서드는 애플리케이션이 이러한 식별자를 매개 변수로 사용하는 모든 UI 자동화 메서드에 전달할 수 있는 속성 ID 또는 이벤트 ID를 반환합니다. 예를 들어 등록된 속성 ID를 IUIAutomationElement::GetCurrentPropertyValue 메서드 또는 IUIAutomation::CreatePropertyCondition 메서드에 전달할 수 있습니다.

다음 예제에서는 사용자 지정 속성을 등록하는 방법을 보여 줍니다.

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

IUIAutomationRegistrar::RegisterPropertyRegisterEvent 메서드에서 검색한 속성 및 이벤트 식별자는 해당 메서드를 검색하는 애플리케이션의 컨텍스트에서만 유효하며 애플리케이션 수명 동안만 유효합니다. 등록 메서드는 동일한 애플리케이션의 다른 런타임 인스턴스를 통해 호출되는 경우 동일한 GUID에 대해 서로 다른 정수 값을 반환할 수 있습니다.

사용자 지정 속성 또는 이벤트를 등록 취소하는 메서드는 없습니다. 대신 마지막 UI 자동화 개체가 해제될 때 암시적으로 등록 취소됩니다.

중요

코드가 MSAA(Microsoft Active Accessibility) 클라이언트인 경우 사용자 지정 속성의 값을 변경할 때 NotifyWinEvent 함수를 호출해야 합니다.

 

사용자 지정 컨트롤 패턴 구현

사용자 지정 컨트롤 패턴은 UI 자동화 API에 포함되지 않지만 런타임에 타사에서 제공합니다. 클라이언트 및 공급자 애플리케이션 개발자는 함께 작동하여 컨트롤 패턴이 지원할 메서드, 속성 및 이벤트를 포함하여 사용자 지정 컨트롤 패턴을 정의해야 합니다. 컨트롤 패턴을 정의한 후 클라이언트와 공급자는 런타임에 컨트롤 패턴을 등록하는 코드와 함께 지원되는 COM(구성 요소 개체 모델) 개체를 구현해야 합니다. 사용자 지정 컨트롤 패턴을 사용하려면 클라이언트 래퍼와 패턴 처리기라는 두 개의 COM 개체를 구현해야 합니다.

참고

다음 topics 예제에서는 기존 컨트롤 패턴의 기능을 복제하는 사용자 지정 컨트롤 패턴을 구현하는 방법을 보여 줍니다. 이러한 예제는 교육용으로만 사용됩니다. 실제 사용자 지정 컨트롤 패턴은 표준 UI 자동화 컨트롤 패턴에서 사용할 수 없는 기능을 제공해야 합니다.

 

클라이언트 래퍼 및 패턴 처리기

클라이언트 래퍼는 클라이언트에서 속성을 검색하고 사용자 지정 컨트롤 패턴에 의해 노출되는 메서드를 호출하는 데 사용되는 API를 구현합니다. API는 모든 속성 요청 및 메서드 호출을 UI 자동화 코어로 전달한 다음, 공급자에 대한 요청 및 호출을 마샬링하는 COM 인터페이스로 구현됩니다.

사용자 지정 컨트롤 패턴을 등록하는 코드는 UI 자동화 클라이언트 래퍼 개체의 인스턴스를 만드는 데 사용할 수 있는 클래스 팩터리를 제공해야 합니다. 사용자 지정 컨트롤 패턴이 성공적으로 등록되면 UI 자동화 클라이언트가 속성 요청 및 메서드 호출을 UI 자동화 코어로 전달하는 데 사용하는 IUIAutomationPatternInstance 인터페이스 포인터를 반환합니다.

공급자 쪽에서 UI 자동화 코어는 클라이언트에서 속성 요청 및 메서드 호출을 가져와서 패턴 처리기 개체에 전달합니다. 그런 다음 패턴 처리기는 사용자 지정 컨트롤 패턴에 대한 공급자 인터페이스에서 적절한 메서드를 호출합니다.

사용자 지정 컨트롤 패턴을 등록하는 코드는 패턴 처리기 개체를 만들고 컨트롤 패턴을 등록할 때 개체의 IUIAutomationPatternHandler 인터페이스에 대한 포인터를 UI 자동화 제공합니다.

다음 다이어그램에서는 클라이언트 속성 요청 또는 메서드 호출이 클라이언트 래퍼에서 UI 자동화 핵심 구성 요소를 통해 패턴 처리기로, 그리고 공급자 인터페이스로 이동하는 방법을 보여 줍니다.

클라이언트 래퍼에서 패턴 처리기 및 공급자로의 흐름을 보여 주는 다이어그램

클라이언트 래퍼 및 패턴 처리기 인터페이스를 구현하는 개체는 자유 스레드여야 합니다. 또한 UI 자동화 코어는 중간 마샬링 코드 없이 개체를 직접 호출할 수 있어야 합니다.

클라이언트 래퍼 구현

클라이언트 래퍼는 클라이언트가 속성을 요청하고 사용자 지정 컨트롤 패턴에서 지원하는 메서드를 호출하는 데 사용하는 IXxxPattern 인터페이스를 노출하는 개체입니다. 인터페이스는 지원되는 각 속성(get_CurrentXxx 및 get_CachedXxx 메서드)에 대한 "getter" 메서드 쌍과 지원되는 각 메서드에 대한 "호출자" 메서드로 구성됩니다. 개체가 인스턴스화되면 개체 생성자는 UI 자동화 코어에서 구현되는 IUIAutomationPatternInstance 인터페이스에 대한 포인터를 받습니다. IXxxPattern 인터페이스의 메서드는 IUIAutomationPatternInstance::GetPropertyCallMethod 메서드를 사용하여 속성 요청 및 메서드 호출을 UI 자동화 코어로 전달합니다.

다음 예제에서는 단일 속성을 지원 하는 간단한 사용자 지정 컨트롤 패턴에 대 한 클라이언트 래퍼 개체를 구현 하는 방법을 보여 줍니다. 더 복잡한 예제는 사용자 지정 컨트롤 패턴의 구현 예제를 참조하세요.

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

패턴 처리기 구현

패턴 처리기는 IUIAutomationPatternHandler 인터페이스를 구현하는 개체입니다. 이 인터페이스에는 IUIAutomationPatternHandler::CreateClientWrapperDispatch라는 두 가지 메서드가 있습니다. CreateClientWrapper 메서드는 UI 자동화 코어에서 호출되고 IUIAutomationPatternInstance 인터페이스에 대한 포인터를 받습니다. CreateClientWrapper 는 클라이언트 래퍼 개체를 인스턴스화하고 IUIAutomationPatternInstance 인터페이스 포인터를 클라이언트 래퍼 생성자에 전달하여 응답합니다.

Dispatch 메서드는 UI 자동화 코어에서 사용자 지정 컨트롤 패턴에 대한 공급자 인터페이스에 속성 요청 및 메서드 호출을 전달하는 데 사용됩니다. 매개 변수에는 공급자 인터페이스에 대한 포인터, 호출되는 속성 getter 또는 메서드의 0부터 시작하는 인덱스 및 공급자에게 전달할 매개 변수가 포함된 UIAutomationParameter 구조의 배열이 포함됩니다. 패턴 처리기는 인덱스 매개 변수를 확인하여 호출할 공급자 메서드를 확인한 다음 해당 공급자 인터페이스를 호출하여 UIAutomationParameter 구조에 포함된 매개 변수를 전달합니다.

패턴 처리기 개체는 컨트롤 패턴이 등록되기 전에 사용자 지정 컨트롤 패턴을 등록하는 동일한 코드에 의해 인스턴스화됩니다. 코드는 등록 시 패턴 처리기 개체의 IUIAutomationPatternHandler 인터페이스 포인터를 UI 자동화 코어에 전달해야 합니다.

다음 예제에서는 단일 속성을 지원하는 간단한 사용자 지정 컨트롤 패턴에 대한 패턴 처리기 개체를 구현하는 방법을 보여 줍니다. 보다 복잡한 예제는 사용자 지정 컨트롤 패턴의 구현 예제를 참조하세요.

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

사용자 지정 컨트롤 패턴 등록

사용하려면 먼저 공급자와 클라이언트 모두에서 사용자 지정 컨트롤 패턴을 등록해야 합니다. 등록은 UI 자동화 코어에 컨트롤 패턴에 대한 자세한 정보를 제공하고 공급자 또는 클라이언트에 컨트롤 패턴 ID 및 컨트롤 패턴에서 지원하는 속성 및 이벤트에 대한 ID를 제공합니다. 공급자 쪽에서는 연결된 컨트롤이 WM_GETOBJECT 메시지를 처리하기 전에 또는 동시에 사용자 지정 컨트롤 패턴을 등록해야 합니다.

사용자 지정 컨트롤 패턴을 등록할 때 공급자 또는 클라이언트는 다음 정보를 제공합니다.

  • 사용자 지정 컨트롤 패턴의 GUID입니다.
  • 사용자 지정 컨트롤 패턴의 이름을 포함하는 로컬링할 수 없는 문자열입니다.
  • 사용자 지정 컨트롤 패턴을 지원하는 공급자 인터페이스의 GUID입니다.
  • 사용자 지정 컨트롤 패턴을 지원하는 클라이언트 인터페이스의 GUID입니다.
  • 사용자 지정 컨트롤 패턴에서 지원하는 속성을 설명하는 UIAutomationPropertyInfo 구조체의 배열입니다. 각 속성에 대해 GUID, 속성 이름 및 데이터 형식을 지정해야 합니다.
  • 사용자 지정 컨트롤 패턴에서 지원하는 메서드를 설명하는 UIAutomationMethodInfo 구조체의 배열입니다. 각 메서드에 대해 구조체에는 메서드 이름, 매개 변수 개수, 매개 변수 데이터 형식 목록 및 매개 변수 이름 목록이 포함됩니다.
  • 사용자 지정 컨트롤 패턴에 의해 발생한 이벤트를 설명하는 UIAutomationEventInfo 구조체의 배열입니다. 각 이벤트에 대해 GUID 및 이벤트 이름을 지정해야 합니다.
  • 클라이언트에서 사용자 지정 컨트롤 패턴을 사용할 수 있도록 하는 패턴 처리기 개체의 IUIAutomationPatternHandler 인터페이스의 주소입니다.

사용자 지정 컨트롤 패턴을 등록하려면 공급자 또는 클라이언트 코드가 다음 단계를 수행해야 합니다.

  1. 이전 정보로 UIAutomationPatternInfo 구조를 채웁니다.
  2. CoCreateInstance 함수를 사용하여 CUIAutomationRegistrar 개체의 instance 만들고 개체의 IUIAutomationRegistrar 인터페이스에 대한 포인터를 검색합니다.
  3. IUIAutomationRegistrar::RegisterPattern 메서드를 호출하여 UIAutomationPatternInfo 구조체의 주소를 전달합니다.

RegisterPattern 메서드는 속성 ID 및 이벤트 ID 목록과 함께 컨트롤 패턴 ID를 반환합니다. 애플리케이션은 이러한 식별자를 매개 변수로 사용하는 모든 UI 자동화 메서드에 이러한 ID를 전달할 수 있습니다. 예를 들어 등록된 패턴 ID를 IUIAutomationElement::GetCurrentPattern 메서드에 전달하여 컨트롤 패턴에 대한 공급자 인터페이스에 대한 포인터를 검색할 수 있습니다.

사용자 지정 컨트롤 패턴의 등록을 취소하는 메서드는 없습니다. 대신 마지막 UI 자동화 개체가 해제될 때 암시적으로 등록 취소됩니다.

사용자 지정 컨트롤 패턴을 등록하는 방법을 보여 주는 예제는 다음 섹션을 참조하세요.

사용자 지정 컨트롤 패턴의 예제 구현

이 섹션에는 사용자 지정 컨트롤 패턴에 대한 클라이언트 래퍼 및 패턴 처리기 개체를 구현하는 방법을 보여 주는 예제 코드가 포함되어 있습니다. 이 예제에서는 컨트롤 패턴을 기반으로 하는 사용자 지정 컨트롤 패턴을 구현합니다.

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

개념

사용자 지정 속성, 이벤트 및 컨트롤 패턴 디자인

UI 자동화 속성 개요

UI 자동화 이벤트 개요

UI 자동화 컨트롤 패턴 개요