You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:54:04