Padrões de controle Text e TextRange

Descreve diretrizes e convenções para implementar ITextProvider, ITextProvider2 e ITextRangeProvider, incluindo informações sobre propriedades e métodos. O padrão de controle Texto permite que aplicativos e controles exponham um modelo de objeto de texto simples, permitindo que os clientes recuperem conteúdo textual, atributos de texto e objetos inseridos de controles baseados em texto.

Para dar suporte ao padrão de controle texto , os controles implementam as interfaces ITextProvider e ITextProvider2 . Os tipos de controle que devem dar suporte ao padrão de controle Texto incluem os tipos de controle Editar e Documento e qualquer outro tipo de controle que permita que o usuário insira texto ou selecione texto somente leitura.

O padrão de controle Texto pode ser usado com outros padrões de controle do Microsoft Automação da Interface do Usuário para dar suporte a vários tipos de objetos inseridos no texto, incluindo tabelas, hiperlinks e botões de comando.

As interfaces ITextProvider e ITextProvider2 incluem vários métodos para adquirir intervalos de texto. Um intervalo de texto é um objeto que representa um intervalo contíguo de texto ou vários intervalos de texto não contíguos em um contêiner de texto. Um método ITextProvider adquire um intervalo de texto que representa todo o documento, enquanto outros adquirem intervalos de texto que representam alguma parte do documento, como o texto selecionado, o texto visível ou um objeto inserido no texto.

Um objeto de intervalo de texto é representado pelo padrão de controle TextRange , que é implementado por meio da interface ITextRangeProvider . O padrão de controle TextRange fornece métodos e propriedades usados para expor informações sobre o texto no intervalo, mover os pontos de extremidade do intervalo, selecionar ou desmarcar texto, rolar o intervalo para a exibição e assim por diante.

Para obter mais informações sobre os padrões de controle Text e TextRange, consulte Suporte Automação da Interface do Usuário para conteúdo textual.

Começando com Windows 8.1 provedores podem implementar a interface ITextRangeProvider2. Isso permite invocar menus de contexto associados a um intervalo de texto. Isso dá suporte a cenários como a autocorreção de texto ou a seleção de candidatos ao IME (Editor de Método de Entrada).

Este tópico inclui as seções a seguir.

Diretrizes e convenções de implementação

Ao implementar o padrão de controle Texto , observe as seguintes diretrizes e convenções:

  • Qualquer controle que permita o acesso ao texto (por exemplo, inserir texto ou selecionar texto somente leitura) deve dar suporte ao padrão de controle Texto .
  • O padrão de controle Texto pode ser usado com qualquer elemento de interface do usuário que apresente texto, até mesmo um rótulo estático em um controle de botão padrão. No entanto, não é necessário em controles de texto estático que não podem ser selecionados ou não têm um ponto de inserção.
  • Para garantir que o texto esteja totalmente acessível, os controles que implementam ITextProvider também devem dar suporte à interface IValueProvider . IValueProvider complementa ITextProvider fornecendo uma maneira programática de alterar o texto. Ele também oferece maior compatibilidade com aplicativos cliente de tecnologia adaptativa, incluindo aqueles baseados em tecnologias herdadas, como a Acessibilidade Ativa da Microsoft. Quando ambos os padrões de controle são implementados, o evento TextChanged (UIA_Text_TextChangedEventId) e o evento AutomationPropertyChanged (UIA_AutomationPropertyChangedEventId) são equivalentes à propriedade Value (UIA_ValueValuePropertyId). Ambos os eventos devem ter suporte.
  • O padrão de controle Texto dá suporte a apenas um fluxo de texto e um visor por controle. Se o aplicativo oferecer várias exibições de documento em painéis, cada exibição (controle) deverá dar suporte a ITextProvider de forma independente.
  • O método ITextProvider::GetSelection pode retornar um único intervalo de texto que representa o texto selecionado no momento. Se um controle der suporte à seleção de vários intervalos não contíguos de texto, o método GetSelection deverá retornar uma matriz que contenha uma interface ITextRangeProvider para cada intervalo de texto selecionado.
  • O padrão de controle Texto representa o ponto de inserção como um intervalo de texto degenerado (vazio). O método ITextProvider::GetSelection deve retornar um intervalo de texto degenerado quando o ponto de inserção existir e nenhum texto for selecionado. Para obter mais informações, consulte Interoperabilidade com o System Caret.
  • O método ITextProvider::GetVisibleRanges poderá retornar um único intervalo de texto se um intervalo contíguo de texto estiver visível no visor ou retornar uma matriz de intervalos de texto não contíguos que representam várias linhas de texto parcialmente visíveis.
  • O método ITextProvider::RangeFromChild deverá retornar um intervalo degenerado se o elemento filho não contiver texto. Como um objeto inserido pode incluir texto, o método RangeFromChild nem sempre pode retornar um intervalo de texto degenerado. Para obter mais informações, consulte Como Automação da Interface do Usuário expõe objetos inseridos.
  • O método ITextProvider::RangeFromPoint executa testes de clique na área do documento usando as coordenadas de tela especificadas. O intervalo de texto resultante deve ser consistente com o ponto de inserção ou seleção resultante do clique no local nas coordenadas de tela especificadas. Por exemplo, se uma imagem residir nas coordenadas de tela especificadas, o intervalo de texto resultante deverá ser o mesmo que o intervalo de texto que o método ITextProvider::RangeFromChild adquiriria para a imagem. Da mesma forma, se um aplicativo cliente solicitar um intervalo de texto para o local no centro do cursor do sistema (o ponto de inserção), o intervalo de texto resultante deverá ser o mesmo que o local do cursor do sistema.
  • A propriedade ITextProvider::D ocumentRange sempre deve fornecer um intervalo de texto que inclua todo o texto compatível com a implementação ITextProvider correspondente.
  • O evento UIA_Text_TextChangedEventId deve ser gerado após qualquer alteração de texto ocorrer, mesmo que a alteração não esteja visível no visor. Por exemplo, o provedor deve gerar o evento mesmo que o usuário cole exatamente o mesmo texto sobre o texto selecionado.
  • A UIA_Text_TextSelectionChangedEventId deve ser gerada sempre que a seleção de texto for alterada ou sempre que o ponto de inserção (circunflexo) se mover entre o texto.

Ao implementar o padrão de controle TextRange , observe as seguintes diretrizes e convenções:

  • Todos os métodos do padrão de controle TextRange devem executar operações de texto, independentemente do estado de visibilidade do texto. A visibilidade de um intervalo de texto sempre pode ser determinada consultando o atributo de texto IsHidden (UIA_IsHiddenAttributeId).
  • Se possível, um provedor deve garantir que quaisquer alterações de texto, como exclusões, inserções e movimentações, sejam refletidas nos objetos de intervalo de texto associados (instâncias da interface ITextRangeProvider ) e gerar um evento de UIA_Text_TextChangedEventId . Os clientes podem usar o evento como uma dica para confirmar as alterações editoriais feitas no texto de um controle.
  • Todos os objetos de intervalo de texto usados pelos métodos ITextRangeProvider::Compare, CompareEndpoints e MoveEndpointByRange devem ser pares da mesma implementação de padrão de controle de texto .
  • Embora não seja necessário, o valor pRetVal recuperado pelo método ITextRangeProvider::CompareEndpoints pode indicar a distância, em caracteres (TextUnit_Character), entre os dois pontos de extremidade. No entanto, os aplicativos cliente não devem depender da precisão de pRetVal além de seu valor positivo ou negativo.
  • Os métodos ITextRangeProvider::ExpandToEnclosingUnit, Move e MoveEndpointByUnit exigem uma consideração cuidadosa da unidade de texto especificada. Para obter mais informações, consulte Manipulando um TextRange por unidade de texto.
  • Para requisitos de implementação relacionados aos métodos ITextRangeProvider::Select, AddToSelection e RemoveFromSelection , consulte Selecting Text in a Text Range.
  • Os métodos ITextRangeProvider::FindText e FindAttribute pesquisam para frente ou para trás um único atributo de texto ou cadeia de texto correspondente. Eles deverão retornar NULL se nenhuma correspondência for encontrada.
  • O método ITextRangeProvider::GetAttributeValue deve retornar o endereço adquirido da função UiaGetReservedMixedAttributeValue ou UiaGetReservedNotSupportedValue se o atributo associado variar no intervalo ou se o atributo não tiver suporte do controle de texto. A especificação do padrão de controle TextRange não permite adicionar novos identificadores de atributo de texto ou alterar a forma como os atributos existentes são definidos.
  • Se possível, o método ITextRangeProvider::GetBoundingRectangles deve retornar uma matriz que contém um retângulo delimitador para cada linha de texto totalmente ou parcialmente visível em um intervalo de texto. Se isso não for possível, o provedor poderá retornar uma matriz que contém os retângulos delimitador apenas de linhas totalmente visíveis; no entanto, isso limita a capacidade de um aplicativo cliente de descrever com precisão como o texto está sendo apresentado na tela.
  • O método ITextRangeProvider::GetChildren deve retornar todos os elementos filho inseridos em um intervalo de texto, mas não precisa retornar nenhum filho dos elementos filho. Por exemplo, se um intervalo de texto contiver uma tabela que tenha várias células filho, o método GetChildren poderá retornar apenas o elemento table e não os elementos de célula. Por motivos de desempenho ou arquitetura, um provedor pode não ser capaz de expor todos os objetos inseridos hospedados em um documento na árvore de automação. Nesse caso, o provedor deve pelo menos dar suporte à enumeração de objetos filho por meio do método GetChildren e, como opção, dar suporte ao padrão de controle VirtualizedItem para suporte à des virtualização.
  • O método ITextRangeProvider::GetEnclosingElement normalmente retorna o provedor de texto que fornece o intervalo de texto. No entanto, se o provedor de texto der suporte a objetos filho, como tabelas ou hiperlinks, o elemento delimitador poderá ser um descendente do provedor de texto. O elemento retornado por GetEnclosingElement deve ser o elemento mais próximo do intervalo de texto fornecido. Por exemplo, se o intervalo de texto estiver em uma célula de uma tabela, GetEnclosingElement deverá retornar a célula que contém em vez do elemento table.
  • O método ITextRangeProvider::GetText deve retornar o texto sem formatação no intervalo. Para obter mais informações, consulte Adquirindo texto de um intervalo de texto.
  • Chamar ITextRangeProvider::ScrollIntoView deve alinhar o texto no visor do controle de texto, conforme especificado pelo parâmetro alignToTop . Embora não haja nenhum requisito em termos de alinhamento horizontal, o intervalo de texto deve ser visível horizontal e verticalmente. Ao avaliar o parâmetro alignToTop , um provedor deve levar em conta a orientação do controle de texto e a direção do fluxo do texto. Por exemplo, se alignToTop for TRUE para um controle de texto orientado verticalmente contendo texto que flui da direita para a esquerda, o provedor deverá alinhar o intervalo de texto com o lado direito do visor.
  • Ao mover um documento por TextUnit_Line, se o intervalo de texto entrar em uma tabela inserida, cada linha de texto em uma célula deverá ser tratada como uma linha.

Membros necessários para ITextProvider

As propriedades e os métodos a seguir são necessários para implementar a interface ITextProvider .

Membros necessários Tipo de membro Observações
Documentrange Propriedade Nenhum
Supportedtextselection Propriedade Nenhum
Getselection Método Nenhum
GetVisibleRanges Método Nenhum
RangeFromChild Método Nenhum
Rangefrompoint Método Nenhum
UIA_Text_TextChangedEventId Evento Nenhum
UIA_Text_TextSelectionChangedEventId Evento Nenhum

 

As propriedades e métodos adicionais a seguir são necessários para implementar a interface ITextProvider2 .

Membros necessários Tipo de membro Observações
GetCaretRange Método Nenhum
RangeFromAnnotation Método Nenhum

 

Membros necessários para ITextRangeProvider

As propriedades e os métodos a seguir são necessários para implementar a interface ITextRangeProvider .

Membros necessários Tipo de membro Observações
Addtoselection Método Nenhum
Clone Método Nenhum
Comparar Método Nenhum
CompareEndpoints Método Nenhum
ExpandToEnclosingUnit Método Nenhum
FindAttribute Método Nenhum
Findtext Método Nenhum
Getattributevalue Método Nenhum
GetBoundingRectangles Método Nenhum
GetChildren Método Nenhum
GetEnclosingElement Método Nenhum
Gettext Método Nenhum
Mover Método Nenhum
MoveEndpointByUnit Método Nenhum
MoveEndpointByRange Método Nenhum
Selecionar Método Nenhum
ScrollIntoView Método Nenhum

 

As propriedades e métodos adicionais a seguir são necessários para implementar a interface ITextRangeProvider2 .

Membros necessários Tipo de membro Observações
ShowContextMenu Método Consulte a seção "Implementando ShowContextMenu"

 

O padrão de controle TextRange não tem eventos associados.

Suporte a intervalos de texto

Esta seção descreve como um provedor deve implementar vários métodos das interfaces ITextRangeProvider e ITextRangeProvider2 para dar suporte ao padrão de controle TextRange .

Manipulando um intervalo de texto por unidade de texto

A interface ITextRangeProvider fornece vários métodos para manipular e navegar intervalos de texto em um controle baseado em texto. Os métodos ITextRangeProvider::Move, MoveEndpointByUnit e ExpandToEnclosingUnit movem um intervalo de texto ou um de seus pontos de extremidade pela unidade de texto especificada, como caractere, palavra, parágrafo e assim por diante. Para obter mais informações, consulte Automação da Interface do Usuário Unidades de Texto.

Apesar do nome, o método ITextRangeProvider::ExpandToEnclosingUnit não necessariamente expande um intervalo de texto. Em vez disso, ele "normaliza" um intervalo de texto movendo os pontos de extremidade para que o intervalo engloba a unidade de texto especificada. O intervalo será expandido se for menor que a unidade especificada ou reduzido se for maior que a unidade especificada. É fundamental que o método ExpandToEnclosingUnit sempre normalize os intervalos de texto de maneira consistente; caso contrário, outros aspectos da manipulação de intervalo de texto por unidade de texto seriam imprevisíveis. O diagrama a seguir mostra como ExpandToEnclosingUnit normaliza um intervalo de texto movendo os pontos de extremidade do intervalo.

diagrama mostrando as posições do ponto de extremidade do intervalo de texto antes e depois de uma chamada para expandtoenclosingunit

Se o intervalo de texto começar no início de uma unidade de texto e terminar no início ou antes do próximo limite de unidade de texto, o ponto de extremidade final será movido para o próximo limite de unidade de texto (consulte 1 e 2 no diagrama anterior).

Se o intervalo de texto começar no início de uma unidade de texto e terminar em ou após o próximo limite de unidade, o ponto de extremidade final permanecerá ou será movido para trás para o próximo limite de unidade após o ponto de extremidade inicial (consulte 3 e 4 na ilustração anterior). Se houver mais de um limite de unidade de texto entre os pontos de extremidade inicial e final, o ponto de extremidade final será movido para trás para o próximo limite de unidade após o ponto de extremidade inicial, resultando em um intervalo de texto com uma unidade de texto de comprimento.

Se o intervalo de texto começar em um meio da unidade de texto, o ponto de extremidade inicial será movido para trás para o início da unidade de texto e o ponto de extremidade final será movido para frente ou para trás, conforme necessário, para o próximo limite de unidade após o ponto de extremidade inicial (consulte 5 a 8 no diagrama anterior).

Quando o método ITextRangeProvider::Move é chamado, o provedor normaliza o intervalo de texto pela unidade de texto especificada, usando a mesma lógica de normalização que o método ExpandToEnclosingUnit . Em seguida, o provedor move o intervalo para trás ou para frente pelo número especificado de unidades de texto. Ao mover o intervalo, o provedor deve ignorar os limites de qualquer objeto inserido no texto. (No entanto, o limite de unidade em si pode ser afetado pela existência de um objeto inserido). O diagrama a seguir demonstra como o método Move move um intervalo de texto, unidade por unidade, entre objetos inseridos e limites de unidade de texto.

diagrama mostrando como o método move pontos de extremidade de intervalo entre os limites de unidade de texto e objeto

O método ITextRangeProvider::MoveEndpointByUnit move um dos pontos de extremidade para frente ou para trás por unidade de texto especificada, como mostra a ilustração a seguir.

diagrama mostrando como moveendpointbyunit move o ponto de extremidade de um intervalo

O método ITextRangeProvider::MoveEndpointByRange permite que um aplicativo cliente defina um ponto de extremidade de um intervalo de texto para o mesmo local que o ponto de extremidade especificado de um segundo intervalo de texto.

Selecionando Texto em um Intervalo de Texto

A interface ITextRangeProvider inclui vários métodos para controlar a seleção de texto em um controle baseado em texto.

O método ITextRangeProvider::Select deve selecionar o texto que corresponde a um intervalo de texto e remover a seleção anterior, se houver, do controle de texto. Se Select for chamado em um intervalo de texto degenerado, o provedor deverá mover o ponto de inserção para o local do intervalo de texto sem selecionar nenhum texto.

Se um controle der suporte à seleção de vários intervalos de texto, os métodos ITextRangeProvider::AddToSelection e RemoveFromSelection adicionarão intervalos de texto e os removerão da coleção de intervalos de texto selecionados. Se o controle der suporte apenas a um intervalo de texto selecionado por vez, mas a operação de seleção resultar na seleção de vários intervalos de texto não contíguos, o provedor deverá retornar um erro de E_INVALIDOPERATION ou deve estender ou truncar a seleção atual. A propriedade ITextProvider::SupportedTextSelection deve indicar se um controle dá suporte à seleção de intervalos únicos ou múltiplos de texto ou nenhum.

Se um controle baseado em texto der suporte a inserções de texto, chamar ITextRangeProvider::AddToSelection ou RemoveFromSelection em um intervalo de texto degenerado no controle deverá mover o ponto de inserção, mas não deve selecionar nenhum texto.

Adquirir texto de um intervalo de texto

O método ITextRangeProvider::GetText deve retornar o texto sem formatação de um intervalo de texto. O texto sem formatação deve incluir todos os caracteres de controle encontrados no texto de origem, como retornos de carro e a LRM (marca da esquerda para a direita) Unicode. O texto sem formatação não deve incluir marcas de marcação como HTML que possam estar presentes no texto de origem. Além disso, todos os códigos de escape no texto de origem devem ser convertidos nos equivalentes de texto sem formatação. Por exemplo, " " deve ser convertido em um caractere de espaço simples.

Se um objeto inserido abranger um intervalo de texto, o texto sem formatação deverá incluir o texto interno do objeto, mas não o texto alternativo (a propriedade name do objeto inserido) porque ele pode ser inconsistente com o texto interno descritivo. Para obter mais informações, consulte Como Automação da Interface do Usuário expõe objetos inseridos.

Implementando ShowContextMenu

ITextRangeProvider2::ShowContextMenu sempre deve mostrar o menu de contexto no ponto de extremidade inicial do intervalo. Isso deve ser equivalente ao que aconteceria se o usuário pressionasse a tecla de menu de contexto ou SHIFT + F10 com o ponto de inserção no início do intervalo.

Se mostrar o menu de contexto normalmente resultar na mudança do ponto de inserção para um determinado local, ele deverá fazer isso para invocar programaticamente ShowContextMenu para Automação da Interface do Usuário suporte também.

Interoperabilidade com o System Caret

O suporte correto ao ponto de inserção é fundamental para muitos aplicativos cliente, incluindo aqueles que não se baseiam em Automação da Interface do Usuário. No padrão de controle Texto , o ponto de inserção é representado por um intervalo de texto degenerado (vazio) na posição do cursor do sistema. Quando o ponto de inserção é movido, um controle deve gerar o evento TextSelectionChanged (UIA_Text_TextSelectionChangedEventId). Alguns aplicativos cliente dependem desse evento para monitorar o local do ponto de inserção e acompanhar a seleção de texto.

Quando um controle contém o texto selecionado, o design atual do padrão de controle Texto não fornece uma maneira de associar diretamente o local do ponto de inserção a um intervalo de texto específico. O provedor deve acompanhar a seleção de texto e definir o local do ponto de inserção adequadamente. Como a seleção de texto normalmente é feita movendo o ponto de inserção enquanto mantém pressionada a tecla SHIFT ou CTRL, ou ambos, um provedor pode acompanhar a seleção de texto verificando o estado dessas chaves sempre que a seleção for alterada.

Como a estrutura de acessibilidade fornece suporte interno para o cursor do sistema, mas não para um cursor personalizado, os controles baseados em texto devem usar o cursor do sistema sempre que possível. Os controles que usam um cursor personalizado podem garantir que o cursor esteja acessível criando um cursor do sistema que tenha as mesmas dimensões que o cursor personalizado e posicionando o cursor do sistema no mesmo local na interface do usuário do controle que o cursor personalizado, ou seja, no ponto de inserção. Como alternativa, um controle que usa um cursor personalizado pode implementar um provedor de Acessibilidade Ativa da Microsoft para OBJID_CARET fornecer informações de acessibilidade diretamente para seu cursor personalizado.

Para obter mais informações sobre o cursor do sistema, consulte Carets.

Para testar se o controle expõe corretamente a localização do cursor do sistema, use as ferramentas Inspecionar e Observador de Eventos Acessíveis .

As coordenadas de tela do centro do bitmap de cursor do sistema sempre devem corresponder ao local do ponto de inserção. Dessa forma, um cliente pode usar as coordenadas da tela de cursor em uma chamada para ITextProvider::RangeFromPoint para recuperar um intervalo de texto que representa com precisão o local do ponto de inserção.

Tipos de controle e seus padrões de controle com suporte

Tipo de controle de texto

Padrão de controle TextEdit

Padrão de controle TextChild

Visão Geral de Padrões de Controle de Automação de Interface de Usuário

suporte Automação da Interface do Usuário para conteúdo textual

Visão geral da árvore de automação de interface do usuário