다음을 통해 공유


UI 자동화 사용하여 창 없는 ActiveX 컨트롤에 액세스할 수 있도록 하는 방법

Microsoft UI 자동화 API를 사용하여 창이 없는 Microsoft ActiveX 컨트롤이 AT(보조 기술) 클라이언트 애플리케이션에 액세스할 수 있도록 하는 방법을 설명합니다.

알아야 하는 작업

기술

필수 구성 요소

  • C/C++
  • Microsoft Win32 및 COM(구성 요소 개체 모델) 프로그래밍
  • 창 없는 ActiveX 컨트롤
  • UI 자동화 공급자

지침

1단계: UI 자동화 공급자 인터페이스를 구현합니다.

애플리케이션에 액세스할 수 있도록 하려면 IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRootIRawElementProviderAdviseEvents를 포함하여 창이 없는 ActiveX 컨트롤에 대한 UI 자동화 공급자 인터페이스를 구현해야 합니다. 다음 단계에 설명된 경우를 제외하고 창 기반 컨트롤과 마찬가지로 이러한 인터페이스를 구현해야 합니다. UIA 공급자 인터페이스 구현에 대한 자세한 내용은 UI 자동화 공급자 프로그래머 가이드를 참조하세요.

2단계: IServiceProvider 인터페이스를 구현합니다.

클라이언트에 창 없는 컨트롤에 대한 접근성 정보가 필요한 경우 컨트롤 컨테이너는 컨트롤의 IServiceProvider::QueryService 메서드를 호출하여 컨트롤에 대한 IRawElementProviderSimple 인터페이스 포인터를 검색합니다.

다음 예제에서는 QueryService 메서드를 구현하는 방법을 보여줍니다.

STDMETHODIMP CMyAccessibleUIAControl::QueryService(REFGUID guidService,
        REFIID riid, void **ppvObject)
{  
    if (ppvObject == NULL)
    {
        return E_INVALIDARG;
    }

    *ppvObject = NULL;  
    HRESULT hr = E_FAIL; 
 
    if (guidService == __uuidof(IRawElementProviderSimple))
    {  
        hr = QueryInterface(riid, ppvObject);  
    }  
    return hr;  
}

3단계: IRawElementProviderFragment::Navigate 메서드를 구현합니다.

창 없는 컨트롤의 IRawElementProviderFragment::Navigate 메서드를 호출하여 창 없는 컨트롤의 루트 공급자의 부모 또는 형제로 이동하면 Navigate 메서드가 컨트롤 컨테이너의 IRawElementProviderWindowlessSite::GetAdjacentFragment 메서드에 위임되어야 합니다.

다음 예제에서는 Navigate 메서드를 구현하는 방법을 보여줍니다.

STDMETHODIMP CMyAccessibleUIAControl::Navigate(NavigateDirection direction,
     IRawElementProviderFragment **ppRetVal) 
{   
    if (ppRetVal == NULL)
    {
        return E_INVALIDARG;
    }

    *ppRetVal = NULL;  
    HRESULT hr = E_FAIL;
    IRawElementProviderWindowlessSite *pWindowlessSite = NULL;  
    
    if (direction == NavigateDirection_Parent)  
    {  
        // Query the control container's windowless site 
        // for the parent.
         if (SUCCEEDED(m_pClientSite->QueryInterface(
                IID_PPV_ARGS(&pWindowlessSite))))  
        {  
            hr =  pWindowlessSite->GetAdjacentFragment(direction, ppRetVal);  
        }  
    }  

    else if (direction == NavigateDirection_FirstChild)  
    {  
        // GetFragmentForChild is an application-defined function that 
        // retrieves the first or last child fragment.
        hr =  GetFragmentForChild(FIRST, ppRetVal);  
    }  

    else if (direction == NavigateDirection_LastChild)  
    {  
        hr = GetFragmentForChild(LAST, ppRetVal);  
    }  

    SafeRelease(&pWindowlessSite);
    return S_OK;   
}

4단계: IRawElementProviderFragment::GetRuntimeId 메서드를 구현합니다.

창 없는 컨트롤이 IRawElementProviderFragment::GetRuntimeId 메서드에 대한 호출을 받으면 컨트롤은 다음을 수행해야 합니다.

  1. 컨트롤 사이트의 IRawElementProviderWindowlessSite::GetRuntimeIdPrefix 메서드를 호출하여 런타임 ID 접두사를 검색합니다.
  2. 런타임 ID 접두사에 정수 를 추가하여 컨트롤에 대한 고유한 런타임 ID를 만듭니다.
  3. 런타임 ID를 호출자에게 반환합니다.

다음 예제에서는 GetRuntimeId 메서드를 구현하는 방법을 보여줍니다.

STDMETHODIMP CMyAccessibleUIAControl::GetRuntimeId(SAFEARRAY **ppRetVal)  
{   
    if (ppRetVal == NULL)
    {
        return E_INVALIDARG;
    }

    *ppRetVal = NULL;  
    HRESULT hr = E_FAIL;
    IRawElementProviderWindowlessSite *pWindowlessSite = NULL;  

    if (SUCCEEDED(m_pClientSite->QueryInterface(IID_PPV_ARGS(&pWindowlessSite))))  
    {  
        // Create a safe array to hold runtime ID.
        SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 1, 3);  
        if (psa == NULL)
        {
            hr = E_OUTOFMEMORY;
        }

        // Retrieve the runtime ID prefix from the control container. The prefix
        // consists of UiaAppendRuntimeId followed by the windowless site ID.
        if (SUCCEEDED(hr))
        {    
            hr = pWindowlessSite->GetRuntimeIdPrefix(&psa);  
        } 

        if (SUCCEEDED(hr))
        {
        // Append this fragment's ID to the retrieved runtime ID prefix.
            long i = 2;
            hr = SafeArrayPutElement(psa, &i, (void*)&m_Id);        
        }

        if (SUCCEEDED(hr))
        {
            *ppRetVal = psa;  
        }
    }

    SafeRelease(&pWindowlessSite);
    return hr;  
}

MSAA를 사용하여 창 없는 ActiveX 컨트롤에 액세스할 수 있도록 설정

창 없는 ActiveX 컨트롤 접근성