MSDN décrit que lParam
de WM_MOUSEMOVE
est de 2 short
est due au fait qu'elle doit être compatible avec les coordonnées virtuelles car elle agit comme un événement redirigé si la capture est activée, ce qui est clair. Cependant, les coordonnées négatives sont toujours reçues dans des circonstances normales lorsque l'on déplace la souris légèrement en dehors de la fenêtre, pour être exact un bonus de 5 pixels dans toutes les directions sauf vers le haut (qui est là où se trouve la légende, et elle irait à WM_NCMOUSEMOVE
à la place).
J'ai d'abord pensé que cela était dû au fait que l'ombre portée faisait techniquement partie de la fenêtre (comme avec la sortie de AdjustWindowRectEx
Il est possible de recevoir des événements dans une partie de l'ombre, mais les valeurs ne correspondent pas et le fait de fixer les valeurs à la taille de la zone client n'est pas voulu. D'où viennent les 5 pixels supplémentaires (sur mon système, Windows 10 Education 2004), surtout si l'on considère qu'ils ne devraient même pas faire partie de la zone client à ma connaissance, et existe-t-il un moyen propre/intuitif d'éviter les valeurs indésirables ?
J'ai vu des discussions sur le lien potentiel entre la zone que vous pouvez saisir pour redimensionner la fenêtre, mais ma fenêtre n'est pas redimensionnable (elle n'a pas de cadre épais).
Edit : Après avoir bricolé, il semble que cela soit lié au style de la fenêtre. Voici un exemple reproductible (sur d'autres machines, j'espère) :
#include <Windows.h>
#include <stdio.h>
// Remove `^ WS_THICKFRAME` and the bug vanishes!
#define WINDOW_STYLE ((WS_OVERLAPPEDWINDOW | WS_VISIBLE) ^ WS_THICKFRAME)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (message == WM_MOUSEMOVE) {
POINTS mouse = MAKEPOINTS(lParam);
printf("WM_MOUSEMOVE @ x=%hd, y=%hd\n", mouse.x, mouse.y);
} else if (message == WM_DESTROY) {
PostQuitMessage(0);
}
return DefWindowProcW(hWnd, message, wParam, lParam);
}
int main(void) {
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"SO_Example";
wcex.hIconSm = NULL;
RECT windowRect = { 0, 0, 600, 600 };
AdjustWindowRectEx(&windowRect, WINDOW_STYLE, FALSE, 0);
ATOM windowClass = RegisterClassExW(&wcex);
HWND hWnd = CreateWindowExW(
0,
(LPCWSTR)windowClass,
L"hello stackoverflow!",
WINDOW_STYLE,
CW_USEDEFAULT, CW_USEDEFAULT,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
NULL,
NULL,
GetModuleHandle(NULL),
NULL
);
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0) != 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}
Voici cet échantillon en action : https://i.imgur.com/LfCe9od.mp4