retrieve WHEEL_DELTA from wParam in WM_MOUSEHWHEEL msg in C#
Asked Answered
F

2

6

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;
        }
Fournier answered 17/2, 2012 at 14:42 Comment(2)
Something seems amiss. You compare wParam for equality with the message id, but then want the same value's top 16 bits to vary?Extraditable
Something probably is amiss, but in that case what would the correct solution be?Fournier
E
6

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 :)

Extraditable answered 17/2, 2012 at 15:21 Comment(0)
D
0

Here you are looking for WM_MOUSE**H**WHEEL, which is movement horizontally of the wheel (side to side),

NOT the scrolling action of the wheel, which is WM_MOUSEWHEEL.

        if (eventType == WM_MOUSE**H**WHEEL)
        {
            int wheelMovement = GetWheelDeltaWParam(eventType);
        }

Are you sure that's what you want? Maybe just substitute WM_MOUSEWHEEL here, as well as other suggestions.

Dagny answered 6/4, 2015 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.