共用方式為


如何在文字配置上執行點擊測試

提供簡短教學課程,說明如何使用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方法會輸出下列參數。

    變數 描述
    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成員包含所按下字元的以零起始的索引。

    將此值傳遞至 IDWriteTextLayout::GetUnderline 方法,以取得這個字元的底線。

  3. 宣告 DWRITE_TEXT_RANGE 變數,並將開始位置設定為 hitTestMetrics.textPosition ,長度為 1。

  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 位置。