Windows WH_MOUSE_LL鼠标钩子中WM_MOUSEWHEEL滚轮delta值始终为0
问题原因分析
- 钩子结构体类型使用错误
WH_MOUSE_LL低级鼠标钩子的回调输入lParam对应的结构体是MSLLHOOKSTRUCT,你代码中使用的MOUSEHOOKSTRUCT仅适用于非低级的WH_MOUSE钩子,结构体不匹配导致参数读取错误。 - delta值取值位置错误
普通窗口进程内收到的WM_MOUSEWHEEL消息的滚轮delta值存储在wParam中,但低级鼠标钩子属于全局钩子,回调中的wParam仅用于标识当前触发的消息类型,滚轮delta值实际存储在MSLLHOOKSTRUCT的mouseData字段高位,需要对该字段调用GET_WHEEL_DELTA_WPARAM宏取值。 - 消息循环逻辑错误
GetMessage函数返回值规则:获取到有效消息时返回>0,收到WM_QUIT退出消息时返回0,调用出错时返回-1。你代码中写的while (!GetMessage(&msg, NULL, NULL, NULL))逻辑完全倒置,只有当消息循环要退出或者调用出错时才会进入循环处理消息,属于明显的逻辑错误。
修正后完整代码
#include <iostream> #include <windows.h> LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam){ // 微软官方要求仅nCode>=0时处理钩子消息 if (nCode >= 0) { if(wParam == WM_MOUSEWHEEL){ MSLLHOOKSTRUCT* pMouseData = (MSLLHOOKSTRUCT*)lParam; short delta = GET_WHEEL_DELTA_WPARAM(pMouseData->mouseData); std::cout << "wheel: " << delta << std::endl; }else{ MSLLHOOKSTRUCT* pMouseData = (MSLLHOOKSTRUCT*)lParam; std::cout << "etc: " << wParam << " - " << pMouseData->pt.x << "x" << pMouseData->pt.y << std::endl; } } return CallNextHookEx(NULL, nCode, wParam, lParam); } int main(int argc, char *argv[]) { // 第三个参数传入当前模块实例句柄更符合底层钩子规范 HHOOK hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, GetModuleHandle(NULL), 0); if (!hhkLowLevelMouse) { std::cerr << "挂钩失败,错误码:" << GetLastError() << std::endl; return 1; } MSG msg; // 修正消息循环逻辑 while (GetMessage(&msg, NULL, NULL, NULL) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } UnhookWindowsHookEx(hhkLowLevelMouse); return 0; }
内容的提问来源于stack exchange,提问作者enoeht
相关产品推荐
相关产品推荐

