Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

retrieve WHEEL_DELTA from wParam in WM_MOUSEHWHEEL msg in C#

I'm using global hooks from user32.dll with dllimport in C#. Keyboard one works fine, but the mouse wheel events are a problem. This is my mouse event callback:

        private IntPtr MouseInputCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode < 0) return CallNextHookEx(mouseHookId, nCode, wParam, lParam);

            int eventType = wParam.ToInt32();
            if (eventType == WM_MOUSEHWHEEL)
            {
                int wheelMovement = GetWheelDeltaWParam(eventType);
            }

            return CallNextHookEx(mouseHookId, nCode, wParam, lParam);
        }

Everything goes fine until I have to retrieve the WHEEL_DELTA value that shows which way and how much the wheel was scrolled. Since C# lacks the GET_WHEEL_DELTA_WPARAM macro, I'm using this code that should do the job:

private static int GetWheelDeltaWParam(int wparam) { return (int)(wparam >> 16); }

But the output is always 0, which doesn't make any sense.

EDIT - result:

        MSLLHOOKSTRUCT mouseData = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
        int wheelMovement = GetWheelDeltaWParam(mouseData.mouseData);

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public Point pt;
            public int mouseData;
            public int flags;
            public int time;
            public long dwExtraInfo;
        }
like image 415
user1151923 Avatar asked Feb 17 '12 14:02

user1151923


1 Answers

The problem is that GET_WHEEL_DELTA_WPARAM is for extracting the mouse wheel delta from the wParam of a WindowProc, whereas what you have is a LowLevelMouseProc callback. In your case,

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.

the wParam is simply WM_MOUSEWHEEL; to get the wheel delta, you need to look in

lParam [in]

Type: LPARAM

A pointer to an MSLLHOOKSTRUCT structure.

and within that struct,

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.

you will find your value.

Please don't ask me for the necessary C# P/Invoke details for working this struct as I would almost certainly get them wrong :)

like image 82
AakashM Avatar answered Nov 11 '22 09:11

AakashM