Partilhar via


Entrada de texto personalizada

As APIs de texto principais no espaço de nomes Windows.UI.Text.Core permitem que uma aplicação Windows receba entrada de texto de qualquer serviço de texto suportado em dispositivos Windows. As APIs são semelhantes às APIs do Text Services Framework no sentido em que a aplicação não é obrigada a ter conhecimento detalhado dos serviços de texto. Isto permite que a aplicação receba texto em qualquer língua e de qualquer tipo de entrada (como teclado, voz ou caneta).

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

Por que usar APIs de texto essenciais?

Para muitas aplicações, os controlos das caixas de texto XAML ou HTML são suficientes para introdução e edição de texto. No entanto, se a sua aplicação lida com cenários de texto complexos, como uma aplicação de processamento de texto, pode precisar da flexibilidade de um controlo personalizado de edição de texto. Podes usar as APIs de teclado CoreWindow para criar o controlo de edição de texto, mas estas não oferecem uma forma de receber entrada de texto baseada em composição, que é necessária para suportar línguas do Leste Asiático.

Em vez disso, use APIs do Windows.UI.Text.Core quando precisar de criar um controlo personalizado de edição de texto. Estas APIs foram concebidas para lhe dar muita flexibilidade no processamento de introdução de texto, em qualquer linguagem, e permitir-lhe proporcionar a experiência de texto mais adequada à sua aplicação. Os controlos de entrada e edição de texto construídos com as APIs de texto principais podem receber entrada de texto de todos os métodos de introdução de texto existentes em dispositivos Windows, desde Editores de Métodos de Entrada (IMEs) baseados no Framework de Serviços de Texto e escrita manual em PCs até ao teclado WordFlow (que fornece autocorreção, previsão e ditado) em dispositivos móveis.

Architecture

Segue-se uma representação simples do sistema de introdução de texto.

  • "Aplicação" representa uma aplicação Windows que aloja um controlo de edição personalizado construído usando as APIs de texto principais.
  • As APIs Windows.UI.Text.Core facilitam a comunicação com serviços de texto através do Windows. A comunicação entre o controlo de edição de texto e os serviços de texto é tratada principalmente através de um objeto CoreTextEditContext que fornece os métodos e eventos para facilitar a comunicação.

Diagrama de arquitetura CoreText

Intervalos de texto e seleção

Os controlos de edição fornecem espaço para introdução de texto e os utilizadores esperam editar texto em qualquer lugar deste espaço. Aqui, explicamos o sistema de posicionamento do texto utilizado pelas APIs principais de texto e como os intervalos e seleções são representados neste sistema.

Posição do cursor da aplicação

Os intervalos de texto usados com as APIs de texto core são expressos em termos de posições de caret. Uma "Posição do Cursor da Aplicação (ACP)" é um número baseado em zero que indica a contagem de caracteres desde o início do fluxo de texto, imediatamente antes do cursor, como mostrado aqui.

Captura de ecrã a mostrar a contagem de caracteres da posição do cursor da aplicação (ACP)

Intervalos de texto e seleção

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

Campo Tipo de dados Description
StartCaretPosição Número [JavaScript] | System.Int32 [.NET] | int32 [C++] A posição inicial de um intervalo é o ACP imediatamente antes do primeiro caractere.
EndCaretPosição 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 ser sempre menor ou igual à EndCaretPosition. O intervalo [5, 0] é inválido.

Ponto de inserção

A posição atual do caret, frequentemente referida como ponto de inserção, é representada definindo o StartCaretPosition igual ao EndCaretPosition.

Seleção não contígua

Alguns controlos de edição suportam seleções não contíguas. Por exemplo, as aplicações do Microsoft Office suportam múltiplas seleções arbitrárias, e muitos editores de código-fonte suportam seleção de colunas. No entanto, as APIs de texto núcleo não suportam seleções não contíguas. Os controlos de edição devem reportar apenas uma única seleção contígua, sendo na maioria das vezes a sub-gama ativa das seleções não contíguas.

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

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

Trabalhar com texto

A classe CoreTextEditContext permite o fluxo de texto entre o Windows e controlos de edição através do evento TextUpdateing , do evento TextRequested e do método NotifyTextChanged .

O seu controlo de edição recebe texto através de eventos TextUpdating que são gerados quando os utilizadores interagem com métodos de introdução de texto como teclados, voz ou IMEs.

Quando altera texto no seu controlo de edição, por exemplo, ao colar texto no controlo, precisa de notificar o Windows chamando NotifyTextChanged.

Se o serviço de texto exigir o novo texto, um evento TextRequested é gerado. Deve fornecer o novo texto no gestor de eventos TextRequested .

Aceitar atualizações de texto

O controlo de edição deve normalmente aceitar pedidos de atualização de texto porque representam o texto que o utilizador quer inserir. No gestor TextUpdating, estas ações são esperadas do seu controle de edição:

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

Por exemplo, este é o estado de um controlo de edição antes do utilizador escrever "d". O ponto de inserção está em [10, 10].

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

Quando o utilizador escreve "d", é ativado um evento TextUpdating com os seguintes dados CoreTextTextUpdatingEventArgs :

No teu controlo de edição, aplica as alterações especificadas e define Resultado como Bem-sucedido. Aqui está o estado do controlo após a aplicação das alterações.

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

Rejeitar atualizações de texto

Por vezes, não pode aplicar atualizações de texto porque o intervalo solicitado está numa área do controlo de edição que não deve ser alterada. Neste caso, não deve aplicar quaisquer alterações. Em vez disso, notifique o sistema de que a atualização falhou, definindo CoreTextTextUpdatingEventArgs.Result para CoreTextTextUpdatingResult.Failed.

Por exemplo, considere um controlo de edição que aceita apenas um endereço de e-mail. Os espaços devem ser rejeitados porque os endereços de e-mail não podem conter espaços, por isso, quando os eventos TextUpdating forem levantados para a tecla de espaço, deverá simplesmente configurar o Resultado como Falha no seu controlo de edição.

Notificação de alterações de texto

Por vezes, o teu controlo de edição faz alterações ao texto, como quando o texto é colado ou corrigido automaticamente. Nestes casos, deve notificar os serviços de texto destas alterações ligando para o método NotifyTextChanged .

Por exemplo, este é o estado de um controlo de edição antes de o utilizador colar "Mundo". O ponto de inserção está em [6, 6].

Captura de ecrã de um diagrama de fluxo de texto a mostrar o ponto de inserção em [6, 6], antes de uma inserção

O utilizador executa a ação de colar e o controlo de edição após a aplicação das alterações:

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

Quando isto acontecer, deve ligar NotifyTextChanged com estes argumentos:

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

Seguir-se-ão um ou mais eventos TextRequested , que tu geres para atualizar o texto com que os serviços de texto estão a trabalhar.

Sobreposição de atualizações de texto

No seu controlo de edição, pode querer substituir uma atualização de texto para fornecer funcionalidades de correção automática de texto.

Por exemplo, considere um controlo de edição que fornece uma funcionalidade de correção que formaliza as contrações. Este é o estado do controlo de edição antes do utilizador digitar a tecla de espaço para acionar a correção. O ponto de inserção está em [3, 3].

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

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

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

Fora do manipulador de eventos TextUpdating, o controlo de edição faz a seguinte correção. Este é o estado do controlo de edição após a correção estar concluída. O ponto de inserção está em [5, 5].

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

Quando isto acontecer, deve ligar NotifyTextChanged com estes argumentos:

  • modificadoIntervalo = [1, 2]
  • newLength = 2
  • novaSeleção = [5, 5]

Seguir-se-ão um ou mais eventos TextRequested , que tu geres para atualizar o texto com que os serviços de texto estão a trabalhar.

Fornecer texto solicitado

É importante que os serviços de texto tenham o texto correto para fornecer funcionalidades como auto-correção ou previsão, especialmente para texto que já existia no controlo de edição, como o carregamento de um documento, por exemplo, ou texto inserido pelo controlo de edição, como explicado nas secções anteriores. Portanto, sempre que um evento TextRequested for disparado, deve fornecer o texto que está atualmente no seu controlo de edição para o intervalo especificado.

Haverá ocasiões em que o Range no CoreTextTextRequest especifica um intervalo que o seu controlo de edição não pode acomodar como está. Por exemplo, o Intervalo é maior do que o tamanho do controle de edição no momento do evento TextRequested, ou o fim do Intervalo está fora dos limites. Nestes casos, deve devolver o intervalo que fizer sentido, que normalmente é um subconjunto do intervalo solicitado.

Samples

Arquivar amostras