テキスト レイアウトでヒット テストを実行する方法
IDWriteTextLayout インターフェイスを使用してテキストを表示するDirectWrite アプリケーションにヒット テストを追加する方法に関する簡単なチュートリアルを提供します。
このチュートリアルの結果は、次のスクリーン ショットに示すように、マウスの左ボタンでクリックされた文字に下線を引くアプリケーションです。
この方法では、次の部分を含めます。
- 手順 1: テキスト レイアウトを作成する。
- 手順 2: OnClick メソッドを追加します。
- 手順 3: ヒット テストを実行する。
- 手順 4: クリックしたテキストに下線を引きます。
- 手順 5: WM_LBUTTONDOWN メッセージを処理します。
手順 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::D rawText メソッドの呼び出 しを ID2D1RenderTarget::D rawTextLayout に変更する必要があります。
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 ヒット テストの場所を完全に囲むジオメトリ。 isInside ヒット テストの場所がテキスト文字列内にあるかどうかを示します。 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 メンバーには、クリックした文字の 0 から始まるインデックスが含まれます。
この値を IDWriteTextLayout::GetUnderline メソッドに渡して、この文字の下線を取得します。
開始位置が hitTestMetrics.textPosition に設定され、長さが 1 のDWRITE_TEXT_RANGE変数を宣言します。
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 位置を簡単に取得できます。