在LowLevelMouseProc调用中无法使用SendInput发送新的滚动方向

时间:2011-08-24 21:56:45

标签: c# winapi mousewheel

我正在调用下面的代码,它正确地挂钩到WM_MOUSEWHEEL。我遇到的问题是即使我只是向一个方向发送滚动消息(-120),滚轮也能正常工作。我在其中设置了断点以及ifs和预期的工作。

   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;

1 个答案:

答案 0 :(得分:3)

最后在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);

    }

}