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 secondsint 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 });}}
}相关文章:
C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;namespa…...
php虚拟站点提示No input file specified时的问题及权限处理方法
访问站点,提示如下 No input file specified. 可能是文件权限有问题,也可能是“.user.ini”文件路径没有配置对,最简单的办法就是直接将它删除掉,还有就是将它设置正确 #配置成自己服务器上正确的路径 open_basedir/mnt/qiy/te…...
RISC-V汇编学习(三)—— RV指令集
有了前两节对于RISC-V汇编、寄存器、汇编语法等的认识,本节开始介绍RISC-V指令集和伪指令。 前面说了RISC-V的模块化特点,是以RV32I为作为ISA的核心模块,其他都是要基于此为基础,可以这样认为:RISC-V ISA 基本整数指…...
java 重点知识 — JVM存储模块与类加载器
1 jvm主要模块 方法区 存储了由类加载器从.class文件中解析的类的元数据(类型信息、域信息、方法信息)及运行时常量池(引用符号及字面量)。 所有线程共享;内存不要求连续,可扩展,可能发生垃圾回…...
WPF有哪些使用率高的框架
架构类库 Community Toolkit MVVMMVVM Light UI类库 MahApps.MetroMaterial Design In XAML Toolkit 图标类库 MahApps.Metro.IconPacks...
idea中使用DeepSeek让编程更加便捷
IDEA中使用DeepSeek让编程更加便捷 对于开发者来说,IDEA(IntelliJ IDEA)是一款强大的开发工具。但你是否知道,通过安装DeepSeek这款插件,可以让你的编程体验更上一层楼?今天,我们就来聊聊如何在…...
创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程
环境: node v20.18.0 npm 11.1.0 用到的所有依赖: "dependencies": {"core-js": "^3.8.3","vue": "^3.2.13","vue-router": "^4.5.0"},"devDependencies": {"ba…...
elasticsearch是哪家的
Elasticsearch:数据搜索与分析的领航者 在当今这个信息爆炸的时代,快速且准确地处理海量数据成为了众多企业和组织追求的目标。而Elasticsearch正是在这个背景下脱颖而出的一款强大的开源搜索引擎。它是由位于美国加利福尼亚州的Elastic公司所开发和维护…...
nginx基础http基础
目录 nginx简介正向代理&反向代理正向代理反向代理What Is a Reverse Proxy Server? High-Performance Load Balancing (负载均衡)Problem(问题)Solution(解决方案)常见负载均衡算法Round Robin(轮询)…...
5. MySQL 存储引擎(详解说明)
5. MySQL 存储引擎(详解说明) 文章目录 5. MySQL 存储引擎(详解说明)1. 查看存储引擎2. 设置系统默认的存储引擎3. 设置表的存储引擎3.1 创建表时指定存储引擎3.2 修改表的存储引擎 4. 引擎介绍4.1 InnoDB 引擎:具备外键支持功能的事务存储引擎4.2 MyISAM 引擎&…...
基于LabVIEW的伺服阀高频振动测试闭环控制系统
为实现伺服阀在设定位置上下快速移动(1kHz控制频率)的振动测试目标,需构建基于LabVIEW的闭环控制系统。系统需满足高速数据采集、实时控制算法(如PID或自适应控制)、高精度电流驱动及传感器反馈处理等需求。结合用户提…...
97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)
前言 在许多卫星应用场景中,我们需要 基于 TLE(Two-Line Element Set, 两行根数)计算卫星轨迹,并在地图上进行可视化。本文将使用 Vue 3 OpenLayers satellite.js,实现 实时计算卫星轨迹,并在地图上动态更…...
Android Coil总结
文章目录 Android Coil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听 简单封装 Android Coil总结 概述 Coil 是一个用于 Android 的 Kotlin 图像加载库,旨在简化图像加载和显示的过程。它基于 Kotlin 协程࿰…...
fastjson漏洞#不出网#原理#流量特征
原理 本质是java的反序列化漏洞,由于引进了自动检测类型的(autotype)功能,fastjson在对json字符串反序列化的时候,会读取type内容,会试图将json内容反序列化成这个对象,并调用这个类的setter方…...
云计算:虚拟化、容器化与云存储技术详解
在上一篇中,我们深入探讨了网络安全的核心技术,包括加密、认证和防火墙,并通过实际案例和细节帮助读者全面理解这些技术的应用和重要性。今天,我们将转向一个近年来迅速发展的领域——云计算。云计算通过提供按需访问的计算资源,彻底改变了IT基础设施的构建和管理方式。本…...
使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅
最近,我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全,但生成的 HTML 代码繁杂,维护起来非常麻烦。为了追求更简洁高效的写作体验,我开始研究 Markdown 编辑器,并最终选择了 marked.min.js。 1. 传…...
Linux系统基于ARM平台的LVGL移植
软硬件介绍:Ubuntu 20.04 ARM 和(Cortex-A53架构)开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的,如果想要实现在ARM开发板上运行LVGL图形库,那么就需要把LVGL图形库提供的关于帧缓冲设…...
LeetCode 2070.每一个查询的最大美丽值:排序 + 二分查找
【LetMeFly】2070.每一个查询的最大美丽值:排序 二分查找 力扣题目链接:https://leetcode.cn/problems/most-beautiful-item-for-each-query/ 给你一个二维整数数组 items ,其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和…...
电力场景绝缘子缺陷分割数据集labelme格式1585张4类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1585 标注数量(json文件个数):1585 标注类别数:4 标注类别名称:["broken part","broken insulat…...
【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式
网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议: HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站,就是通过HTTP协议来…...
IPFS:下一代互联网传输协议
IPFS:下一代互联网传输协议 1. 引言2. IPFS概述3. IPFS的核心优势3.1 去中心化3.2 高效性3.3 安全性3.4 持久性3.5 可扩展性 4. IPFS的工作原理4.1 内容寻址4.2 分布式哈希表(DHT)4.3 文件分块4.4 版本控制4.5 网络协议 5. IPFS的应用场景5.1…...
线上接口tp99突然升高如何排查?
当线上接口的 TP99 突然升高时,意味着该接口在 99% 的情况下响应时间变长,这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99:监控系统计算 TP99(第 99 百分位数的响应时间&…...
SpringBoot优雅关机,监听关机事件,docker配置
Spring Boot 提供了多种方法来实现优雅停机(Graceful Shutdown),这意味着在关闭应用程序之前,它会等待当前正在处理的请求完成,并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下: …...
在【k8s】中部署Jenkins的实践指南
🐇明明跟你说过:个人主页 🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…...
Unity DOTS从入门到精通之 C# Job System
文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程,我们将创建一个旋转立方体的简单程序,并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…...
Spring Boot 本地缓存工具类设计与实现
在 Spring Boot 应用中,缓存是提升性能的重要手段之一。为了更方便地使用缓存,我们可以设计一套通用的本地缓存工具类,封装常见的缓存操作,简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类࿰…...
【Godot4.4】浅尝Godot中的MVC
概述 基于一个Unity的视频。学习了一下基本的MVC概念,并尝试在Godot中实现了一下。 原始的MVC: Godot中的MVC: Model、View和Controller各自应该实现的功能如下: Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…...
如何解决前端的竞态问题
前端的竞态问题通常是指多个异步操作的响应顺序与发起顺序不一致,导致程序出现不可预测的结果。这种问题在分页、搜索、选项卡切换等场景中尤为常见。以下是几种常见的解决方法: 1. 取消过期请求 当用户发起新的请求时,取消之前的请求&…...
Elasticsearch为索引设置自动时间戳,ES自动时间戳
文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时,时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…...
计算机网络:计算机网络的组成和功能
计算机网络的组成: 计算机网络的工作方式: 计算机网络的逻辑功能; 总结: 计算机网络的功能: 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点(计算机或设备&…...
