In mouse hooking, the wheel delta is always 0

Viewed 204
#include <iostream>
#include <windows.h>

LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam){
  if(wParam == WM_MOUSEWHEEL){
    std::cout << "wheel: " << GET_WHEEL_DELTA_WPARAM(wParam) << std::endl;
  }else{
    MOUSEHOOKSTRUCT* mouselparam = (MOUSEHOOKSTRUCT*)lParam;
    std::cout << "etc: " << wParam << " - " << mouselparam->pt.x << "x" << mouselparam->pt.y << std::endl;
  }
  return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main(int argc, char *argv[]) {

    HHOOK hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, 0, 0);

    MSG msg;
    while (!GetMessage(&msg, NULL, NULL, NULL)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(hhkLowLevelMouse);

    return 0;
}

This is the full code.

"etc:" works perfectly as I intended.

"wheel:" always outputs 0.

am i missing something?

Using HIWORD instead of GET_WHEEL_DELTA_WPARAM gives the same result.

1 Answers

GET_WHEEL_DELTA_WPARAM() only works with the wParam of a real WM_MOUSEWHEEL window message, not the wParam of a WH_MOUSE_LL hook.

In the hook, the wParam is just the message identifier by itself, nothing more. ALL of the mouse details are stored in a MSLLHOOKSTRUCT struct pointed by the lParam. Which you attempted to look at for all mouse messages other than WM_MOUSEWHEEL, but you are looking at the wrong struct (MOUSEHOOKSTRUCT is used by WH_MOUSE, not WH_MOUSE_LL).

Per the LowLevelMouseProc callback function documentation:

  • wParam [in]
    Type: WPARAM

    The identifier of the mouse message. This parameter can be one of the following messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_RBUTTONDOWN, or WM_RBUTTONUP.

  • lParam [in]
    Type: LPARAM

    A pointer to an MSLLHOOKSTRUCT structure.

And the MSLLHOOKSTRUCT structure documentation:

mouseData
Type: DWORD

If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta. The low-order word is reserved. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.

Try this instead:

LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam){
    if (nCode == HC_ACTION) {
        MSLLHOOKSTRUCT* mouselparam = (MSLLHOOKSTRUCT*)lParam;
        if (wParam == WM_MOUSEWHEEL) {
            short delta = HIWORD(mouselparam->mouseData); 
            // alternatively, GET_WHEEL_DELTA_WPARAM() would also work here:
            // short delta = GET_WHEEL_DELTA_WPARAM(mouselparam->mouseData);
            std::cout << "wheel: " << delta << std::endl;
        }else{
            std::cout << "etc: " << wParam << " - " << mouselparam->pt.x << "x" << mouselparam->pt.y << std::endl;
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Related