Compartilhar via


Entrada de texto personalizado

As APIs de texto principais no namespace Windows.UI.Text.Core permitem que um aplicativo Windows receba entrada de texto de qualquer serviço de texto com suporte em dispositivos Windows. As APIs são semelhantes às APIs da Estrutura de Serviços de Texto, pois o aplicativo não precisa ter conhecimento detalhado dos serviços de texto. Isso permite que o aplicativo receba texto em qualquer idioma e de qualquer tipo de entrada, como teclado, fala ou caneta.

APIs importantes: Windows.UI.Text.Core, CoreTextEditContext

Por que usar APIs de texto principais?

Para muitos aplicativos, os controles de caixa de texto XAML ou HTML são suficientes para entrada e edição de texto. No entanto, se seu aplicativo lida com cenários de texto complexos, como um aplicativo de processamento de texto, talvez você precise da flexibilidade de um controle de edição de texto personalizado. Você pode usar as APIs de teclado CoreWindow para criar seu controle de edição de texto, mas elas não fornecem uma maneira de receber entrada de texto baseada em composição, que é necessária para dar suporte a idiomas do Leste Asiático.

Em vez disso, use as APIs Windows.UI.Text.Core quando precisar criar um controle de edição de texto personalizado. Essas APIs foram projetadas para oferecer muita flexibilidade no processamento de entrada de texto, em qualquer idioma, e permitir que você forneça a experiência de texto mais adequada ao seu aplicativo. Os controles de entrada e edição de texto criados com as APIs de texto principais podem receber entrada de texto de todos os métodos de entrada de texto existentes em dispositivos Windows, desde IMEs (Editores de Método de Entrada) baseados na Estrutura de Serviços de Texto e manuscrito em PCs até o teclado WordFlow (que fornece correção automática, previsão e ditado) em dispositivos móveis.

Arquitetura

A seguir está uma representação simples do sistema de entrada de texto.

  • "Aplicativo" representa um aplicativo do Windows que hospeda um controle de edição personalizado criado usando as APIs de texto principais.
  • As APIs Windows.UI.Text.Core facilitam a comunicação com serviços de texto por meio do Windows. A comunicação entre o controle de edição de texto e os serviços de texto é tratada principalmente por meio de um objeto CoreTextEditContext que fornece os métodos e eventos para facilitar a comunicação.

Diagrama de arquitetura do CoreText

Intervalos e seleção de texto

Os controles de edição fornecem espaço para entrada de texto e os usuários esperam editar o texto em qualquer lugar nesse espaço. Aqui, explicamos o sistema de posicionamento de texto usado pelas APIs de texto principais e como os intervalos e seleções são representados nesse sistema.

Posição do cursor do aplicativo

Os intervalos de texto usados com as APIs de texto principais são expressos em termos de posições de cursor. Um "ACP (Application Caret Position)" é um número baseado em zero que indica a contagem de caracteres desde o início do fluxo de texto imediatamente antes do cursor, conforme mostrado aqui.

Captura de tela mostrando a contagem de caracteres da ACP (Posição do Cursor do Aplicativo)

Intervalos e seleção de texto

Os intervalos e seleções de texto são representados pela estrutura CoreTextRange que contém dois campos:

Campo Tipo de dados Descrição
StartCaretPosition Número [JavaScript] | System.Int32 [.NET] | int32 [C++] A posição inicial de um intervalo é o ACP imediatamente antes do primeiro caractere.
EndCaretPosition Número [JavaScript] | System.Int32 [.NET] | int32 [C++] A posição final de um intervalo é o ACP imediatamente após o último caractere.

 

Por exemplo, no intervalo de texto mostrado anteriormente, o intervalo [0, 5] especifica a palavra "Olá". StartCaretPosition deve sempre ser menor ou igual a EndCaretPosition. O intervalo [5, 0] é inválido.

Ponto de inserção

A posição atual do cursor, freqüentemente chamada de ponto de inserção, é representada pela definição de StartCaretPosition para ser igual a EndCaretPosition.

Seleção não contígua

Alguns controles de edição dão suporte a seleções não contíguas. Por exemplo, os aplicativos do Microsoft Office dão suporte a várias seleções arbitrárias e muitos editores de código-fonte dão suporte à seleção de colunas. No entanto, as APIs de texto principais não dão suporte a seleções não contíguas. Os controles de edição devem relatar apenas uma única seleção contígua, na maioria das vezes o subintervalo ativo das seleções não contíguas.

Por exemplo, a imagem a seguir mostra um fluxo de texto com duas seleções não contíguas: [0, 1] e [6, 11] para as quais o controle de edição deve relatar apenas uma ([0, 1] ou [6, 11]).

Captura de tela mostrando uma seleção de texto não contígua, onde o primeiro caractere e os últimos cinco caracteres são selecionados.

Trabalhando com texto

A classe CoreTextEditContext permite o fluxo de texto entre Windows e controles de edição por meio do evento TextUpdating , do evento TextRequested e do método NotifyTextChanged .

Seu controle de edição recebe texto por meio de eventos TextUpdating que são gerados quando os usuários interagem com métodos de entrada de texto, como teclados, fala ou IMEs.

Quando você altera o texto em seu controle de edição, por exemplo, colando texto no controle, você precisa notificar o Windows chamando NotifyTextChanged.

Se o serviço de texto exigir o novo texto, um evento TextRequested será gerado. Você deve fornecer o novo texto no manipulador de eventos TextRequested .

Aceitando atualizações de texto

Seu controle de edição normalmente deve aceitar solicitações de atualização de texto porque elas representam o texto que o usuário deseja inserir. No manipulador de eventos TextUpdating , essas ações são esperadas do seu controle de edição:

  1. Insira o texto especificado em CoreTextTextUpdatingEventArgs.Text na posição especificada em CoreTextTextUpdatingEventArgs.Range.
  2. Coloque a seleção na posição especificada em CoreTextTextUpdatingEventArgs.NewSelection.
  3. Notifique o sistema de que a atualização foi bem-sucedida definindo CoreTextTextUpdatingEventArgs.Result como CoreTextTextUpdatingResult.Succeeded.

Por exemplo, esse é o estado de um controle de edição antes que o usuário digite "d". O ponto de inserção está em [10, 10].

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em [10, 10], antes de uma inserção

Quando o usuário digita "d", um evento de userupdating é gerado com os seguintes dados de CoreTextTextUpdatingEventArgs :

No controle de edição, aplique as alterações especificadas e defina Resultado como Bem-sucedido. Aqui está o estado do controle depois que as alterações são aplicadas.

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em \[11, 11\], após uma inserção

Rejeitando atualizações de texto

Às vezes, você não pode aplicar atualizações de texto porque o intervalo solicitado está em uma área do controle de edição que não deve ser alterada. Nesse caso, você não deve aplicar nenhuma alteração. Em vez disso, notifique o sistema de que a atualização falhou definindo CoreTextTextUpdatingEventArgs.Result como CoreTextTextUpdatingResult.Failed.

Por exemplo, considere um controle de edição que aceita apenas um endereço de email. Os espaços devem ser rejeitados porque os endereços de email não podem conter espaços, portanto, quando os eventos TextUpdating são gerados para a chave de espaço, você deve simplesmente definir Result como Failed em seu controle de edição.

Notificando alterações de texto

Às vezes, seu controle de edição faz alterações no texto, como quando o texto é colado ou corrigido automaticamente. Nesses casos, você deve notificar os serviços de texto sobre essas alterações chamando o método NotifyTextChanged.

Por exemplo, esse é o estado de um controle de edição antes que o usuário cole "Mundo". O ponto de inserção está em [6, 6].

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em [6, 6], antes de uma inserção

O usuário executa a ação de colar e o controle de edição depois que as alterações são aplicadas:

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em \[11, 11\], após uma inserção

Quando isso acontecer, você deverá chamar NotifyTextChanged com estes argumentos:

  • intervaloModificado = [6, 6]
  • novoComprimento = 5
  • novaSeleção = [11, 11]

Um ou mais eventos TextRequested serão seguidos, que você manipula para atualizar o texto com o qual os serviços de texto estão trabalhando.

Substituindo atualizações de texto

Em seu controle de edição, talvez você queira substituir uma atualização de texto para fornecer recursos de correção automática.

Por exemplo, considere um controle de edição que fornece um recurso de correção que formaliza contrações. Esse é o estado do controle de edição antes que o usuário digite a tecla de espaço para disparar a correção. O ponto de inserção está em [3, 3].

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em [3, 3], antes de uma inserção

O usuário pressiona a tecla de espaço e um evento TextUpdating correspondente é gerado. O controle de edição aceita a atualização de texto. Esse é o estado do controle de edição por um breve momento antes que a correção seja concluída. O ponto de inserção está em [4, 4].

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em [4, 4], após uma inserção

Fora do manipulador de eventos TextUpdating , o controle de edição faz a seguinte correção. Esse é o estado do controle de edição após a conclusão da correção. O ponto de inserção está em [5, 5].

Captura de tela de um diagrama de fluxo de texto mostrando o ponto de inserção em [5, 5]

Quando isso acontecer, você deverá chamar NotifyTextChanged com estes argumentos:

  • intervaloModificado = [1, 2]
  • novoComprimento = 2
  • novaSeleção = [5, 5]

Um ou mais eventos TextRequested serão seguidos, que você manipula para atualizar o texto com o qual os serviços de texto estão trabalhando.

Fornecendo o texto solicitado

É importante que os serviços de texto tenham o texto correto para fornecer recursos como correção automática ou previsão, especialmente para texto que já existia no controle de edição, do carregamento de um documento, por exemplo, ou texto inserido pelo controle de edição, conforme explicado nas seções anteriores. Portanto, sempre que um evento TextRequested for gerado, você deverá fornecer o texto atualmente em seu controle de edição para o intervalo especificado.

Haverá vezes em que o Range em CoreTextTextRequest especificará um intervalo que o controle de edição não poderá acomodar como está. Por exemplo, o Range é maior do que o tamanho do controle de edição no momento do evento TextRequested ou o final do Range está fora dos limites. Nesses casos, você deve retornar qualquer intervalo que faça sentido, que normalmente é um subconjunto do intervalo solicitado.

Amostras

Exemplos de arquivos