Quando o mouse se move, o Windows posta uma mensagem WM_MOUSEMOVE . Por padrão, WM_MOUSEMOVE vai para a janela que contém o cursor. Você pode substituir esse comportamento capturando o mouse, que é descrito na próxima seção.
A mensagem WM_MOUSEMOVE contém os mesmos parâmetros que as mensagens para cliques do mouse. Os 16 bits mais baixos de lParam contêm a coordenada x e os próximos 16 bits contêm a coordenada y. Use as macros GET_X_LPARAM e GET_Y_LPARAM para desempacotar as coordenadas do lParam. O parâmetro wParam contém um OR bit a bit de sinalizadores, indicando o estado dos outros botões do mouse mais as teclas SHIFT e CTRL. O código a seguir obtém as coordenadas do mouse do lParam.
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
Lembre-se de que essas coordenadas estão em pixels, não em DIPs (pixels independentes de dispositivo). Posteriormente neste tópico, examinaremos o código que converte entre as duas unidades.
Uma janela também poderá receber uma mensagem WM_MOUSEMOVE se a posição do cursor for alterada em relação à janela. Por exemplo, se o cursor estiver posicionado sobre uma janela e o usuário ocultar a janela, a janela receberá WM_MOUSEMOVE mensagens mesmo que o mouse não tenha se movido. Uma consequência desse comportamento é que as coordenadas do mouse podem não mudar entre mensagens WM_MOUSEMOVE .
Capturando o movimento do mouse fora da janela
Por padrão, uma janela para de receber mensagens WM_MOUSEMOVE se o mouse passar pela borda da área do cliente. Mas, para algumas operações, talvez seja necessário rastrear a posição do mouse além desse ponto. Por exemplo, um programa de desenho pode permitir que o usuário arraste o retângulo de seleção para além da borda da janela, conforme mostrado no diagrama a seguir.
Para receber mensagens de movimentação do mouse além da borda da janela, chame a função SetCapture . Depois que essa função for chamada, a janela continuará recebendo WM_MOUSEMOVE mensagens, desde que o usuário mantenha pelo menos um botão do mouse para baixo, mesmo que o mouse se mova para fora da janela. A janela de captura deve ser a janela em primeiro plano e apenas uma janela pode ser a janela de captura por vez. Para liberar a captura do mouse, chame a função ReleaseCapture .
Quando o usuário pressionar o botão esquerdo do mouse, chame SetCapture para começar a capturar o mouse.
Responder a mensagens de movimentação do mouse.
Quando o usuário liberar o botão esquerdo do mouse, chame ReleaseCapture.
Exemplo: círculos de desenho
Vamos estender o programa Círculo do Módulo 3 , permitindo que o usuário desenhe um círculo com o mouse. Comece com o programa Direct2D Circle Sample. Modificaremos o código neste exemplo para adicionar um desenho simples. Primeiro, adicione uma nova variável de membro à MainWindow classe .
D2D1_POINT_2F ptMouse;
Essa variável armazena a posição do mouse para baixo enquanto o usuário arrasta o mouse.
MainWindow No construtor, inicialize as variáveis de elipse e ptMouse.
Remova o corpo do MainWindow::CalculateLayout método; ele não é necessário para este exemplo.
void CalculateLayout() { }
Em seguida, declare manipuladores de mensagens para o botão esquerdo para baixo, botão esquerdo para cima e mensagens de movimentação do mouse.
void OnLButtonDown(int pixelX, int pixelY, DWORD flags);
void OnLButtonUp();
void OnMouseMove(int pixelX, int pixelY, DWORD flags);
As coordenadas do mouse são fornecidas em pixels físicos, mas Direct2D espera DIPs (pixels independentes de dispositivo). Para manipular as configurações de alto DPI corretamente, você deve converter as coordenadas de pixel em DIPs. Para obter mais discussões sobre DPI, consulte DPI e pixels de Device-Independent. O código a seguir mostra uma classe auxiliar que converte pixels em DIPs.
Chame DPIScale::Initialize no manipulador de WM_CREATE depois de criar o objeto de fábrica Direct2D.
case WM_CREATE:
if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
{
return -1; // Fail CreateWindowEx.
}
DPIScale::Initialize(hwnd);
return 0;
Para obter as coordenadas do mouse em DIPs das mensagens do mouse, faça o seguinte:
Use as macros GET_X_LPARAM e GET_Y_LPARAM para obter as coordenadas de pixel. Essas macros são definidas no WindowsX.h, portanto, lembre-se de incluir esse cabeçalho em seu projeto.
Chame DPIScale::PixelsToDips para converter pixels em DIPs.
Agora, adicione os manipuladores de mensagens ao procedimento de janela.
case WM_LBUTTONDOWN:
OnLButtonDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (DWORD)wParam);
return 0;
case WM_LBUTTONUP:
OnLButtonUp();
return 0;
case WM_MOUSEMOVE:
OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (DWORD)wParam);
return 0;
Por fim, implemente os próprios manipuladores de mensagens.
Botão esquerdo para baixo
Para a mensagem de botão esquerdo para baixo, faça o seguinte:
Para a mensagem de movimentação do mouse, marcar se o botão esquerdo do mouse está para baixo. Se for, recalcule a elipse e repinte a janela. Em Direct2D, uma elipse é definida pelo ponto central e pelos raios x e y. Queremos desenhar uma elipse que se ajuste à caixa delimitadora definida pelo ponto do mouse para baixo (ptMouse) e a posição atual do cursor (x, y), portanto, um pouco de aritmética é necessário para localizar a largura, altura e posição da elipse.
O código a seguir recalcula a elipse e chama InvalidateRect para repintar a janela.
Aprenda a automatizar movimentos simulados do mouse, cliques, digitação e pressionamentos de teclas no Power Automate. Além disso, descubra como selecionar e localizar imagens ou áreas na tela.