C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace WpfAppYolo11_test1.Tool
{/// <summary>/// 模拟鼠标点击/// </summary>public class MyMouseClick{/// <summary>/// 当鼠标移动时触发/// </summary>public static event EventHandler OnMoveMouse;// 定义鼠标事件标志枚举[Flags]public enum MouseEventFlags : uint{Move = 0x0001,LeftDown = 0x0002,LeftUp = 0x0004,RightDown = 0x0008,RightUp = 0x0010,MiddleDown = 0x0020,MiddleUp = 0x0040,XDown = 0x0080,XUp = 0x0100,Wheel = 0x0800,VirtualDesk = 0x4000,Absolute = 0x8000}/// <summary>/// 移动鼠标到一个坐标/// </summary>/// <param name="X"></param>/// <param name="Y"></param>/// <returns></returns> [DllImport("user32.dll")]public static extern bool SetCursorPos(int X, int Y);// 导入user32.dll中的mouse_event函数[DllImport("user32.dll")]public static extern void mouse_event(MouseEventFlags flags, int dx, int dy, uint data, UIntPtr extraInfo);/// <summary>/// 当前鼠标位置/// </summary>/// <param name="lpPoint"></param>/// <returns></returns> [DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]public static extern bool GetCursorPos(out POINT lpPoint);/// <summary>/// 导入模拟键盘的方法/// </summary>/// <param name="bVk" >按键的虚拟键值</param>/// <param name= "bScan" >扫描码,一般不用设置,用0代替就行</param>/// <param name= "dwFlags" >选项标志:0:表示按下,2:表示松开</param>/// <param name= "dwExtraInfo">一般设置为0</param>[DllImport("user32.dll")]public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);// 定义POINT结构体[StructLayout(LayoutKind.Sequential)]public struct POINT{public int X;public int Y;}/// <summary>/// 点击鼠标左键/// </summary>/// <param name="x">坐标x</param>/// <param name="y">坐标y</param>public static void MouseLeftClick(int x, int y){//移动鼠标到一个坐标SetCursorPos(x, y);mouse_event(MouseEventFlags.LeftDown, 0, 0, 0, UIntPtr.Zero);mouse_event(MouseEventFlags.LeftUp, 0, 0, 0, UIntPtr.Zero);}/// <summary>/// 点击鼠标左键/// </summary>/// <param name="point"></param>public static void MouseLeftClick(POINT point){//移动鼠标到一个坐标SetCursorPos(point.X, point.Y);mouse_event(MouseEventFlags.LeftDown, 0, 0, 0, UIntPtr.Zero);mouse_event(MouseEventFlags.LeftUp, 0, 0, 0, UIntPtr.Zero);}/// <summary>/// 双击鼠标左键/// </summary>/// <param name="x"></param>/// <param name="y"></param>public static void MouseDoubleLeftClick(int x, int y){MouseLeftClick(x, y);MouseLeftClick(x, y);}/// <summary>/// 双击鼠标左键/// </summary>/// <param name="x"></param>/// <param name="y"></param>public static void MouseDoubleLeftClick(POINT pOINT){MouseLeftClick(pOINT.X, pOINT.Y);MouseLeftClick(pOINT.X, pOINT.Y);}/// <summary>/// 移动鼠标从一个点到另一个点,有移动轨迹/// </summary>/// <param name="startPoint">开始坐标</param>/// <param name="endPoint">停止坐标</param> /// <param name="delay">每步歇息耗时毫秒</param>public static void MoveMouseSmoothly(POINT startPoint, POINT endPoint, int delay = 5){int currentX = startPoint.X;int currentY = startPoint.Y;int step = 40;int deltaX = (endPoint.X - startPoint.X) / step;int deltaY = (endPoint.Y - startPoint.Y) / step;OnMoveMouse?.Invoke(new POINT() { X = deltaX, Y = deltaY }, new EventArgs());int index = 0;Task.Run(() =>{try{while (index <= step){OnMoveMouse?.Invoke(new POINT() { X = currentX, Y = currentY }, new EventArgs());SetCursorPos(currentX, currentY);currentX += deltaX;currentY += deltaY;index++;Thread.Sleep(delay);}SetCursorPos(endPoint.X, endPoint.Y);}catch (Exception){}});}/// <summary>/// 计算两点之间的距离/// </summary>/// <param name="x1"></param>/// <param name="y1"></param>/// <param name="x2"></param>/// <param name="y2"></param>/// <returns></returns>public static double CalculateDistance(int x1, int y1, int x2, int y2){var num1 = Math.Abs(x2 - x1);var num2 = Math.Abs(y2 - y1);return Math.Sqrt(Math.Pow(num1, 2) + Math.Pow(num2, 2));}/// <summary>/// 以恒定速度移动鼠标,可以看轨迹/// </summary>/// <param name="startX"></param>/// <param name="startY"></param>/// <param name="endX"></param>/// <param name="endY"></param>/// <param name="speedPixelsPerSecond">移动速度,多少像素/5毫秒</param>/// <param name="cancellationToken"></param>/// <returns></returns>public static void MoveMouseAtConstantSpeedAsync(int startX, int startY, int endX, int endY, double speedPixelsPerSecond = 10, CancellationToken cancellationToken = default){double distance = CalculateDistance(startX, startY, endX, endY);//移动总步数,毫秒double steps = distance / speedPixelsPerSecond; int currentX = startX;int currentY = startY;//每步移动的像素double x_move = (endX - startX) / steps;double y_move = (endY - startY) / steps;for (int i = 0; i < steps; i++){//if (cancellationToken.IsCancellationRequested)//{// Console.WriteLine("Mouse movement cancelled.");// return;//}currentX += (int)x_move;currentY += (int)y_move;SetCursorPos(currentX, currentY);Task.Delay(5).Wait();}//SetCursorPos(endX, endY);}/// <summary>/// (推荐)以恒定速度移动鼠标,可以看轨迹/// </summary>/// <param name="startX">开始坐标x</param>/// <param name="startY">开始坐标y</param>/// <param name="endX">终点坐标x</param>/// <param name="endY">终点坐标y</param>/// <param name="speedPixelsPerSecond">移动速度,多少像素/5毫秒</param>/// <param name="cancellationToken"></param>/// <returns></returns>public static void MoveMouseAtConstantSpeedAsync2(int startX, int startY, int endX, int endY, double speedPixelsPerSecond = 20, CancellationToken cancellationToken = default){int currentX = startX;int currentY = startY;while (true){ //当前鼠标位置POINT startPoint;GetCursorPos(out startPoint);double distance = CalculateDistance(startPoint.X, startPoint.Y, endX, endY);//移动总步数,毫秒double steps = distance / speedPixelsPerSecond; 移动总共多少步//double stepsX = Math.Abs(endX - startPoint.X) / speedPixelsPerSecond;//double stepsY = Math.Abs(endY - startPoint.Y) / speedPixelsPerSecond;//每步移动像素double xMove= (endX - startPoint.X)/ steps;double yMove= (endY - startPoint.Y) / steps;currentX += (int)xMove;currentY += (int)yMove;SetCursorPos(currentX, currentY);if (currentX == endX && currentY == endY|| (Math.Abs(currentX - endX) <= 8 && Math.Abs(currentY - endY) <= 8)){break;}Task.Delay(5).Wait();}SetCursorPos(endX, endY);}}
}