다음을 통해 공유


텍스트 레이아웃에서 적중 테스트를 수행하는 방법

IDWriteTextLayout 인터페이스를 사용하여 텍스트를 표시하는 DirectWrite 애플리케이션에 적중 테스트를 추가하는 방법에 대한 간단한 자습서를 제공합니다.

이 자습서의 결과는 다음 스크린샷과 같이 마우스 왼쪽 단추로 클릭하는 문자에 밑줄을 긋는 애플리케이션입니다.

이 방법에는 다음 부분이 포함됩니다.

1단계: 텍스트 레이아웃 만들기

시작하려면 IDWriteTextLayout 개체를 사용하는 애플리케이션이 필요합니다. 텍스트 레이아웃이 있는 텍스트를 표시하는 애플리케이션이 이미 있는 경우 2단계로 이동합니다.

텍스트 레이아웃을 추가하려면 다음을 수행해야 합니다.

  1. IDWriteTextLayout 인터페이스에 대한 포인터를 클래스의 멤버로 선언합니다.

    IDWriteTextLayout* pTextLayout_;
    
  2. CreateDeviceIndependentResources 메서드의 끝에서 CreateTextLayout 메서드를 호출하여 IDWriteTextLayout 인터페이스 개체를 만듭니다.

    // Create a text layout using the text format.
    if (SUCCEEDED(hr))
    {
        RECT rect;
        GetClientRect(hwnd_, &rect); 
        float width  = rect.right  / dpiScaleX_;
        float height = rect.bottom / dpiScaleY_;
    
        hr = pDWriteFactory_->CreateTextLayout(
            wszText_,      // The string to be laid out and formatted.
            cTextLength_,  // The length of the string.
            pTextFormat_,  // The text format to apply to the string (contains font information, etc).
            width,         // The width of the layout box.
            height,        // The height of the layout box.
            &pTextLayout_  // The IDWriteTextLayout interface pointer.
            );
    }
    
  3. 그런 다음, 다음 코드와 같이 ID2D1RenderTarget::D rawText 메서드에 대한 호출을 ID2D1RenderTarget::D rawTextLayout 으로 변경해야 합니다.

    pRT_->DrawTextLayout(
        origin,
        pTextLayout_,
        pBlackBrush_
        );
    

2단계: OnClick 메서드를 추가합니다.

이제 텍스트 레이아웃의 적중 횟수 테스트 기능을 사용할 메서드를 클래스에 추가합니다.

  1. 클래스 헤더 파일에서 OnClick 메서드를 선언합니다.

    void OnClick(
        UINT x,
        UINT y
        );
    
  2. 클래스 구현 파일에서 OnClick 메서드를 정의합니다.

     void DemoApp::OnClick(UINT x, UINT y)
     {    
     }
    

3단계: 적중 테스트를 수행합니다.

사용자가 텍스트 레이아웃을 클릭한 위치를 확인하려면 IDWriteTextLayout::HitTestPoint 메서드를 사용합니다.

2단계에서 정의한 OnClick 메서드에 다음을 추가합니다.

  1. 메서드에 매개 변수로 전달할 변수를 선언합니다.

    DWRITE_HIT_TEST_METRICS hitTestMetrics;
    BOOL isTrailingHit;
    BOOL isInside; 
    

    HitTestPoint 메서드는 다음 매개 변수를 출력합니다.

    변수 Description
    hitTestMetrics 적중 테스트 위치를 완전히 둘러싸는 기하 도형입니다.
    isInside 적중 테스트 위치가 텍스트 문자열 내에 있는지 여부를 나타냅니다. FALSE이면 텍스트 가장자리와 가장 가까운 위치가 반환됩니다.
    isTrailingHit 적중 테스트 위치가 문자의 선행 또는 후행 쪽에 있는지 여부를 나타냅니다.
  2. IDWriteTextLayout 개체의 HitTestPoint 메서드를 호출합니다.

    pTextLayout_->HitTestPoint(
                    (FLOAT)x, 
                    (FLOAT)y,
                    &isTrailingHit,
                    &isInside,
                    &hitTestMetrics
                    );
    

    이 예제의 코드는 수정 없이 위치에 대한 xy 변수를 전달합니다. 이 예제에서는 텍스트 레이아웃이 창과 크기가 같고 창의 왼쪽 위 모서리에서 시작되므로 이 작업을 수행할 수 있습니다. 그렇지 않은 경우 텍스트 레이아웃의 원점과 관련하여 좌표를 결정해야 합니다.

4단계: 클릭한 텍스트에 밑줄을 긋습니다.

HitTestPoint 메서드를 호출한 후 2단계에서 정의한 OnClick에 다음을 추가합니다.

if (isInside == TRUE)
{
    BOOL underline;

    pTextLayout_->GetUnderline(hitTestMetrics.textPosition, &underline);

    DWRITE_TEXT_RANGE textRange = {hitTestMetrics.textPosition, 1};

    pTextLayout_->SetUnderline(!underline, textRange);
}

이 코드는 다음을 수행합니다.

  1. isInside 변수를 사용하여 적중 테스트 지점이 텍스트 내에 있는지 확인합니다.

  2. hitTestMetrics 구조체의 textPosition 멤버에는 클릭한 문자의 인덱스(0부터 시작)가 포함됩니다.

    이 값을 IDWriteTextLayout::GetUnderline 메서드에 전달하여 이 문자의 밑줄을 가져옵니다.

  3. 시작 위치가 hitTestMetrics.textPosition으로 설정되고 길이가 1인 DWRITE_TEXT_RANGE 변수를 선언합니다.

  4. IDWriteTextLayout::SetUnderline 메서드를 사용하여 밑줄을 전환합니다.

밑줄을 설정한 후 클래스의 DrawD2DContent 메서드를 호출하여 텍스트를 다시 그립니다.

DrawD2DContent();

5단계: WM_LBUTTONDOWN 메시지를 처리합니다.

마지막으로 애플리케이션의 메시지 처리기에 WM_LBUTTONDOWN 메시지를 추가하고 클래스의 OnClick 메서드를 호출합니다.

case WM_LBUTTONDOWN:
    {
        int x = GET_X_LPARAM(lParam); 
        int y = GET_Y_LPARAM(lParam);

        pDemoApp->OnClick(x, y);
    }
    break;

GET_X_LPARAMGET_X_LPARAM 매크로는 windowsx.h 헤더 파일에 선언됩니다. 마우스 클릭의 x 및 y 위치를 쉽게 검색합니다.