Como usar Automação da Interface do Usuário para tornar um controle ActiveX sem janelas acessível
Descreve como usar a API do Microsoft Automação da Interface do Usuário para garantir que o controle Microsoft ActiveX sem janelas esteja acessível a aplicativos cliente at (tecnologia adaptativa).
O que você precisa saber
Tecnologias
Pré-requisitos
- C/C++
- Programação do Microsoft Win32 e do COM (Component Object Model)
- Controles ActiveX sem janelas
- provedores de Automação da Interface do Usuário
Instruções
Etapa 1: implementar as interfaces do provedor de Automação da Interface do Usuário.
Para tornar seu aplicativo acessível, você deve implementar as interfaces do provedor Automação da Interface do Usuário para o controle ActiveX sem janelas, incluindo IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRoot e IRawElementProviderAdviseEvents. Você deve implementar essas interfaces da mesma forma que faria para um controle baseado em janela, exceto conforme descrito nas etapas a seguir. Para obter mais informações sobre como implementar interfaces de provedor UIA, consulte Guia do programador do provedor de Automação da Interface do Usuário.
Etapa 2: implementar a interface IServiceProvider.
Quando um cliente precisa de informações de acessibilidade sobre o controle sem janelas, o contêiner de controle chama o método IServiceProvider::QueryService do controle para recuperar o ponteiro da interface IRawElementProviderSimple para o controle.
O exemplo a seguir mostra como implementar o método 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;
}
Etapa 3: implementar o método IRawElementProviderFragment::Navigate.
Quando o método IRawElementProviderFragment::Navigate do controle sem janelas é chamado para navegar até o pai ou um irmão do provedor raiz do controle sem janelas, seu método Navigate deve delegar ao método IRawElementProviderWindowlessSite::GetAdjacentFragment do contêiner de controle.
O exemplo a seguir mostra como implementar o método 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;
}
Etapa 4: implementar o método IRawElementProviderFragment::GetRuntimeId.
Quando o controle sem janelas recebe uma chamada para o método IRawElementProviderFragment::GetRuntimeId , o controle deve fazer o seguinte:
- Recupere um prefixo de ID de runtime chamando o método IRawElementProviderWindowlessSite::GetRuntimeIdPrefix do site de controle.
- Crie uma ID de runtime exclusiva para o controle acrescentando um inteiro ao prefixo da ID do runtime.
- Retornar a ID de runtime para o chamador.
O exemplo a seguir mostra como implementar o método 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;
}
Tópicos relacionados