사용자 지정 텍스트 입력

Windows.UI.Text.Core 네임스페이스의 코어 텍스트 API를 통해 Windows 앱은 Windows 디바이스에서 지원되는 모든 텍스트 서비스에서 텍스트 입력을 받을 수 있습니다. API는 앱이 텍스트 서비스에 대한 자세한 정보를 가질 필요가 없다는 점에서 Text Services Framework API와 유사합니다. 이렇게 하면 앱이 키보드, 음성 또는 펜과 같은 모든 입력 형식에서 모든 언어로 텍스트를 받을 수 있습니다.

중요 API: Windows.UI.Text.Core, CoreTextEditContext

왜 핵심 텍스트 API를 사용하나요?

대부분의 앱은 XAML 또는 HTML 텍스트 상자 컨트롤로 텍스트 입력 및 편집을 충분히 할 수 있습니다. 그러나 앱이 단어 처리 앱과 같은 복잡한 텍스트 시나리오를 처리하는 경우 사용자 지정 텍스트 편집 컨트롤의 유연성이 필요할 수 있습니다. CoreWindow 키보드 API를 사용하여 텍스트 편집 컨트롤을 만들 수 있지만, 이는 동아시아 언어를 지원하는 데 필요한 컴퍼지션 기반 텍스트 입력을 수신하는 방법을 제공하지 않습니다.

사용자 지정 텍스트 편집 컨트롤을 만들어야 하는 경우에는 Windows.UI.Text.Core API를 사용합니다. 이러한 API는 모든 언어로 텍스트 입력을 처리할 수 있는 큰 유연성을 제공하고 앱에 가장 적합한 텍스트 환경을 제공할 수 있도록 설계되었습니다. 핵심 텍스트 API를 사용하여 빌드된 텍스트 입력 및 편집 컨트롤은 Windows 디바이스의 모든 기존 텍스트 입력 방법, Text Services Framework 기반 IME(입력 방법 편집기) 및 PC의 필기에서 모바일 디바이스의 WordFlow 키보드(자동 수정, 예측 및 받아쓰기 제공)에 이르기까지 텍스트 입력을 받을 수 있습니다.

아키텍처

다음은 텍스트 입력 시스템을 간단하게 표현한 것입니다.

  • "애플리케이션"은 코어 텍스트 API를 사용하여 작성된 사용자 지정 편집 컨트롤을 호스트하는 Windows 앱을 나타냅니다.
  • Windows.UI.Text.Core API는 Windows를 통한 텍스트 서비스와의 통신을 용이하게 합니다. 텍스트 편집 컨트롤과 텍스트 서비스 간의 통신은 통신을 용이하게 하는 메서드와 이벤트를 제공하는 CoreTextEditContext 개체를 통해 주로 처리됩니다.

CoreText architecture diagram

텍스트 범위 및 선택 영역

편집 컨트롤은 텍스트 입력 공간을 제공하며 사용자는 이 공간 어디서나 텍스트를 편집하게 됩니다. 여기서는 핵심 텍스트 API에서 사용하는 텍스트 위치 지정 시스템과 이 시스템에서 범위 및 선택 영역이 어떻게 표현되는지 설명합니다.

애플리케이션 캐럿 위치

핵심 텍스트 API와 함께 사용되는 텍스트 범위는 캐럿 위치로 표현됩니다. "ACP(Application Caret Position)"는 여기에 표시된 것처럼 캐럿 직전 텍스트 스트림 시작 앞의 문자 수를 나타내는 0부터 시작하는 숫자입니다.

Screenshot showing the Application Caret Position (ACP) count of characters

텍스트 범위 및 선택 영역

텍스트 범위와 선택 영역은 두 개의 필드가 포함된 CoreTextRange 구조로 표현됩니다.

필드 데이터 형식 설명
StartCaretPosition 숫자 [Java스크립트] | System.Int32 [.NET] | int32 [C++] 범위의 시작 위치는 첫 번째 문자 직전의 ACP입니다.
EndCaretPosition 숫자 [Java스크립트] | System.Int32 [.NET] | int32 [C++] 범위의 끝 위치는 마지막 문자 바로 뒤의 ACP입니다.

 

예를 들어 앞에서 표시된 텍스트 범위에서 범위 [0, 5]는 단어 "Hello"를 지정합니다. StartCaretPosition은 항상 EndCaretPosition 이하여야 합니다. 범위 [5, 0]은 잘못되었습니다.

삽입 지점

삽입 지점이라고도 하는 현재 캐럿 위치는 StartCaretPositionEndCaretPosition과 같게 설정하여 표현합니다.

불연속 선택

일부 편집 컨트롤은 불연속 선택을 지원합니다. 예를 들어, Microsoft Office 앱은 여러 개의 임의 선택을 지원하며, 대부분의 소스 코드 편집기에서 열 선택을 지원합니다. 그러나 코어 텍스트 API는 비연속 선택을 지원하지 않습니다. 편집 컨트롤은 인접하지 않은 선택 영역의 활성 하위 범위인 단일 연속 선택 영역만 보고해야 합니다.

예를 들어 다음 이미지는 [0, 1] 및 [6, 11] 두 개의 비연속 선택 항목이 있는 텍스트 스트림을 보여 줍니다. 여기서 편집 컨트롤은 하나만 보고해야 합니다([0, 1] 또는 [6, 11] ).

Screenshot showing a non-contiguous text selection, where the first character and the last five characters are selected.

텍스트 작업

CoreTextEditContext 클래스를 사용하면 TextUpdating 이벤트, TextRequested 이벤트 및 NotifyTextChanged 메서드를 통해 편집 컨트롤과 Windows 간의 텍스트 흐름을 사용할 수 있습니다.

편집 컨트롤은 사용자가 키보드, 음성 또는 IME와 같은 텍스트 입력 메서드와 상호 작용할 때 생성되는 TextUpdating 이벤트를 통해 텍스트를 받습니다.

예를 들어, 텍스트를 컨트롤에 붙여넣어 편집 컨트롤의 텍스트를 변경하면 NotifyTextChanged를 호출하여 Windows에 알려야 합니다.

텍스트 서비스에 새 텍스트 가 필요한 경우 TextRequested 이벤트가 발생합니다. TextRequested 이벤트 처리기에서 새 텍스트를 제공해야 합니다.

텍스트 업데이트 수락

편집 컨트롤은 사용자가 입력하려는 텍스트를 표현하므로 일반적으로 텍스트 업데이트 요청을 수락해야 합니다. TextUpdating 이벤트 처리기에서는 편집 컨트롤에 다음 작업이 필요합니다.

  1. CoreTextTextUpdatingEventArgs.Text에서 지정된 텍스트를 CoreTextTextUpdatingEventArgs.Range에서 지정된 위치에 삽입합니다.
  2. CoreTextTextUpdatingEventArgs.NewSelection에 지정된 위치에 선택 영역을 배치합니다.
  3. CoreTextTextUpdatingEventArgs.ResultCoreTextTextUpdatingResult.Succeeded로 설정하여 업데이트에 성공했음을 시스템에 알립니다.

예를 들어, 이것은 사용자가 "d"를 입력하기 전 편집 컨트롤의 상태입니다. 삽입 지점은 [10, 10]에 있습니다.

Screenshot of a text stream diagram showing the insertion point at [10, 10], before an insertion

사용자가 "d"를 입력하면 다음 CoreTextTextUpdatingEventArgs 데이터와 함께 TextUpdating가 이벤트가 발생합니다.

편집 컨트롤에서 지정된 변경 내용을 적용하고 결과성공으로 설정합니다. 다음은 변경 내용이 적용된 후의 컨트롤 상태입니다.

Screenshot of a text stream diagram showing the insertion point at \[11, 11\], after an insertion

텍스트 업데이트 거부

요청된 범위가 변경해서는 안 되는 편집 컨트롤의 영역에 있어 텍스트 업데이트를 적용할 수 없는 경우가 있습니다. 이 경우에는 변경 내용을 적용하면 안 됩니다. 그 대신 CoreTextTextUpdatingEventArgs.ResultCoreTextTextUpdatingResult.Failed로 설정하여 업데이트에 실패했음을 시스템에 알립니다.

예를 들어, 이메일 주소만 허용하는 편집 컨트롤을 생각해보세요. 이메일 주소에 공백이 포함될 수 없어 공백을 거부해야 하므로 공백 키에 TextUpdating 이벤트가 발생하면 편집 컨트롤에서 결과실패로 설정해야 합니다.

텍스트 변경 내용 알림

편집 컨트롤이 텍스트를 붙여넣거나 자동 수정하는 경우와 같이 텍스트를 변경할 때가 간혹 있습니다. 이런 경우에는 NotifyTextChanged 메서드를 호출하여 텍스트 서비스에 이러한 변경 내용을 알려야 합니다.

예를 들어, 이것은 사용자가 "World"를 붙여넣기 전의 편집 컨트롤 상태입니다. 삽입 지점은 [6, 6]에 있습니다.

Screenshot of a text stream diagram showing the insertion point at [6, 6], before an insertion

사용자는 변경 내용이 적용된 후 붙여넣기 작업과 편집 컨트롤을 수행합니다.

Screenshot of a text stream diagram showing the insertion point at \[11, 11\], after an insertion

이 경우 다음 인수를 사용하여 NotifyTextChanged를 호출해야 합니다.

  • modifiedRange = [6, 6]
  • newLength = 5
  • newSelection = [11, 11]

하나 이상의 TextRequested 이벤트가 뒤따르는데 이는 텍스트 서비스에서 작업하는 텍스트를 업데이트하기 위해 처리하는 것입니다.

텍스트 업데이트 재정의

편집 컨트롤에서 텍스트 업데이트를 재정의하여 자동 수정 기능을 제공해야 할 것입니다.

예를 들어, 수축을 공식화하는 수정 기능을 제공하는 편집 컨트롤을 생각해보세요. 이것은 사용자가 수정을 트리거할 공백 키를 입력하기 전의 편집 컨트롤 상태입니다. 삽입 지점은 [3, 3]에 있습니다.

Screenshot of a text stream diagram showing the insertion point at [3, 3], before an insertion

사용자가 스페이스 키를 누르면 해당하는 TextUpdating 이벤트가 발생합니다. 편집 컨트롤은 텍스트 업데이트를 허용합니다. 이것은 수정이 완료되기 전 잠시 동안 편집 컨트롤의 상태입니다. 삽입 지점은 [4, 4]에 있습니다.

Screenshot of a text stream diagram showing the insertion point at [4, 4], after an insertion

TextUpdating 이벤트 처리기 외부에서 edit 컨트롤은 다음과 같이 수정합니다. 이것은 수정이 완료된 후 편집 컨트롤의 상태입니다. 삽입 지점은 [5, 5]에 있습니다.

Screenshot of a text stream diagram showing the insertion point at [5, 5]

이 경우 다음 인수를 사용하여 NotifyTextChanged를 호출해야 합니다.

  • modifiedRange = [1, 2]
  • newLength = 2
  • newSelection = [5, 5]

하나 이상의 TextRequested 이벤트가 뒤따르는데 이는 텍스트 서비스에서 작업하는 텍스트를 업데이트하기 위해 처리하는 것입니다.

요청된 텍스트 제공

텍스트 서비스에는 자동 수정 또는 예측 같은 기능을 제공하는 올바른 텍스트가 있어야 하는데, 특히 문서 로드의 편집 컨트롤에 이미 있는 텍스트 또는 이전 섹션에서 설명한 대로 편집 컨트롤이 삽입하는 텍스트가 있어야 합니다. 따라서 TextRequested 이벤트가 발생할 때마다 지정된 범위에 대한 편집 컨트롤에 현재 텍스트를 제공해야 합니다.

CoreTextTextRequest범위가 편집 컨트롤에서 그대로 수용할 수 없는 범위를 지정하는 경우가 있습니다. 예를 들어, TextRequested 이벤트 시점에 범위가 편집 컨트롤의 크기보다 크거나 범위의 끝이 경계를 벗어납니다. 이러한 경우 적합한 모든 범위를 반환해야 하는데 이는 일반적으로 요청된 범위의 하위 집합입니다.

샘플

보관 샘플