Como executar testes de clique em um layout de texto
Fornece um breve tutorial sobre como adicionar testes de clique a um aplicativo DirectWrite que exibe texto usando a interface IDWriteTextLayout.
O resultado deste tutorial é um aplicativo que sublinha o caractere clicado no botão esquerdo do mouse, conforme mostrado na captura de tela a seguir.
Esta é a maneira de conter as seguintes partes:
- Etapa 1: criar um layout de texto.
- Etapa 2: Adicionar um método OnClick.
- Etapa 3: executar o teste de clique.
- Etapa 4: sublinhar o texto clicado.
- Etapa 5: manipular a mensagem de WM_LBUTTONDOWN.
Etapa 1: criar um layout de texto.
Para começar, você precisará de um aplicativo que use um objeto IDWriteTextLayout . Se você já tiver um aplicativo que exibe texto com um layout de texto, vá para a Etapa 2.
Para adicionar um layout de texto, você deve fazer o seguinte:
Declare um ponteiro para uma interface IDWriteTextLayout como um membro da classe .
IDWriteTextLayout* pTextLayout_;
No final do método CreateDeviceIndependentResources , crie um objeto de interface IDWriteTextLayout chamando o método 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. ); }
Em seguida, você deve alterar a chamada para o método ID2D1RenderTarget::D rawText para ID2D1RenderTarget::D rawTextLayout , conforme mostrado no código a seguir.
pRT_->DrawTextLayout( origin, pTextLayout_, pBlackBrush_ );
Etapa 2: Adicionar um método OnClick.
Agora, adicione um método à classe que usará a funcionalidade de teste de clique do layout de texto.
Declare um método OnClick no arquivo de cabeçalho de classe.
void OnClick( UINT x, UINT y );
Defina um método OnClick no arquivo de implementação de classe.
void DemoApp::OnClick(UINT x, UINT y) { }
Etapa 3: executar o teste de clique.
Para determinar onde o usuário clicou no layout de texto, usaremos o método IDWriteTextLayout::HitTestPoint .
Adicione o seguinte ao método OnClick que você definiu na Etapa 2.
Declare as variáveis que passaremos como parâmetros para o método .
DWRITE_HIT_TEST_METRICS hitTestMetrics; BOOL isTrailingHit; BOOL isInside;
O método HitTestPoint gera os parâmetros a seguir.
Variável Descrição hitTestMetrics A geometria que inclui totalmente o local de teste de ocorrência. isInside Indica se o local de teste de ocorrência está dentro da cadeia de caracteres de texto ou não. Quando FALSE, a posição mais próxima da borda do texto é retornada. isTrailingHit Indica se o local de teste de ocorrência está no lado à esquerda ou à direita do caractere. Chame o método HitTestPoint do objeto IDWriteTextLayout .
pTextLayout_->HitTestPoint( (FLOAT)x, (FLOAT)y, &isTrailingHit, &isInside, &hitTestMetrics );
O código neste exemplo passa as variáveis x e y para a posição sem nenhuma modificação. Isso pode ser feito neste exemplo porque o layout de texto tem o mesmo tamanho que a janela e se origina no canto superior esquerdo da janela. Se esse não fosse o caso, você teria que determinar as coordenadas em relação à origem do layout de texto.
Etapa 4: sublinhar o texto clicado.
Adicione o seguinte ao OnClick que você definiu na Etapa 2, após a chamada para o método HitTestPoint .
if (isInside == TRUE)
{
BOOL underline;
pTextLayout_->GetUnderline(hitTestMetrics.textPosition, &underline);
DWRITE_TEXT_RANGE textRange = {hitTestMetrics.textPosition, 1};
pTextLayout_->SetUnderline(!underline, textRange);
}
Esse código faz o seguinte.
Verifica se o ponto de teste de ocorrência estava dentro do texto usando a variável isInside .
O membro textPosition da estrutura hitTestMetrics contém o índice baseado em zero do caractere clicado.
Obtém o sublinhado para esse caractere passando esse valor para o método IDWriteTextLayout::GetUnderline .
Declara uma variável DWRITE_TEXT_RANGE com a posição inicial definida como hitTestMetrics.textPosition e um comprimento de 1.
Alterna o sublinhado usando o método IDWriteTextLayout::SetUnderline .
Depois de definir o sublinhado, redesenhe o texto chamando o método DrawD2DContent da classe .
DrawD2DContent();
Etapa 5: manipular a mensagem de WM_LBUTTONDOWN.
Por fim, adicione a mensagem WM_LBUTTONDOWN ao manipulador de mensagens do aplicativo e chame o método OnClick da classe .
case WM_LBUTTONDOWN:
{
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
pDemoApp->OnClick(x, y);
}
break;
GET_X_LPARAM e macros GET_X_LPARAM são declaradas no arquivo de cabeçalho windowsx.h. Eles recuperam facilmente a posição x e y do clique do mouse.