Как использовать автоматизацию пользовательского интерфейса для создания элемента управления ActiveX без окон

Описывает, как использовать API автоматизации пользовательского интерфейса Майкрософт, чтобы убедиться, что безоконный элемент управления Microsoft ActiveX доступен для клиентских приложений с поддержкой технологий для людей с ограниченными возможностями (АТ).

Что нужно знать

Технологии

Необходимые условия

  • C/C++
  • Программирование Microsoft Win32 и компонентной объектной модели (COM)
  • Элементы ActiveX без окон
  • Поставщики автоматизации пользовательского интерфейса

Инструкции

Шаг 1. Реализация интерфейсов поставщика автоматизации пользовательского интерфейса.

Чтобы сделать ваше приложение доступным, следует реализовать интерфейсы поставщика автоматизации пользовательского интерфейса для ActiveX-контрола без окон, включая IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRootи IRawElementProviderAdviseEvents. Эти интерфейсы следует реализовать так же, как и для элемента управления на основе окон, за исключением описанных ниже действий. Дополнительные сведения о реализации интерфейсов UIA-провайдера см. в Руководстве программиста по автоматизации пользовательского интерфейса.

Шаг 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.
  2. Создайте уникальный идентификатор среды выполнения для элемента управления, добавив целое число в префикс идентификатора среды выполнения.
  3. Возвратите идентификатор времени выполнения вызывающему.

В следующем примере показано, как реализовать метод 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 без окон