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

标签 c# winapi mousewheel

我调用下面的代码,它适当地连接到wm_mouseweel上。我遇到的问题是,尽管我只向一个方向(-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;

最佳答案

终于在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);

    }

}

关于c# - 在LowLevelMouseProc调用中无法使用SendInput发送新的滚动方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7182813/

相关文章:

javascript - 在 Vanilla javascript 中鼠标滚轮上的平滑垂直滚动?

java - 正确处理 Ext-GWT 中的 OnMouseWheel 事件

c# - 如何修改以前配置的 StructureMap 配置?

c# - 使用Quartz.NET监控Mysql表并执行一些东西

c# - SendKeys 与游戏 : with some characters it works, 但有一些它没有

c++ - 如何禁用 DEP

c# - 'Y' 中的实体参与 'FK_Y_X' 关系。找到 0 个相关的 'X'。预计 1 'X'

c# - 是否可以在 C# 5.0 中使用相同的异步方法签名并能够稍后决定如何执行此类方法

c++ - 通过路径获取 Windows 可执行文件的显示名称

c++ - 鼠标滚轮只能向上或向下滚动