c# 获取鼠标坐标,鼠标点击,鼠标事件监听,键盘事件监听

该代码块内有四个功能,获取鼠标坐标,鼠标点击,鼠标事件监听,键盘事件监听
其鼠标坐标,鼠标点击 可以在窗体范围之外生效
鼠标事件监听,鼠标事件只在窗体范围之内有效

public class MouseAction
{
    #region 鼠标坐标

    /* 在外部通过以下命令调用
     * 开启获取鼠标坐标
     * MouseAction.MousePositionStart(textBox1);
     * 关闭获取鼠标坐标
     * MouseAction.MousePositionStop();
     */

    /// <summary>
    /// 用于回传鼠标坐标的控制
    /// </summary>
    private static System.Windows.Forms.TextBox _textBox;

    /// <summary>
    /// 获取鼠标坐标
    /// </summary>
    private static void ScreenPoint()
    {
        while (true)
        {
            Point mousePosition = Control.MousePosition;

            _textBox.Text = $"x:{mousePosition.X}    y:{mousePosition.Y}";
        }
    }

    /// <summary>
    /// 鼠标事件后移动回原位置
    /// </summary>
    /// <param name="point"></param>
    public static void MouseMoveBack(Point point)
    {
        SetCursorPos(point.X, point.Y);
    }

    /// <summary>
    /// 获取鼠标坐标
    /// </summary>
    /// <returns></returns>
    public static Point GetScreenPoint()
    {
        Point mousePosition = Control.MousePosition;
        return mousePosition;
    }

    /// <summary>
    /// 以线程的方式跟踪鼠标坐标
    /// </summary>
    private static Thread _threadMousePosition;

    /// <summary>
    /// 开启鼠标坐标跟踪
    /// </summary>
    /// <param name="textBox"></param>
    public static void MousePositionStart(System.Windows.Forms.TextBox textBox)
    {
        _textBox = textBox;
        _threadMousePosition = new Thread(new ThreadStart(ScreenPoint));
        _threadMousePosition.Start();
    }

    /// <summary>
    /// 停止鼠标坐标跟踪
    /// </summary>
    public static void MousePositionStop()
    {
        _threadMousePosition.Abort();
    }

    ~MouseAction()
    {
        MousePositionStop();
        StopHook();
    }

    #endregion

    // ------------------------------------------------------------------------------------

    #region 鼠标点击


    /*在外部通过以下命令调用
     * 获取当前坐标
     * Point pointP1 = MouseAction.GetScreenPoint();
        目标坐标
        Point pointP = new Point(Convert.ToInt32(txtX.Text), Convert.ToInt32(txtY.Text));
        鼠标左键
        MouseAction.MouseLeftClick(pointP);
        鼠标回位
        MouseAction.MouseMoveBack(pointP1);
     * 
     */


    /// <summary>
    /// 引用user32.dll运态链接库;库中定定了API:SetCursorPos
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    [DllImport("user32.dll")]

    /// <summary>
    /// 设置鼠标目标位置
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    private static extern int SetCursorPos(int x, int y);

    [DllImport("user32.dll")]
    /// <summary>
    /// 设置鼠标事件
    /// </summary>
    /// <param name="dwFlags"></param>
    /// <param name="dx"></param>
    /// <param name="dy"></param>
    /// <param name="cButtons"></param>
    /// <param name="dwExtraInfo"></param>
    private extern static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    /// <summary>
    /// 鼠标事件枚举
    /// </summary>
    private enum MouseEventFlags
    {
        Move = 0x0001,
        LeftDown = 0x0002,
        LeftUp = 0x0004,
        RightDown = 0x0008,
        RightUp = 0x0010,
        MiddleDown = 0x0020,
        MiddleUp = 0x0040,
        Wheel = 0x0800,
        Absolute = 0x8000

    }
    /// <summary>
    /// 鼠标点击左键
    /// </summary>
    /// <param name="point"></param>
    public static void MouseLeftClick(Point point)
    {
        SetCursorPos(point.X, point.Y);
        MouseAction.mouse_event(MouseAction.MouseEventFlags.LeftDown.GetHashCode() | MouseAction.MouseEventFlags.LeftUp.GetHashCode(), point.X, point.Y, 0, 0);
    }
    #endregion

    // ------------------------------------------------------------------------------------

    #region 键盘事件监听

    /*在外部通过以下命令调用
     * MouseAction.StartKeyboardHook(richTextBox1);
     */

    /// <summary>
    /// 安装钩子
    /// </summary>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
    private delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);


    /// <summary>
    /// 继续下一个钩子
    /// </summary>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

    /// <summary>
    /// 卸载钩子
    /// </summary>
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(int idHook);

    /// <summary>
    ///获取当前线程编号(线程钩子需要用到)
    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();

    /// <summary>
    /// 获取当前实例的函数
    /// </summary>
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string name);


    /// <summary>
    /// 获取按键的状态
    /// </summary>
    /// <param name="pbKeyState"></param>
    /// <returns></returns>
    [DllImport("user32")]
    private static extern int GetKeyboardState(byte[] pbKeyState);

    /// <summary>
    /// 将指定的虚拟键码和键盘状态翻译为相应的字符或字符串
    /// </summary>
    [DllImport("user32")]
    private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);


    /// <summary>
    /// 键盘结构
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private class KeyboardHookStruct
    {
        public int vkCode;  //定一个虚拟键码。该代码必须有一个价值的范围1至254
        public int scanCode; // 指定的硬件扫描码的关键
        public int flags;  // 键标志
        public int time; // 指定的时间戳记的这个讯息
        public int dwExtraInfo; // 指定额外信息相关的信息
    }

    //定义为键盘钩子
    private static int WH_KEYBOARD_LL = 13;

    //相关键盘事件
    //private event KeyEventHandler KeyDownEvent;
    //private event KeyPressEventHandler KeyPressEvent;
    //private event KeyEventHandler KeyUpEvent;
    private static void KeyDownEvent(object sender,KeyEventArgs e  )
    {
        //_richTextBox.AppendText(e.KeyData.ToString()+"\n");
    }

    private static void KeyPressEvent(object sender, KeyPressEventArgs e)
    {
        _richTextBox.AppendText(e.KeyChar.ToString() + "\n");
    }

    private static void KeyUpEvent(object sender, KeyEventArgs e)
    {
        //_richTextBox.AppendText(e.KeyData.ToString() + "\n");
    }


    //相关动作
    private const int WM_KEYDOWN = 0x100;//KEYDOWN
    private const int WM_KEYUP = 0x101;//KEYUP
    private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
    private const int WM_SYSKEYUP = 0x105;//SYSKEYUP

    //hookid
    private static int hookID = 0;

    //向下传递数据
    private static Keys NoNextKeyCode;

    /// <summary>
    /// 安装钩子
    /// </summary>
    public static void StartKeyboardHook(RichTextBox richTextBox)
    {
        _richTextBox = richTextBox;
        if (hookID == 0)
        {
            HookProc hookProc = new HookProc(KeyboardHookProc);
            hookID = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);


            if (hookID == 0)
            {
                StopHook();
                throw new Exception("安装键盘钩子失败");
            }
        }
    }


    public static void StopHook()
    {
        bool isStop = true;
        if (hookID != 0)
        {
            isStop = UnhookWindowsHookEx(hookID);
            hookID = 0;
        }
        if (!isStop) throw new Exception("卸载键盘钩子失败!");
    }

    /// <summary>
    /// 监听事件
    /// </summary>
    private static int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
    {
        if ((nCode >= 0) )
        {

            KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

            //按下处理
            if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
            {
                Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                KeyEventArgs e = new KeyEventArgs(keyData);
                KeyDownEvent(null, e);
                //阻止向下传递
                if (NoNextKeyCode == keyData)
                {
                    return hookID;
                }
            }

            //按下并抬起处理
            if ( wParam == WM_KEYDOWN)
            {
                byte[] keyState = new byte[256];
                GetKeyboardState(keyState);

                byte[] inBuffer = new byte[2];
                if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
                {
                    KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                    KeyPressEvent(null, e);
                }
            }

            // 抬起处理
            if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
            {
                Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                KeyEventArgs e = new KeyEventArgs(keyData);
                KeyUpEvent(null, e);
            }

        }
        return CallNextHookEx(hookID, nCode, wParam, lParam);
    }

    #endregion


    //--------------------------------------------------------------------------------

    #region 鼠标事件监听

    /*在外部通过以下命令调用
     * MouseAction.StartMouseHook(richTextBox1);
     */

    /// <summary>
    /// 鼠标结构
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private class MouseHookStruct
    {
        public POINT pt; // 鼠标位置
        public int hWnd;
        public int wHitTestCode;
        public int dwExtraInfo;
    }

    /// <summary>
    /// 鼠标位置结构
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private class POINT
    {
        public int x;
        public int y;
    }

    //定义为鼠标钩子
    private static int WH_MOUSE_LL = 14;

    //相关鼠标事件
    //public event MouseEventHandler MouseDown;
    //public event MouseEventHandler MouseUp;

    private static void MouseDown(object sender, MouseEventArgs e)
    {
        _richTextBox.AppendText(string.Format("在{0},{1}位置按下了鼠标{2}键", e.X, e.Y, e.Button.ToString())+"\n");
    }

    private static void MouseUp(object sender,MouseEventArgs e)
    {
        //_richTextBox.AppendText(string.Format("在{0},{1}位置松开了鼠标{2}键", e.X, e.Y, e.Button.ToString()) + "\n");
    }

    //相关动作
    private const int WM_MOUSEMOVE = 0x200; // 鼠标移动
    private const int WM_LBUTTONDOWN = 0x201;// 鼠标左键按下
    private const int WM_RBUTTONDOWN = 0x204;// 鼠标右键按下
    private const int WM_MBUTTONDOWN = 0x207;// 鼠标中键按下
    private const int WM_LBUTTONUP = 0x202;// 鼠标左键抬起
    private const int WM_RBUTTONUP = 0x205;// 鼠标右键抬起
    private const int WM_MBUTTONUP = 0x208;// 鼠标中键抬起

    //hookid
    //private int hookID = 0;


    private static int MouseHookProc(int nCode, int wParam, IntPtr lParam)
    {
        if ((nCode >= 0))
        {

            MouseHookStruct hookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

            MouseEventArgs e = null;
            switch (wParam)
            {
                case WM_LBUTTONDOWN:
                    e = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
                    MouseDown(null, e);
                    break;
                case WM_RBUTTONDOWN:
                    e = new MouseEventArgs(MouseButtons.Right, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
                    MouseDown(null, e);
                    break;
                case WM_LBUTTONUP:
                    e = new MouseEventArgs(MouseButtons.Left, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
                    MouseUp(null, e);
                    break;
                case WM_RBUTTONUP:
                    e = new MouseEventArgs(MouseButtons.Right, 1, hookStruct.pt.x, hookStruct.pt.y, 0);
                    MouseUp(null, e);
                    break;
                default:
                    break;
            }
        }

        return CallNextHookEx(hookID, nCode, wParam, lParam);
    }

    private static System.Windows.Forms.RichTextBox _richTextBox;

    /// <summary>
    /// 安装钩子
    /// </summary>
    public static void StartMouseHook(RichTextBox richTextBox)
    {
        _richTextBox = richTextBox;

        if (hookID == 0)
        {
            HookProc hookProc1 = new HookProc(MouseHookProc);
            hookID = SetWindowsHookEx(WH_MOUSE_LL, hookProc1, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);

            if (hookID == 0)
            {
                StopHook();
                throw new Exception("安装键盘钩子失败");
            }
        }
    }

    #endregion

}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Microsoft Visual Studio 2010做的C#实时监控鼠标位置和左键点击时的位置实例,主要代码: public class MouseHook { private Point point; private Point Point { get { return point; } set { if (point != value) { point = value; if (MouseMoveEvent != null) { var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0); MouseMoveEvent(this, e); } } } } private int hHook; private const int WM_LBUTTONDOWN = 0x201; public const int WH_MOUSE_LL = 14; public Win32Api.HookProc hProc; public MouseHook() { this.Point = new Point(); } public int SetHook() { hProc = new Win32Api.HookProc(MouseHookProc); hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0); return hHook; } public void UnHook() { Win32Api.UnhookWindowsHookEx(hHook); } private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) { Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct)); if (nCode < 0) { return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } else { if (MouseClickEvent != null) { MouseButtons button = MouseButtons.None; int clickCount = 0; switch ((Int32)wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; clickCount = 1; break; } var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0); MouseClickEvent(this, e); } this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y); return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } } public delegate void MouseMoveHandler(object sender, MouseEventArgs e); public event MouseMoveHandler MouseMoveEvent; public delegate void MouseClickHandler(object sender, MouseEventArgs e); public event MouseClickHandler MouseClickEvent; }
您可以使用`SetWindowsHookEx`函数来监听鼠标事件。下面是一个示例代码,演示如何在C#中监听鼠标在其他窗体的点击事件: ```csharp using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; public class MouseListener { private const int WH_MOUSE_LL = 14; private const int WM_LBUTTONDOWN = 0x0201; private static LowLevelMouseProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; public static void Main() { _hookID = SetHook(_proc); 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 && wParam == (IntPtr)WM_LBUTTONDOWN) { int x = Marshal.ReadInt32(lParam); // 获取鼠标点击的X坐标 int y = Marshal.ReadInt32(lParam + 4); // 获取鼠标点击的Y坐标 Console.WriteLine($"Left button down at ({x}, {y})"); } return CallNextHookEx(_hookID, nCode, wParam, lParam); } [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); } ``` 这段代码会在控制台输出鼠标左键点击坐标。您可以根据需要修改`HookCallback`方法,处理其他鼠标事件。请注意,此代码需要以管理员身份运行,以便安装全局钩子。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值