Ler em inglês

Partilhar via


Hospedar um controle ActiveX sem janela de automação da interface do usuário

Saiba como criar um contêiner de controle capaz de hospedar controles Microsoft ActiveX sem janela que implementam a Automação da Interface do Usuário da Microsoft. Usando as etapas descritas aqui, você pode garantir que todos os controles sem janelas de automação da interface do usuário hospedados em seu contêiner de controle estejam acessíveis a aplicativos cliente de tecnologia assistiva (AT).

O que precisa de saber

Tecnologias

Pré-requisitos

  • C/C++
  • Programação do Microsoft Win32 e COM (Component Object Model)
  • Controlos ActiveX sem janelas
  • Provedores de automação da interface do usuário

Instruções

Etapa 1: Forneça a interface IRawElementProviderSimple em nome do controle sem janela.

Sempre que o sistema precisa do ponteiro IRawElementProviderSimple para a raiz de um controle sem janelas, o sistema consulta o contêiner de controle. Para recuperar o ponteiro, o contêiner chama a implementação do controle sem janela do método IServiceProvider::QueryService.

Se o contêiner de controle tiver uma implementação de Automação da Interface do Utilizador, ele poderá retornar ao sistema o ponteiro de IRawElementProviderSimple do controlo sem janela.

Se o container de controlo tiver uma implementação do Microsoft Active Accessibility, chame a função UiaIAccessibleFromProvider para obter um ponteiro de interface IAccessible que representa o controlo e, em seguida, retorne o ponteiro de interface IAccessible para o sistema.

Etapa 2: Implementar a interface IRawElementProviderWindowlessSite.

Um contêiner de controle implementa o IRawElementProviderWindowlessSite interface para habilitar um controle sem janela baseado em automação da interface do usuário para comunicar suas informações de acessibilidade.

  1. Implemente IRawElementProviderWindowlessSite::GetRuntimeIdPrefix.

    Um fragmento de controle sem janela deve criar um ID de tempo de execução exclusivo para si mesmo. Para criar o seu ID de tempo de execução, um fragmento de controle sem janela recupera um valor de prefixo chamando o método GetRuntimeIdPrefix do site de controle e, em seguida, acrescenta ao prefixo um valor inteiro que é único em relação a todos os outros fragmentos no controle sem janela.

    O site de controle para um controle sem janela deve implementar o GetRuntimeIdPrefix método formando um SAFEARRAY que contém a constante UiaAppendRuntimeId, seguido por um valor inteiro que é exclusivo para o site.

    Este exemplo mostra como retornar um prefixo de ID de tempo de execução para um controle sem janela.

    IFACEMETHODIMP CProviderWindowlessSite::GetRuntimeIdPrefix(   
         SAFEARRAY **ppsaPrefix)   
    {   
        if (ppsaPrefix == NULL) 
        {
            return E_INVALIDARG;
        }
    
        // m_siteIndex is the index of the windowless control's
        // site. It is defined by the control container.
        int rId[] = { UiaAppendRuntimeId, m_siteIndex };
        SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 0, 2);  
        if (psa == NULL)
        {
            return E_OUTOFMEMORY;
        }
    
        for (LONG i = 0; i < 2; i++)
        {
            SafeArrayPutElement(psa, &i, (void*)&(rId[i]));
        }
    
        *ppsaPrefix = psa;  
        return S_OK;  
    }  
    
  2. Implemente o método IRawElementProviderWindowlessSite::GetAdjacentFragment.

    Um controle que implementa a automação da interface do usuário deve retornar um ponteiro para o provedor de fragmento pai do controle.

    Para retornar o pai do fragmento, um objeto que implementa a interface IRawElementProviderFragment deve ser capaz de implementar o método Navigate. Implementar Navigate é difícil para um controle sem janela porque o controle pode não conseguir determinar sua localização na árvore acessível do objeto pai. O métodoIRawElementProviderWindowlessSite::GetAdjacentFragment permite que o controle sem janela consulte seu site para o fragmento adjacente e, em seguida, retorne esse fragmento para o cliente chamado Navigate.

    Este exemplo mostra como um contêiner de controle recupera o fragmento pai de um controle sem janela.

    IFACEMETHODIMP CProviderWindowlessSite::GetAdjacentFragment(
            enum NavigateDirection direction, IRawElementProviderFragment **ppFragment)   
    {
        if (ppFragment == NULL)
        {
            return E_INVALIDARG;
        }
    
        *ppFragment = NULL;
        HRESULT hr = S_OK;
    
        switch (direction)
        {
            case NavigateDirection_Parent:
                {  
                    IRawElementProviderSimple *pSimple = NULL;
    
                    // Call an application-defined function to retrieve the
                    // parent provider interface.
                    hr = GetParentProvider(&pSimple);  
                    if (SUCCEEDED(hr))  
                    {  
                        // Get the parent's IRawElementProviderFragment interface.
                        hr = pSimple->QueryInterface(IID_PPV_ARGS(ppFragment));  
                        pSimple->Release();  
                    } 
                }  
                break;  
    
            case NavigateDirection_FirstChild:
            case NavigateDirection_LastChild:
                hr = E_INVALIDARG;
                break;
    
            // Ignore NavigateDirection_NextSibling and NavigateDirection_PreviousSibling
            // because there are no adjacent fragments.
            default:  
                break;  
        }  
    
        return hr;  
    }   
    

Etapa 3: Opcional: Implemente a interface IRawElementProviderHostingAccessibles.

Implemente o interface de IRawElementProviderHostingAccessibles se o contêiner de controle tiver uma implementação de provedor de Automação da Interface do Usuário que seja a raiz de uma árvore de acessibilidade que inclua controles ActiveX sem janelas que ofereçam suporte ao Microsoft Ative Accessibility. A interface IRawElementProviderHostingAccessibles tem um único método, GetEmbeddedAccessibles, que recupera os ponteiros de interface de IAccessible de todos os controlos ActiveX sem janela baseados em Microsoft Active Accessibility, hospedados pelo seu contentor de controlo.

Como hospedar um controle ActiveX sem janela MSAA

Acessibilidade do Controle ActiveX Sem Janelas