代码控制鼠标光标移动并点击和代码模拟键盘按下(C#)

前面介绍过通过代码的方式模拟键盘按下,博文如下:

C#通过代码的方式模拟键盘按下_c# 模拟键盘输入_zxy2847225301的博客-CSDN博客

这个博文是通过win32的keybd_event实现,可能会未来的window版本中被淘汰(不是我说的,看到老外一篇文章中说的)

本文的内容参考自:

How to Send Inputs using C# - CodeProject

本文的主要核心是利用了win32的函数SendInput,将会实现并演示如下的效果:

演示效果1:   点击按钮,然后模拟键盘输入,把输入的内容显示到文本框上

演示效果2:   点击按钮,然后控制鼠标光标移动(对角线移动)

演示效果3:   点击按钮,然后控制鼠标光标移动到演示效果1中的那个按钮的位置上,并实现点击,接着就会看到效果1中的效果(模拟键盘输入,把输入的内容显示到文本框上)

本文测试环境:

vistual studio 2017

.net framework 4.0

winform

步骤如下:

1   新建winform项目,.net framework选4.0,名为SendInputDemo,并新建类Win32SendInputApi并编辑如下:

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

namespace SendInputDemo
{
    public class Win32SendInputApi
    {
        /// <summary>
        /// 键盘输入参数
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct KeyboardInput
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        /// <summary>
        /// 鼠标输入参数
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct MouseInput
        {
            public int dx;
            public int dy;
            public uint mouseData;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        /// <summary>
        /// Hardware输入参数,Hardware不知道是什么设备,应该类似于传感器输入之类的设备(usb输入或者串口输入)
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct HardwareInput
        {
            public uint uMsg;
            public ushort wParamL;
            public ushort wParamH;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct InputUnion
        {
            [FieldOffset(0)] public MouseInput mi;
            [FieldOffset(0)] public KeyboardInput ki;
            [FieldOffset(0)] public HardwareInput hi;
        }

        public struct Input
        {
            public int type;
            public InputUnion u;
        }


        [Flags]
        public enum InputType
        {
            Mouse = 0,  //鼠标
            Keyboard = 1,//键盘
            Hardware = 2
        }

        /// <summary>
        /// 键盘状态
        /// </summary>
        [Flags]
        public enum KeyEventF
        {
            KeyDown = 0x0000,   //键盘按下
            ExtendedKey = 0x0001,  //不懂,看名字像追加键
            KeyUp = 0x0002,    //键盘抬起
            Unicode = 0x0004,  //不懂
            Scancode = 0x0008  //不懂
        }
        /// <summary>
        /// 鼠标参数类型
        /// </summary>
        [Flags]
        public enum MouseEventF
        {
            Absolute = 0x8000,
            HWheel = 0x01000,
            Move = 0x0001,  //鼠标移动
            MoveNoCoalesce = 0x2000,
            LeftDown = 0x0002,  //鼠标左键按下
            LeftUp = 0x0004,    //鼠标左键抬起
            RightDown = 0x0008, //鼠标右键按下
            RightUp = 0x0010,   //鼠标右键抬起
            MiddleDown = 0x0020,  //鼠标中键按下
            MiddleUp = 0x0040,    //鼠标中键抬下
            VirtualDesk = 0x4000, //不懂,看名字像是虚拟桌面
            Wheel = 0x0800,    //鼠标滚轮
            XDown = 0x0080,
            XUp = 0x0100
        }

        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize);

        [DllImport("user32.dll")]
        public  static extern IntPtr GetMessageExtraInfo();





        /// <summary>
        /// 获取鼠标的坐标
        /// </summary>
        /// <param name="lpPoint"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(out POINT lpPoint);

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
        }

        /// <summary>
        /// 设置鼠标的位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public static extern bool SetCursorPos(int x, int y);

    }
}

2  winform的UI布局如下:

 

3  实现演示效果1:   点击按钮,然后模拟键盘输入,把输入的内容显示到文本框上

'触发键盘按下'按钮的代码逻辑如下:

public partial class Form1 : Form
{
        public Form1()
        {
            InitializeComponent();
            this.btnPress.Click += new System.EventHandler(this.btnPress_Click);
        }

        /// <summary>
        /// 触发键盘按下按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPress_Click(object sender, EventArgs e)
        {
            this.txtKeyInput.Focus();
            Input[] inputs = new Input[]
                                {
                                    new Input
                                    {
                                        type = (int)InputType.Keyboard,
                                        u = new InputUnion
                                        {
                                            ki = new KeyboardInput
                                            {
                                                wVk = 0,
                                                wScan = 0x02, // 数字1
                                                dwFlags = (uint)(KeyEventF.KeyDown | KeyEventF.Scancode),
                                                dwExtraInfo = Win32SendInputApi.GetMessageExtraInfo()
                                            }
                                        }
                                    }
                                  };

            Win32SendInputApi.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(Input)));
            this.txtKeyInput.Focus();
        }
        
}

运行效果如下:

每点一次按钮,就录入一个1

键盘的16进制编码可以参考这个网址:Keyboard scancodes: Keyboard scancodes

如上图中的01代表键盘上的ESC键,02 数字键1或者!键(在笔记本键盘上,这两个键是公用的),相信你能看懂后面编码对应的按钮含义了

 

 

4  实现演示效果2:   点击按钮,然后控制鼠标光标移动(对角线移动)

 '设置鼠标的位置'按钮的代码逻辑如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static SendInputDemo.Win32SendInputApi;

namespace SendInputDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.btnSetCurPosition.Click += new System.EventHandler(this.btnSetCurPosition_Click);
        }

        /// <summary>
        /// 设置鼠标的位置按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetCurPosition_Click(object sender, EventArgs e)
        {
            
            for (int i = 0; i <150; i+=20)
            {
                POINT lpPoint;
                Win32SendInputApi.GetCursorPos(out lpPoint);
                Win32SendInputApi.SetCursorPos(lpPoint.X + i, lpPoint.Y +i);
                Thread.Sleep(100);
            }
        }
    }
}

上面的逻辑是:获取到当前鼠标光标的位置,然后赋予鼠标光标新的位置,每次设置睡眠100毫秒才能看到效果

运行效果:

可以看到鼠标光标在按钮"设置鼠标的位置"上点击后,鼠标光标逐渐以对角线的方式往右下角移动

5  实现演示效果3:   点击按钮,然后控制鼠标光标移动到演示效果1中的那个按钮的位置上,并实现点击,接着就会看到效果1中的效果(模拟键盘输入,把输入的内容显示到文本框上)

'设置鼠标的位置并按模拟鼠标点击'的代码逻辑如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static SendInputDemo.Win32SendInputApi;

namespace SendInputDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.btnPress.Click += new System.EventHandler(this.btnPress_Click);
            this.btnSetCurPosition.Click += new System.EventHandler(this.btnSetCurPosition_Click);
            this.btnMouseClick.Click += new System.EventHandler(this.btnMouseClick_Click);
        }

        /// <summary>
        /// 设置鼠标的位置并按模拟鼠标点击按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMouseClick_Click(object sender, EventArgs e)
        {
            //PointToScreen为btnPress控件转屏幕坐标
            Point pointScreen =this.btnPress.PointToScreen(new Point(0,0));
            //Point pointScreen =this.btnPress.PointToScreen(new Point(0,0))可以换成
            //这样的写法Point pointScreen = this.PointToScreen(new Point(btnPress.Location.X, btnPress.Location.Y));
            Win32SendInputApi.SetCursorPos(pointScreen.X+10, pointScreen.Y+1);
            Input[] inputs = new Input[]
            {
                new Input
                {
                    type = (int) InputType.Mouse,
                    u = new InputUnion
                    {
                        mi = new MouseInput
                        {
                            dx =pointScreen.X+10,
                            dy =pointScreen.Y+1,
                            dwFlags = (uint)(MouseEventF.LeftDown), //鼠标左键按下
                            dwExtraInfo = Win32SendInputApi.GetMessageExtraInfo()
                        }
                    }
                },
                new Input
                {
                    type = (int) InputType.Mouse,
                    u = new InputUnion
                    {
                        mi = new MouseInput
                        {
                            dx =pointScreen.X+10,
                            dy =pointScreen.Y+1,
                            dwFlags = (uint)(MouseEventF.LeftUp),  //鼠标左键抬起
                            dwExtraInfo = Win32SendInputApi.GetMessageExtraInfo()
                        }
                    }
                }
            };

            Win32SendInputApi.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(Input)));

        }
    }
}

想要在'触发键盘按下'按钮(名为btnPress)触发自动按钮逻辑,就得通过PointToScreen把控件的坐标转换为计算机桌面的坐标(以前做Unity 3D的时候经常看到这种骚操作),然后把转换后的坐标作为鼠标光标的位置,最后通过模拟鼠标左键按下和抬起,一定要鼠标按下和抬起一起使用才有效,因为鼠标按下和抬起同时完成才算实现鼠标按下的逻辑。

运行效果如下图:

 

好了,本文的内容到此结束(Tips:在线招个亲,最近家里逼得太急了,老铁有亲戚朋友啥的适龄未婚、活的女的都可以介绍哈,本人情况:男,1993出生,广州工作,广东人,硕士毕业,其它的可以私聊)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用MPU6050控制鼠标移动C#代码示例: ```csharp using System; using System.IO.Ports; using System.Windows.Forms; namespace MPU6050MouseControl { public partial class Form1 : Form { private SerialPort port; private int centerX; private int centerY; private int sensitivity = 2; public Form1() { InitializeComponent(); port = new SerialPort("COM3", 9600); // 请根据实际情况设置串口号和波特率 port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); port.Open(); centerX = Screen.PrimaryScreen.Bounds.Width / 2; centerY = Screen.PrimaryScreen.Bounds.Height / 2; } private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { string data = port.ReadLine(); string[] values = data.Split(','); if (values.Length == 3) { int x = Convert.ToInt32(values[0]) * sensitivity; int y = Convert.ToInt32(values[1]) * sensitivity; int z = Convert.ToInt32(values[2]) * sensitivity; Cursor.Position = new System.Drawing.Point(Cursor.Position.X + x, Cursor.Position.Y - y); } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { port.Close(); } } } ``` 上面的代码首先初始化了一个串口对象,并在串口接收数据时解析数据并将其转换为鼠标移动的信息。然后,代码鼠标移动到计算出的位置。你可以根据需要修改代码中的灵敏度值来调整鼠标移动速度。最后,当窗口关闭时,代码关闭串口连接。请注意,这只是一个简单的示例,你需要根据你的实际需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxy2847225301

测试使用

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值