MouseTool.cs 2.97 KB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace RCS.WinClient.Common
{
    internal struct Mouse_LL_Hook_Data
    {
        internal long yx;
        internal readonly int mouseData;
        internal readonly uint flags;
        internal readonly uint time;
        internal readonly IntPtr dwExtraInfo;
    }
    public static class MouseTool
    {
        public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);

        //安装钩子
        [DllImport("user32.dll")]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr pInstance, int threadID);

        //卸载钩子
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);

        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); //parameter 'hhk' is ignored.

        internal static event Action<IntPtr, Mouse_LL_Hook_Data> CallbackErroeHandle;

        internal static event Action<int> InsertErrorHandle;

        //鼠标点击
        public const int WH_MOUSE_LL = 14;

        //鼠标按下
        public const int WM_LBUTTONDOWN = 0x0201;

        //鼠标松开
        public const int WM_LBUTTONUP = 0x0202;


        private static IntPtr pMouseHook = IntPtr.Zero;

        private static HookProc mouseHookProc;

        private static int MouseHookCallback(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code < 0)
            {
                return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
            }

            Mouse_LL_Hook_Data mhd = (Mouse_LL_Hook_Data)Marshal.PtrToStructure(lParam, typeof(Mouse_LL_Hook_Data))!;
            CallbackErroeHandle?.Invoke(wParam, mhd);
            return 0;
        }

        public static bool InsertMouseHook()
        {
            if (pMouseHook == IntPtr.Zero)
            {
                mouseHookProc = MouseHookCallback;
                pMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseHookProc, IntPtr.Zero, 0);

                if (pMouseHook == IntPtr.Zero)
                {
                    int error = Marshal.GetLastWin32Error();
                    InsertErrorHandle?.Invoke(error);
                    //MessageBox.Show($"Failed to install global mouse hook. Error code: {error}");
                    RemoveMouseHook();
                    return false;
                }
            }

            return true;
        }

        public static bool RemoveMouseHook()
        {
            if (pMouseHook != IntPtr.Zero)
            {
                if (UnhookWindowsHookEx(pMouseHook))
                {
                    pMouseHook = IntPtr.Zero;
                }
                else
                {
                    return false;
                }
            }

            return true;
        }

    }
}