简体   繁体   中英

Can't send new scroll direction with SendInput in LowLevelMouseProc call

I'm calling the below code and it appropriately is hooked onto WM_MOUSEWHEEL. The problem I'm having is that even though I'm only sending the scroll message in one direction (-120), the scroll wheel works just as expected. I've set breakpoints in it and the ifs and such work as expected.

   private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 &&
            MouseMessages.WM_MOUSEWHEEL == (MouseMessages)wParam)
        {
            MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));

            Console.WriteLine(hookStruct.mouseData);

                INPUT[] input;
                input = new INPUT[1];
                input[0].type = INPUT_MOUSE;
                input[0].mi.dx = 0;
                input[0].mi.dy = 0;
                input[0].mi.dwFlags = MOUSEEVENTF_WHEEL;
                input[0].mi.time = 0;
                input[0].mi.dwExtraInfo = 0;
                input[0].mi.mouseData = -120;
                SendInput(1, input, Marshal.SizeOf(input));
                return (IntPtr)1;

Finally figured it out with some help from Phil :

using System;

using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace EnableMacScrolling
{
    class InterceptMouse
    {
        const int INPUT_MOUSE = 0;
        const int MOUSEEVENTF_WHEEL = 0x0800;
        const int WH_MOUSE_LL = 14; 


        private static LowLevelMouseProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;

        public static void Main()
        {
            _hookID = SetHook(_proc);

            if (_hookID == null)
            {
                MessageBox.Show("SetWindowsHookEx Failed");
                return;
            }
            Application.Run();
            UnhookWindowsHookEx(_hookID);
        }

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && MouseMessages.WM_MOUSEWHEEL == (MouseMessages)wParam)
            {
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));

                Console.WriteLine(hookStruct.mouseData);
                if (hookStruct.flags != -1) //prevents recursive call to self
                {
                    INPUT input;
                    input = new INPUT();
                    input.type = INPUT_MOUSE;
                    input.mi.dx = 0;
                    input.mi.dy = 0;
                    input.mi.dwFlags = MOUSEEVENTF_WHEEL;
                    input.mi.time = 0;
                    input.mi.dwExtraInfo = 0;
                    input.mi.mouseData = -(hookStruct.mouseData >> 16);
                    try
                    {
                       SendInput(1, ref input, Marshal.SizeOf(input));
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(e.Message);
                    }

                    return (IntPtr)1;
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }


        private enum MouseMessages
        {
            WM_MOUSEWHEEL = 0x020A
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        public struct INPUT
        {
            public int type;
            public MOUSEINPUT mi;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public int mouseData;
            public uint dwFlags;
            public int time;
            public int dwExtraInfo;
        }



        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("User32.dll", SetLastError = true)]
        public static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize);

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM