Выполнение проверки попадания в макет текста
Краткое руководство по добавлению проверки попадания в приложение DirectWrite, которое отображает текст с помощью интерфейса IDWriteTextLayout.
Результатом работы с этим руководством является приложение, которое подчеркивает символ, нажатый левой кнопкой мыши, как показано на следующем снимке экрана.
Этот способ содержит следующие части:
- Шаг 1. Создание макета текста.
- Шаг 2. Добавление метода OnClick.
- Шаг 3. Проверка попадания.
- Шаг 4. Подчеркивание щелкнутого текста.
- Шаг 5. Обработка сообщения WM_LBUTTONDOWN.
Шаг 1. Создание макета текста.
Для начала потребуется приложение, использующее объект IDWriteTextLayout . Если у вас уже есть приложение, отображающее текст с текстовым макетом, перейдите к шагу 2.
Чтобы добавить макет текста, необходимо выполнить следующие действия.
Объявите указатель на интерфейс IDWriteTextLayout в качестве члена класса .
IDWriteTextLayout* pTextLayout_;
В конце метода CreateDeviceIndependentResources создайте объект интерфейса IDWriteTextLayout , вызвав метод CreateTextLayout .
// 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 .
Добавьте следующий код в метод OnClick , определенный на шаге 2.
Объявите переменные, которые мы будем передавать в качестве параметров в метод .
DWRITE_HIT_TEST_METRICS hitTestMetrics; BOOL isTrailingHit; BOOL isInside;
Метод HitTestPoint выводит следующие параметры.
Переменная Описание hitTestMetrics Геометрия, полностью включающая место проверки попадания. isInside Указывает, находится ли расположение проверки попадания внутри текстовой строки. При значении FALSE возвращается позиция, ближайшая к краю текста. isTrailingHit Указывает, находится ли место проверки нажатия на начальной или конечной стороне символа. Вызовите метод HitTestPoint объекта IDWriteTextLayout .
pTextLayout_->HitTestPoint( (FLOAT)x, (FLOAT)y, &isTrailingHit, &isInside, &hitTestMetrics );
Код в этом примере передает переменные x и y для позиции без каких-либо изменений. Это можно сделать в этом примере, так как макет текста имеет тот же размер, что и окно, и находится в левом верхнем углу окна. Если бы это не так, необходимо было бы определить координаты относительно происхождения макета текста.
Шаг 4. Подчеркивание щелкнутого текста.
Добавьте следующий код в onClick , определенный на шаге 2, после вызова метода HitTestPoint .
if (isInside == TRUE)
{
BOOL underline;
pTextLayout_->GetUnderline(hitTestMetrics.textPosition, &underline);
DWRITE_TEXT_RANGE textRange = {hitTestMetrics.textPosition, 1};
pTextLayout_->SetUnderline(!underline, textRange);
}
Этот код выполняет следующие действия.
Проверяет, находилась ли точка проверки попадания внутри текста с помощью переменной isInside .
Элемент textPosition структуры hitTestMetrics содержит отсчитываемый от нуля индекс нажатого символа.
Получает подчеркивание для этого символа путем передачи этого значения в метод 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 щелчка мыши.