활성 접근성 서버에 UI 자동화 기능 추가

Microsoft UI 자동화 공급자가 없지만 IAccessible을 구현하는 컨트롤은 IAccessibleEx 인터페이스를 구현하여 일부 UI 자동화 기능을 제공하도록 쉽게 업그레이드할 수 있습니다. 이 인터페이스를 사용하면 컨트롤이 IRawElementProviderFragment와 같은 UI 자동화 공급자 인터페이스를 완전히 구현할 필요 없이 UI 자동화 속성 및 컨트롤 패턴을 노출할 수 있습니다. IAccessibleEx를 구현하려면 기준 Microsoft Active Accessibility 개체 계층 구조에 오류 또는 불일치(예: 부모 개체가 자식 개체로 나열되지 않은 자식 개체)가 없어야 하며 UI 자동화 사양과 충돌해서는 안 됩니다. Microsoft Active Accessibility 개체 계층 구조가 이러한 요구 사항을 충족하는 경우 IAccessibleEx를 사용하여 기능을 추가하는 것이 좋습니다. 그렇지 않으면 Microsoft Active Accessibility 구현과 함께 UI 자동화 구현해야 합니다.

범위 값이 있는 사용자 지정 컨트롤의 경우를 사용합니다. 컨트롤에 대한 Microsoft Active Accessibility 서버는 해당 역할을 정의하고 현재 값을 반환할 수 있지만 이러한 속성이 Microsoft 활성 접근성에 정의되어 있지 않으므로 컨트롤의 최소값과 최대값을 반환할 수 있는 수단이 부족합니다. UI 자동화 코어는 IAccessible을 통해 이러한 속성을 가져올 수 있으므로 UI 자동화 클라이언트는 컨트롤의 역할, 현재 값 및 기타 Microsoft Active Accessibility 속성을 검색할 수 있습니다. 그러나 개체의 IRangeValueProvider 인터페이스에 액세스할 수 없으면 UI 자동화 최대값과 최소값을 검색할 수도 없습니다.

컨트롤 개발자는 컨트롤에 대한 완전한 UI 자동화 공급자를 제공할 수 있지만 이는 IAccessible 구현의 기존 기능(예: 탐색 및 공통 속성)을 복제하는 것을 의미합니다. 대신 개발자는 IRangeValueProvider를 통해 컨트롤 관련 속성에 대한 지원을 추가하는 동시에 IAccessible을 계속 사용하여 이 기능을 제공할 수 있습니다.

사용자 지정 컨트롤을 업데이트하려면 다음 기본 단계가 필요합니다.

  • 액세스 가능한 개체에서 IServiceProvider 를 구현하여 IAccessibleEx 인터페이스를 이 개체 또는 별도의 개체에서 찾을 수 있도록 합니다.
  • 액세스 가능한 개체에서 IAccessibleEx 를 구현합니다.
  • Microsoft Active Accessibility 자식 항목에 대해 고유한 접근성 개체를 만듭니다. 이 개체는 Microsoft Active Accessibility에서 부모 개체의 IAccessible 인터페이스로 표시되었을 수 있습니다(예: 목록 항목). 이러한 개체에서 IAccessibleEx 를 구현합니다.
  • 액세스 가능한 모든 개체에서 IRawElementProviderSimple 을 구현합니다.
  • 액세스 가능한 개체에 적절한 컨트롤 패턴 인터페이스를 구현합니다.

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

IAccessibleEx 노출

컨트롤에 대한 IAccessibleEx 구현은 별도의 개체에 있을 수 있으므로 클라이언트 애플리케이션은 QueryInterface 를 사용하여 이 인터페이스를 가져올 수 없습니다. 대신 클라이언트는 IServiceProvider::QueryService를 호출해야 합니다. 이 메서드의 다음 예제 구현에서는 IAccessibleEx 가 별도의 개체에 구현되지 않은 것으로 가정합니다. 따라서 메서드는 단순히 QueryInterface를 통해 를 호출합니다.

HRESULT CListboxAccessibleObject::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
{
    if (!ppvObject)
    {
        return E_INVALIDARG;
    }
    *ppvObject = NULL;
    if (guidService == __uuidof(IAccessibleEx))
    {
        return QueryInterface(riid, ppvObject);
    }
    else 
    {
        return E_INVALIDARG;
    }
};

IAccessibleEx 구현

가장 관심 있는 IAccessibleEx 의 메서드는 GetObjectForChild입니다. 이 메서드는 Microsoft Active Accessibility 서버에 자식 항목에 대한 액세스 가능한 개체(최소한 IAccessibleEx를 노출하는 개체)를 만들 수 있는 기회를 제공합니다. Microsoft Active Accessibility에서 자식 항목은 일반적으로 액세스 가능한 개체가 아니라 접근성 있는 개체의 자식으로 표시됩니다. 그러나 UI 자동화 각 요소를 별도의 액세스 가능한 개체로 표현해야 하므로 GetObjectForChild는 요청 시 각 자식에 대해 별도의 개체를 만들어야 합니다.

다음 예제 구현에서는 사용자 지정 목록 보기의 항목에 액세스할 수 있는 개체를 반환합니다.

HRESULT CListboxAccessibleObject::GetObjectForChild(long idChild, IAccessibleEx **pRetVal)
{ 
    *pRetVal = NULL;
    VARIANT vChild;
    vChild.vt = VT_I4;
    vChild.lVal = idChild;

    // ValidateChildId is an application-defined function that checks whether
    // the child ID is valid. This is similar to code that validates the varChild
    // parameter in IAccessible methods.
    //
    // Additionally, if this idChild corresponds to a child that has its own
    // IAccessible, we should also return E_INVALIDARG here. (The caller
    // should instead be using the IAccessibleEx from that child's own
    // IAccessible in that case.)
    if (idChild == CHILDID_SELF || FAILED(ValidateChildId(vChild)))
    {
        return E_INVALIDARG;
    }

    // Return a suitable provider for this specific child.
    // This implementation returns a new instance each time; an implementation
    // can cache these if desired.

    // _pListboxControl is a member variable pointer to the owning control.
    IAccessibleEx* pAccEx  = new CListItemAccessibleObject(idChild, _pListboxControl);
    if (pAccEx == NULL)
    {
        return E_OUTOFMEMORY;
    }
    *pRetVal = pAccEx;
    return S_OK; 
}

전체 샘플 구현은 사용자 지정 컨트롤 액세스 가능 만들기, 5부: IAccessibleEx를 사용하여 MSDN의 사용자 지정 컨트롤에 UI 자동화 지원 추가를 참조하세요.

UI 자동화 공급자 프로그래머 가이드