Adicionando a funcionalidade de automação da interface do usuário ao Active Accessibility Servers.
Os controles que não têm um provedor de Automação da Interface do Usuário da Microsoft, mas que implementam IAccessible podem ser atualizados facilmente para fornecer funcionalidade de Automação da Interface do Usuário, implementando a interface IAccessibleEx. Essa interface permite que o controle exponha propriedades e padrões de controle da automação da interface do usuário, sem a necessidade de uma implementação completa de interfaces de provedor de automação da interface do usuário, como IRawElementProviderFragment. Para implementar IAccessibleEx, a hierarquia de objetos de linha de base do Microsoft Active Accessibility não deve conter erros ou inconsistências (como um objeto filho, cujo objeto pai não o lista como filho) e não deve entrar em conflito com as especificações de Automação da Interface do Usuário. Se a hierarquia de objetos do Microsoft Active Accessibility atender a esses requisitos, será uma boa candidata para adicionar funcionalidade usando IAccessibleEx; caso contrário, você deverá implementar a Automação da Interface do Usuário sozinho ou junto com a implementação do Microsoft Active Accessibility.
Considere o caso de um controle personalizado que tem um valor de intervalo. O servidor Microsoft Active Accessibility para o controle define sua função e é capaz de retornar seu valor atual, mas não tem os meios para retornar os valores mínimo e máximo do controle, pois essas propriedades não são definidas no Microsoft Active Accessibility. Um cliente de Automação da Interface do Usuário é capaz de recuperar a função do controle, o valor atual e outras propriedades do Microsoft Active Accessibility, pois o núcleo de Automação da Interface do Usuário pode obtê-las por meio de IAccessible. No entanto, sem acesso a uma IRangeValueProvider interface no objeto, a Automação da Interface do Usuário também não pode recuperar os valores máximo e mínimo.
O desenvolvedor do controle poderia fornecer um provedor completo de automação da interface do usuário para o controle, mas isso significaria duplicar grande parte da funcionalidade existente da implementação IAccessible : por exemplo, navegação e propriedades comuns. Em vez disso, o desenvolvedor pode continuar a contar com IAccessible para fornecer essa funcionalidade, ao mesmo tempo em que dá suporte a propriedades específicas de controle por meio de IRangeValueProvider.
A atualização de controle personalizado requer estas etapas principais:
- Implemente IServiceProvider no objeto acessível para que a interface IAccessibleEx possa ser encontrada neste objeto ou em um objeto separado.
- Implemente IAccessibleEx no objeto acessível.
- Crie objetos acessíveis distintos para qualquer item filho do Microsoft Active Accessibility que pode ter sido representado pela interface IAccessible no objeto pai (por exemplo, itens de lista). Implemente IAccessibleEx nesses objetos.
- Implemente IRawElementProviderSimple em todos os objetos acessíveis.
- Implemente as interfaces de padrão de controle apropriadas nos objetos acessíveis.
Este tópico inclui as seções a seguir:
Expondo IAccessibleEx.
Já que a implementação de IAccessibleEx para um controle pode residir em um objeto separado, os aplicativos cliente não podem depender de QueryInterface para obter essa interface. Em vez disso, espera-se que os clientes chamem IServiceProvider::QueryService. No exemplo de implementação desse método a seguir, presume-se que IAccessibleEx não é implementado em um objeto separado, portanto, o método simplesmente chama 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;
}
};
Implementando IAccessibleEx
O método de IAccessibleEx o que é mais interessante é GetObjectForChild. Esse método dá ao servidor do Microsoft Active Accessibility a oportunidade de criar um objeto acessível (um que expõe, no mínimo), IAccessibleExpara um item filho. No Microsoft Active Accessibility, os itens filho normalmente não são representados como objetos acessíveis, mas como filhos de um objeto acessível. No entanto, como Automação da Interface do Usuário requer que cada elemento seja representado por um objeto acessível separado, GetObjectForChild deve criar um objeto separado para cada filho sob demanda.
O exemplo de implementação a seguir, retorna um objeto acessível para um item em um modo de exibição de lista personalizado.
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;
}
Para obter um exemplo de implementação completa, consulte Tornando os controles personalizados acessíveis, Parte 5: Usando IAccessibleEx para adicionar suporte a automação da interface do usuário a um controle personalizado.
Tópicos relacionados