Partilhar via


Implementação do provedor de automação da interface do usuário do lado do servidor

Nota

Esta documentação destina-se a desenvolvedores do .NET Framework que desejam usar as classes de automação da interface do usuário gerenciadas definidas no System.Windows.Automation namespace. Para obter as informações mais recentes sobre a automação da interface do usuário, consulte API de automação do Windows: automação da interface do usuário.

Esta seção descreve como implementar um provedor de automação da interface do usuário do lado do servidor para um controle personalizado.

A implementação para elementos do Windows Presentation Foundation (WPF) e elementos não-WPF (como aqueles projetados para Windows Forms) é fundamentalmente diferente. Os elementos do WPF fornecem suporte para automação da interface do usuário por meio de uma classe derivada de AutomationPeer. Elementos não-WPF fornecem suporte através de implementações de interfaces de provedor.

Considerações de Segurança

Os provedores devem ser escritos para que possam trabalhar em um ambiente de confiança parcial. Como UIAutomationClient.dll não está configurado para ser executado sob confiança parcial, o código do provedor não deve fazer referência a esse assembly. Se fizer isso, o código pode ser executado em um ambiente de confiança total, mas falhar em um ambiente de confiança parcial.

Em particular, não use campos de classes em UIAutomationClient.dll como aqueles em AutomationElement. Em vez disso, use os campos equivalentes de classes em UIAutomationTypes.dll, como AutomationElementIdentifiers.

Implementação do provedor pelo Windows Presentation Foundation Elements

Para obter mais informações sobre este tópico, consulte Automação da interface do usuário de um controle personalizado do WPF.

Implementação do provedor por elementos não-WPF

Os controles personalizados que não fazem parte da estrutura do WPF, mas que são escritos em código gerenciado (na maioria das vezes, são controles do Windows Forms), fornecem suporte à automação da interface do usuário implementando interfaces. Cada elemento deve implementar pelo menos uma das interfaces listadas na primeira tabela da próxima seção. Além disso, se o elemento suporta um ou mais padrões de controle, ele deve implementar a interface apropriada para cada padrão de controle.

Seu projeto de provedor de automação da interface do usuário deve fazer referência aos seguintes assemblies:

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Interfaces de provedor

Cada provedor de automação da interface do usuário deve implementar uma das interfaces a seguir.

Interface Description
IRawElementProviderSimple Fornece funcionalidade para um controle simples hospedado em uma janela, incluindo suporte para padrões de controle e propriedades.
IRawElementProviderFragment Herda de IRawElementProviderSimple. Adiciona funcionalidade para um elemento em um controle complexo, incluindo navegação dentro do fragmento, definição de foco e retorno do retângulo delimitador do elemento.
IRawElementProviderFragmentRoot Herda de IRawElementProviderFragment. Adiciona funcionalidade para o elemento raiz em um controle complexo, incluindo a localização de um elemento filho em coordenadas especificadas e a definição do estado de foco para todo o controle.

As interfaces a seguir fornecem funcionalidade adicional, mas não precisam ser implementadas.

Interface Description
IRawElementProviderAdviseEvents Permite que o provedor rastreie solicitações de eventos.
IRawElementProviderHwndOverride Permite o reposicionamento de elementos baseados em janela na árvore de automação da interface do usuário de um fragmento.

Todas as outras interfaces no namespace são para suporte a System.Windows.Automation.Provider padrões de controle.

Requisitos para provedores não-WPF

Para se comunicar com a Automação da Interface do Usuário, seu controle deve implementar as seguintes áreas principais de funcionalidade:

Caraterística Implementação
Expor o provedor à automação da interface do usuário Em resposta a uma mensagem WM_GETOBJECT enviada para a janela de controle, retorne o objeto que implementa IRawElementProviderSimple (ou uma interface derivada). Para fragmentos, este deve ser o provedor para a raiz do fragmento.
Fornecer valores de propriedade Implementar GetPropertyValue para fornecer ou substituir valores.
Permitir que o cliente interaja com o controle Implemente interfaces que suportem padrões de controle, como IInvokeProvider. Retorne esses provedores de padrões em sua implementação do GetPatternProvider.
Aumentar eventos Chame um dos métodos estáticos de AutomationInteropProvider para gerar um evento que um cliente pode ouvir.
Habilitar a navegação e o foco em um fragmento Implementar IRawElementProviderFragment para cada elemento dentro do fragmento. (Não é necessário para elementos que não fazem parte de um fragmento.)
Habilitar o foco e a localização do elemento filho em um fragmento Implementar IRawElementProviderFragmentRoot. (Não é necessário para elementos que não são raízes de fragmento.)

Valores de propriedade em provedores não-WPF

Os provedores de automação da interface do usuário para controles personalizados devem oferecer suporte a determinadas propriedades que podem ser usadas pelo sistema de automação, bem como por aplicativos cliente. Para elementos hospedados em janelas (HWNDs), a Automação da Interface do Usuário pode recuperar algumas propriedades do provedor de janela padrão, mas deve obter outras do provedor personalizado.

Os provedores de controles baseados em HWND geralmente não precisam fornecer as seguintes propriedades (identificadas por valores de campo):

Nota

O RuntimeIdProperty de um elemento simples ou raiz de fragmento hospedado em uma janela é obtido a partir da janela, no entanto, os elementos de fragmento abaixo da raiz (como itens de lista em uma caixa de listagem) devem fornecer seus próprios identificadores. Para obter mais informações, veja GetRuntimeId.

O IsKeyboardFocusableProperty deve ser retornado para provedores hospedados em um controle Windows Forms. Nesse caso, o provedor de janela padrão pode não conseguir recuperar o valor correto.

O NameProperty é geralmente fornecido pelo provedor de host. Por exemplo, se um controle personalizado é derivado de Control, o nome é derivado da Text propriedade do controle.

Para obter um código de exemplo, consulte Propriedades de retorno de um provedor de automação da interface do usuário.

Eventos em provedores não-WPF

Os provedores de automação da interface do usuário devem gerar eventos para notificar os aplicativos cliente sobre alterações no estado da interface do usuário. Os métodos a seguir são usados para gerar eventos.

Método Description
RaiseAutomationEvent Gera vários eventos, incluindo eventos acionados por padrões de controle.
RaiseAutomationPropertyChangedEvent Gera um evento quando uma propriedade de Automação da Interface do Usuário é alterada.
RaiseStructureChangedEvent Gera um evento quando a estrutura da árvore de Automação da Interface do Usuário foi alterada; por exemplo, pela remoção ou adição de um elemento.

O objetivo de um evento é notificar o cliente de algo que está ocorrendo na interface do usuário (UI), independentemente de a atividade ser ou não acionada pelo próprio sistema de automação da interface do usuário. Por exemplo, o evento identificado por InvokedEvent deve ser gerado sempre que o controle é invocado, seja por meio de entrada direta do usuário ou pela chamada Invokedo aplicativo cliente.

Para otimizar o desempenho, um provedor pode gerar eventos seletivamente ou não gerar eventos se nenhum aplicativo cliente estiver registrado para recebê-los. Os métodos a seguir são usados para otimização.

Método Description
ClientsAreListening Essa propriedade estática especifica se algum aplicativo cliente se inscreveu em eventos de Automação da Interface do Usuário.
IRawElementProviderAdviseEvents A implementação dessa interface pelo provedor em uma raiz de fragmento permite que ela seja avisada quando os clientes registram e cancelam o registro de manipuladores de eventos para eventos no fragmento.

Navegação de provedor não-WPF

Os provedores de controles simples, como um botão personalizado hospedado em uma janela (HWND), não precisam oferecer suporte à navegação na árvore de Automação da Interface do Usuário. A navegação de e para o elemento é manipulada pelo provedor padrão para a janela do host, que é especificada na implementação do HostRawElementProvider. No entanto, ao implementar um provedor para um controle personalizado complexo, você deve oferecer suporte à navegação entre o nó raiz do fragmento e seus descendentes e entre nós irmãos.

Nota

Os elementos de um fragmento diferente da raiz devem retornar uma null referência de HostRawElementProvider, porque eles não estão hospedados diretamente em uma janela e nenhum provedor padrão pode oferecer suporte à navegação de e para eles.

A estrutura do fragmento é determinada pela implementação do Navigate. Para cada direção possível de cada fragmento, esse método retorna o objeto provider para o elemento nessa direção. Se não houver nenhum elemento nessa direção, o método retornará uma null referência.

A raiz do fragmento suporta navegação apenas para elementos filho. Por exemplo, uma caixa de listagem retorna o primeiro item da lista quando a direção é FirstChild, e o último item quando a direção é LastChild. A raiz do fragmento não suporta navegação para um pai ou irmãos; Isso é tratado pelo provedor de janela do host.

Os elementos de um fragmento que não são a raiz devem suportar a navegação para os pais e para quaisquer irmãos e filhos que tenham.

Reparentalidade de provedor não-WPF

As janelas pop-up são, na verdade, janelas de nível superior e, portanto, por padrão, aparecem na árvore de automação da interface do usuário como filhos da área de trabalho. Em muitos casos, no entanto, as janelas pop-up são logicamente filhos de algum outro controle. Por exemplo, a lista suspensa de uma caixa de combinação é logicamente filha da caixa de combinação. Da mesma forma, uma janela pop-up de menu é logicamente um filho do menu. A Automação da Interface do Usuário fornece suporte para repais janelas pop-up para que pareçam ser filhos do controle associado.

Para recriar uma janela pop-up:

  1. Crie um provedor para a janela pop-up. Isso requer que a classe da janela pop-up seja conhecida com antecedência.

  2. Implemente todas as propriedades e padrões como de costume para esse pop-up, como se fosse um controle por si só.

  3. Implemente a HostRawElementProvider propriedade para que ela retorne o valor obtido de HostProviderFromHandle, onde o parâmetro é o identificador de janela da janela pop-up.

  4. Implemente Navigate para a janela pop-up e seu pai para que a navegação seja tratada corretamente do pai lógico para os filhos lógicos e entre filhos irmãos.

Quando a Automação da Interface do Usuário encontra a janela pop-up, ela reconhece que a navegação está sendo substituída pelo padrão e ignora a janela pop-up quando é encontrada como filha da área de trabalho. Em vez disso, o nó só será acessível através do fragmento.

A reparentalidade não é adequada para casos em que um controle pode hospedar uma janela de qualquer classe. Por exemplo, um vergalhão pode hospedar qualquer tipo de HWND em suas bandas. Para lidar com esses casos, a Automação da Interface do Usuário oferece suporte a uma forma alternativa de realocação de HWND, conforme descrito na próxima seção.

Reposicionamento de provedor não-WPF

Os fragmentos de automação da interface do usuário podem conter dois ou mais elementos contidos em uma janela (HWND). Como cada HWND tem seu próprio provedor padrão que considera o HWND como filho de um HWND que contém, a árvore de Automação da Interface do Usuário mostrará, por padrão, os HWNDs no fragmento como filhos da janela pai. Na maioria dos casos, esse é um comportamento desejável, mas às vezes pode levar a confusão porque não corresponde à estrutura lógica da interface do usuário.

Um bom exemplo disso é um controle de vergalhão. Um vergalhão contém bandas, cada uma das quais, por sua vez, pode conter um controle baseado em HWND, como uma barra de ferramentas, uma caixa de edição ou uma caixa de combinação. O provedor de janela padrão para o HWND de vergalhão vê os HWNDs de controle de banda como filhos e o provedor de vergalhão vê as bandas como crianças. Como o provedor HWND e o provedor de vergalhão estão trabalhando em conjunto e combinando seus filhos, tanto as bandas quanto os controles baseados em HWND aparecem como filhos do vergalhão. Logicamente, no entanto, apenas as bandas devem aparecer como filhos do vergalhão, e cada provedor de banda deve ser acoplado ao provedor HWND padrão para o controle que ele contém.

Para fazer isso, o provedor raiz do fragmento para o vergalhão expõe um conjunto de filhos que representam as bandas. Cada banda tem um único provedor que pode expor propriedades e padrões. Em sua implementação de , o provedor de banda retorna o provedor de HostRawElementProviderjanela padrão para o controle HWND, que ele obtém chamando HostProviderFromHandle, passando na alça de janela do controle. Finalmente, o provedor raiz de fragmento para o vergalhão implementa a IRawElementProviderHwndOverride interface e, em sua implementação, retorna o provedor de GetOverrideProviderForHwnd banda apropriado para o controle contido no HWND especificado.

Consulte também