C#调用Win32接口获取和设置鼠标位置

因为平常主要做web相关的开发,比较少用到系统级的接口。今天突发奇想做一个小工具,需要用到鼠标的接口,找了些文档研究了一下,发一下心得。

简化的需求:

  1. 获取鼠标当前位置

  2. 设置鼠标位置

  3. 以上两个功能的快捷键


官方文档: https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/

需要用到这个文档中的两个方法 GetCursorPos 和 SetCursorPos

GetCursorPos 中有个LPPOINT 结构体

首先需要把这三个东西引入到C#中

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct tagPOINT
    {
        public int x;
        public int y;
    };
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SetCursorPos(int x, int y);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetCursorPos(out tagPOINT lpPoint);

调用获取鼠标位置的接口

        private void doGetCursorPos()
        {
            tagPOINT point;
            IntPtr result = GetCursorPos(out point);
            if (result.ToInt32() == 1)
            {
                // 将结果显示到label中
                CursorPos.Text = point.x + ":" + point.y;
            }
        }

调用设置鼠标的接口

        private void doSetCursorPos()
        {
            // 从输入框获取要设置的值
            string[] pos = CursorPosBox.Text.Split(',');
            if (pos.Length > 1)
            {
                int x = int.Parse(pos[0]);
                int y = int.Parse(pos[1]);

                SetCursorPos(x, y);
            }
        }

在界面的按钮事件调用以上两个方法就可以做到了。


要添加快捷键,先在根Form中开启KeyPreview ,然后绑定KeyPress事件

        private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
        {
            if(e.KeyChar == 'g')
            {
                doGetCursorPos();
            }
            else if(e.KeyChar == 's')
            {
                doSetCursorPos();
            }
        }

不过这个快捷键只适用于当前窗口,要绑定全局快捷键,就需要调用 RegisterHotKey 这个接口了

导入需要的方法

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr UnregisterHotKey(IntPtr hWnd, int id);


        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetActiveWindow();


绑定热键 这里绑定了两个键 1001对应 Ctrl+Alt+G 1002对应 Ctrl+Alt+S

            IntPtr win = GetActiveWindow();
            IntPtr rst1 = RegisterHotKey(win, 1001, MOD_ALT | MOD_CONTROL, 0x47);
            IntPtr rst2 = RegisterHotKey(win, 1002, MOD_ALT | MOD_CONTROL, 0x53);

取消热键

            IntPtr win = GetActiveWindow();
            IntPtr rst1 = UnregisterHotKey(win, 1001);
            IntPtr rst2 = UnregisterHotKey(win, 1002);

响应热键

        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;

            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 1001:
                            // 响应 Ctrl+Alt+G
                            doGetCursorPos();
                            break;
                        case 1002:
                            // 响应 Ctrl+Alt+S
                            doSetCursorPos();
                            break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

好了,至此基本接口的导入和调用就完成了,效果如下:

微信截图_20211227132257.png