다음을 통해 공유


사용자 지정 텍스트 입력

Windows.UI.Text.Core 네임스페이스의 핵심 텍스트 API를 사용하면 Windows 앱이 Windows 디바이스에서 지원되는 모든 텍스트 서비스에서 텍스트 입력을 받을 수 있습니다. API는 앱이 텍스트 서비스에 대한 자세한 정보를 가질 필요가 없다는 점의 Text Services 프레임워크 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 아키텍처 다이어그램

텍스트 범위 및 선택 영역

편집 컨트롤은 텍스트 입력을 위한 공간을 제공하며 사용자는 이 공간의 아무 곳이나 텍스트를 편집해야 합니다. 여기서는 핵심 텍스트 API에서 사용하는 텍스트 위치 지정 시스템과 이 시스템에서 범위 및 선택 영역을 나타내는 방법을 설명합니다.

애플리케이션 캐럿 위치

핵심 텍스트 API와 함께 사용되는 텍스트 범위는 캐리트 위치로 표현됩니다. "ACP(응용 프로그램 캐럿 위치)"는 여기에 표시된 것처럼 텍스트 스트림 시작에서 캐럿 바로 앞까지의 문자 수를 나타내는 0부터 시작하는 숫자입니다.

ACP(Application Caret Position) 문자 수를 보여 주는 스크린샷

텍스트 범위 및 선택 영역

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

분야 데이터 형식 Description
StartCaretPosition 숫자 [JavaScript] | System.Int32 [.NET] | int32 [C++] 범위의 시작 위치는 첫 번째 문자 바로 앞의 ACP입니다.
EndCaretPosition 숫자 [JavaScript] | 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]).

첫 번째 문자와 마지막 5자를 선택하는 연속되지 않은 텍스트 선택을 보여 주는 스크린샷.

텍스트 작업

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

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

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

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

텍스트 업데이트 수락

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

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

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

삽입 전 [10, 10]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

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

삽입 후 \[11, 11\]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

텍스트 업데이트 거부

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

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

텍스트 변경 내용 알림

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

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

삽입 전 [6, 6]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

삽입 후 \[11, 11\]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

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

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

텍스트 업데이트 덮어쓰기

편집 컨트롤에서 텍스트 업데이트를 덮어써서 자동 수정 기능을 제공할 수 있습니다.

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

삽입 전 [3, 3]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

삽입 후 [4, 4]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

[5, 5]의 삽입 지점을 보여 주는 텍스트 스트림 다이어그램의 스크린샷

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

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

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

요청된 텍스트 제공

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

CoreTextTextRequest범위가 편집 컨트롤에서 as-is수용할 수 없는 범위를 지정하는 경우가 있습니다. 예를 들어 범위TextRequested 이벤트 시 편집 컨트롤의 크기보다 크거나 범위 의 끝이 범위를 벗어났습니다. 이러한 경우 일반적으로 요청된 범위의 하위 집합인 적합한 범위를 반환해야 합니다.

Samples

샘플 보관