Freigeben über


Durchführen von Treffertests für ein Textlayout

Enthält ein kurzes Tutorial zum Hinzufügen von Treffertests zu einer DirectWrite-Anwendung, die Text mithilfe der IDWriteTextLayout-Schnittstelle anzeigt.

Das Ergebnis dieses Tutorials ist eine Anwendung, die das Zeichen unterstreicht, auf das mit der linken Maustaste geklickt wird, wie im folgenden Screenshot gezeigt.

Screenshot von

Diese Vorgehensweise enthält die folgenden Teile:

Schritt 1: Erstellen eines Textlayouts.

Zunächst benötigen Sie eine Anwendung, die ein IDWriteTextLayout-Objekt verwendet. Wenn Sie bereits über eine Anwendung verfügen, die Text mit einem Textlayout anzeigt, fahren Sie mit Schritt 2 fort.

Um ein Textlayout hinzuzufügen, müssen Sie die folgenden Schritte ausführen:

  1. Deklarieren Sie einen Zeiger auf eine IDWriteTextLayout-Schnittstelle als Member der -Klasse.

    IDWriteTextLayout* pTextLayout_;
    
  2. Erstellen Sie am Ende der CreateDeviceIndependentResources-Methode ein IDWriteTextLayout-Schnittstellenobjekt , indem Sie die CreateTextLayout-Methode aufrufen.

    // 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. Anschließend müssen Sie den Aufruf der ID2D1RenderTarget::D rawText-Methode in ID2D1RenderTarget::D rawTextLayout ändern, wie im folgenden Code gezeigt.

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

Schritt 2: Hinzufügen einer OnClick-Methode.

Fügen Sie nun der -Klasse eine Methode hinzu, die die Treffertestfunktion des Textlayouts verwendet.

  1. Deklarieren Sie eine OnClick-Methode in der Klassenheaderdatei.

    void OnClick(
        UINT x,
        UINT y
        );
    
  2. Definieren Sie eine OnClick-Methode in der Klassenimplementierungsdatei.

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

Schritt 3: Führen Sie Treffertests durch.

Um zu bestimmen, wo der Benutzer auf das Textlayout geklickt hat, verwenden wir die IDWriteTextLayout::HitTestPoint-Methode .

Fügen Sie der OnClick-Methode , die Sie in Schritt 2 definiert haben, Folgendes hinzu.

  1. Deklarieren Sie die Variablen, die als Parameter an die -Methode übergeben werden.

    DWRITE_HIT_TEST_METRICS hitTestMetrics;
    BOOL isTrailingHit;
    BOOL isInside; 
    

    Die HitTestPoint-Methode gibt die folgenden Parameter aus.

    Variable BESCHREIBUNG
    hitTestMetrics Die Geometrie, die den Treffertestort vollständig umschließt.
    isInside Gibt an, ob sich die Treffertestposition in der Textzeichenfolge befindet oder nicht. Bei FALSE wird die position zurückgegeben, die dem Rand des Texts am nächsten ist.
    isTrailingHit Gibt an, ob sich die Treffertestposition an der führenden oder hinteren Seite des Zeichens befindet.
  2. Rufen Sie die HitTestPoint-Methode des IDWriteTextLayout-Objekts auf.

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

    Der Code in diesem Beispiel übergibt die Variablen x und y für die Position ohne Änderungen. Dies kann in diesem Beispiel geschehen, da das Textlayout dieselbe Größe wie das Fenster hat und aus der oberen linken Ecke des Fensters stammt. Wenn dies nicht der Fall wäre, müssten Sie die Koordinaten in Bezug auf den Ursprung des Textlayouts bestimmen.

Schritt 4: Unterstreichen Sie den angeklickten Text.

Fügen Sie dem in Schritt 2 definierten OnClick nach dem Aufruf der HitTestPoint-Methode Folgendes hinzu.

if (isInside == TRUE)
{
    BOOL underline;

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

    DWRITE_TEXT_RANGE textRange = {hitTestMetrics.textPosition, 1};

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

Dieser Code führt folgendes aus.

  1. Überprüft mithilfe der Variablen isInside , ob sich der Treffertestpunkt im Text befand.

  2. Das textPosition-Element der hitTestMetrics-Struktur enthält den nullbasierten Index des angeklickten Zeichens.

    Ruft die Unterstreichung für dieses Zeichen ab, indem dieser Wert an die IDWriteTextLayout::GetUnderline-Methode übergeben wird.

  3. Deklariert eine DWRITE_TEXT_RANGE Variable, deren Startposition auf hitTestMetrics.textPosition und eine Länge von 1 festgelegt ist.

  4. Schaltet die Unterstriche mithilfe der IDWriteTextLayout::SetUnderline-Methode um.

Nachdem Sie die Unterstreichung festgelegt haben, zeichnen Sie den Text neu, indem Sie die DrawD2DContent-Methode der -Klasse aufrufen.

DrawD2DContent();

Schritt 5: Behandeln sie die WM_LBUTTONDOWN Nachricht.

Fügen Sie schließlich die WM_LBUTTONDOWN Nachricht zum Nachrichtenhandler für Ihre Anwendung hinzu, und rufen Sie die OnClick-Methode der -Klasse auf.

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

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

GET_X_LPARAM und GET_X_LPARAM Makros werden in der Headerdatei windowsx.h deklariert. Sie können problemlos die x- und y-Position des Mausklicks abrufen.