C模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
目录
C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
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;
[DllImport("User32.dll", EntryPoint = "GetDC")]
private extern static IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118;
/// <summary>
/// 获取屏幕的尺寸,
/// 屏幕宽度
/// </summary>
readonly static int width = GetDeviceCaps(GetDC(IntPtr.Zero), DESKTOPHORZRES);
/// <summary>
/// 屏幕高度
/// </summary>
readonly static int height = GetDeviceCaps(GetDC(IntPtr.Zero), DESKTOPVERTRES);
/// <summary>
/// 操作鼠标,模拟操作
/// </summary>
/// <param name="dwFlags"></param>
/// <param name="dx"></param>
/// <param name="dy"></param>
/// <param name="dwData"></param>
/// <param name="dwExtraInfo"></param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("user32")]
public static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
/// <summary>
/// 鼠标瞬移到一个坐标;绝对坐标,有悬浮提示效果;
/// </summary>
/// <param name="point">到达的坐标点</param>
public static void MouseMove(POINT point)
{
//移动鼠标到某个点,绝对坐标
mouse_event(MOUSEEVENTF_absolute | MOUSEEVENTF_move,
point.X * 65536 / width,
point.Y * 65536 / height
, 0, 0);
}
/// <summary>
/// 移动鼠标
/// </summary>
public const int MOUSEEVENTF_move = 0x0001;
//模拟鼠标左键按下
public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
public const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
public const int MOUSEEVENTF_rightup = 0x0010;
//模拟鼠标中键按下
public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
public const int MOUSEEVENTF_absolute = 0x8000;
//模拟鼠标滚轮滚动操作,必须配合dwData参数
public const int MOUSEEVENTF_wheel = 0x0800;
// 定义鼠标事件标志枚举
[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; // in seconds
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"></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 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);
}
/// <summary>
/// (推荐)以恒定速度移动鼠标,可以看轨迹;鼠标悬浮可以看到提示;
/// </summary>
/// <param name="startX"></param>
/// <param name="startY"></param>
/// <param name="endX"></param>
/// <param name="endY"></param>
/// <param name="speedPixelsPerSecond"></param>
/// <param name="cancellationToken"></param>
public static void MoveMouseAtConstantSpeed3(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;
MouseMove(new POINT() { X = currentX, Y = currentY });
if (currentX == endX && currentY == endY
|| (
Math.Abs(currentX - endX) <= speedPixelsPerSecond*1
&& Math.Abs(currentY - endY) <= speedPixelsPerSecond * 1
)
)
{
break;
}
Task.Delay(5).Wait();
}
MouseMove(new POINT() { X = endX, Y = endY });
}
}
}