如何在文字配置上執行點擊測試
提供一個簡短的教學課程,說明如何使用 IDWriteTextLayout 介面,將點擊測試新增至 DirectWrite 應用程式。
本教學課程的結果是一個應用程式,應用程式會以滑鼠左鍵按一下被點選的字元加上底線,如下列螢幕快照所示。
此操作指南包括以下部分:
步驟 1:建立文字配置。
若要開始,您將需要使用 IDWriteTextLayout 物件的應用程式。 如果您已經有使用文字佈局顯示文字的應用程式,請移至步驟 2。
若要新增文字配置,您必須執行下列動作:
將 IDWriteTextLayout 介面的指標 宣告為類別的成員。
IDWriteTextLayout* pTextLayout_;
在 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. ); }
然後,您必須將呼叫 ID2D1RenderTarget::DrawText 方法變更為 ID2D1RenderTarget::DrawTextLayout,如下列程式碼所示。
pRT_->DrawTextLayout( origin, pTextLayout_, pBlackBrush_ );
步驟 2:新增 OnClick 方法。
現在,將方法新增至 類別,以使用文字版面配置的點擊測試功能。
在類別頭檔中宣告 OnClick 方法。
void OnClick( UINT x, UINT y );
在類別實作檔中定義 OnClick 方法。
void DemoApp::OnClick(UINT x, UINT y) { }
步驟 3:執行點擊測試。
若要判斷使用者按下文字配置的位置,我們將使用 IDWriteTextLayout::HitTestPoint 方法。
將下列內容新增至您在步驟 2 中定義的 OnClick 方法。
宣告我們將當做參數傳遞給方法的變數。
DWRITE_HIT_TEST_METRICS hitTestMetrics; BOOL isTrailingHit; BOOL isInside;
HitTestPoint 方法會輸出下列參數。
變數 描述 hitTestMetrics 幾何完整包圍測試位置。 在 裡面 指出點擊測試位置是否在文字字串內。 當 FALSE 時,會傳回最接近文字邊緣的位置。 isTrailingHit 指出命中測試位置是否位於字元的前置側或後置側。 呼叫 IDWriteTextLayout 物件的 HitTestPoint 方法。
pTextLayout_->HitTestPoint( (FLOAT)x, (FLOAT)y, &isTrailingHit, &isInside, &hitTestMetrics );
此範例中的程式代碼會傳遞位置的 x 和 y 變數,而不需要任何修改。 這可以在此範例中完成,因為文字版面配置的大小與視窗相同,而且源自視窗左上角。 如果情況並非如此,您必須確定與文本佈局原點相關的座標。
步驟 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);
}
此程式代碼會執行下列動作。
使用isInside變數檢查測試點是否位於文字內部。
hitTestMetrics 結構的 textPosition 成員包含所按字元從零開始的索引。
將此值傳遞至 IDWriteTextLayout::GetUnderline 方法,以取得這個字元的底線。
宣告 DWRITE_TEXT_RANGE 變數,並將開始位置設定為 hitTestMetrics.textPosition,長度為 1。
使用 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_LPARAM 和 GET_X_LPARAM 宏指令會在 windowsx.h 標頭檔案中宣告。 它們可以輕鬆地擷取滑鼠按兩下的 x 和 y 位置。