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;// 定义鼠标事件标志枚举[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);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QGIS提取全国景区经纬度的完整流程

一、数据获取与预处理 数据来源选择 全国A级景区数据可从各省文化和旅游厅官网、国家文化和旅游部网站或第三方GIS数据平台获取。推荐使用2020-2021年更新的矢量数据&#xff08;shp格式&#xff09;或Excel表格&#xff0c;其中包含景区名称、地址、等级及WGS84经纬度信息。例…

如何进行postgreSQL专家认证

进行 PostgreSQL 专家认证主要有信创 PostgreSQL 认证和中国 PostgreSQL 考试认证等方式&#xff0c;以下以信创 PostgreSQL 认证为例介绍具体步骤&#xff1a; 了解认证体系 信创 PostgreSQL 认证由工信部人才交流中心组织及颁发证书&#xff0c;包括以下三个级别&#xff1a;…

【前端】【webpack-dev-server】proxy跨域代理

参考&#xff1a;https://www.bilibili.com/video/BV1c5SnYZEnZ?spm_id_from333.788.videopod.episodes&vd_source65c8707649747fd67b232866b69a5ebd&p138

批量在 Word 的指定位置插入页,如插入封面、末尾插入页面

我们经常会碰到需要在 Word 文档中插入新的页面的需求&#xff0c;比如在 Word 文档末尾插入一个广告页、给 Word 文档插入一个说明封面&#xff0c;在 Word 文档的中间位置插入新的页面等等。相信这个操作对于大部分小伙伴来说都不难&#xff0c;难的是同时给多个 Word 文档插…

在Windows 11的WSL中安装Kali Linux

Kali Linux 是网络安全从业者和爱好者的首选工具集&#xff0c;但直接在物理机或虚拟机上运行可能占用较多资源。借助 Windows Subsystem for Linux (WSL)&#xff0c;我们可以在Windows 11中原生运行Kali Linux&#xff0c;轻量且高效。本教程将手把手教你如何在WSL2中安装并配…

Flow Size Prediction with Short Time Gaps

Flow Size Prediction with Short Time Gaps 网络流量预测新突破&#xff1a;微秒级短流预测的可行性分析 在当今数据中心和云计算环境中&#xff0c;网络流量的精准预测是优化资源分配、实现智能负载均衡的关键。传统流量和预测聚焦于长时间间隔&#xff08;如秒级或分钟级&…

pandas——to_datatime用法

Pandas中pd.to_datetime的用法及示例 pd.to_datetime 是 Pandas 库中用于将字符串、整数或列表转换为日期时间&#xff08;datetime&#xff09;对象的核心函数。它在处理时间序列数据时至关重要&#xff0c;能够灵活解析多种日期格式并统一为标准时间类型。以下是其核心用法及…

数学建模:MATLAB强化学习

一、强化学习简述 强化学习是一种通过与环境交互&#xff0c;学习状态到行为的映射关系&#xff0c;以获得最大积累期望回报的方法。包含环境&#xff0c;动作和奖励三部分&#xff0c;本质是智能体通过与环境的交互&#xff0c;使得其作出的动作所得到的决策得到的总的奖励达…

【leetcode hot 100 160】相交链表

解法一&#xff1a;&#xff08;哈希集合&#xff09;利用HashSet保存一个链表的值&#xff0c;循环另一个列表&#xff0c;在HashSet中寻找该值。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x…

19. 大数据-技术生态简介

文章目录 前言一、Hadoop介绍1. 简介2. Hadoop发展史3. Hadoop现状 二、Hadoop特性1. Hadoop国外应用2. Hadoop国内应用 三、Hadoop架构变迁1. 发行版本2. Hadoop架构变迁(1.0-2.0变迁)3. Hadoop架构变迁(3.0新版本)4. 综述 四、技术生态体系 前言 大数据&#xff08;Big Data…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)示例3: 行选择

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

VsCode 快捷键备忘

移动光标及选择文本 Ctrl ← / → &#xff1a;以单词为单位移动游标Home / End&#xff1a;光标移到行首/行位Ctrl Home / End&#xff1a;光标移到文件首和文件尾Ctrl Shift \&#xff1a;在匹配的分隔符之间跳转 配对的分隔符 是指分隔代码元素的字符&#xff0c;比如字…

用数据唤醒深度好眠,时序数据库 TDengine 助力安提思脑科学研究

在智能医疗与脑科学快速发展的今天&#xff0c;高效的数据处理能力已成为突破创新的关键。安提思专注于睡眠监测与神经调控&#xff0c;基于人工智能和边缘计算&#xff0c;实现从生理体征监测、智能干预到效果评估的闭环。面对海量生理数据的存储与实时计算需求&#xff0c;安…

SQL_语法

1 数据库 1.1 新增 create database [if not exists] 数据库名; 1.2 删除 drop database [if exists] 数据库名; 1.3 查询 (1) 查看所有数据库 show databases; (2) 查看当前数据库下的所有表 show tables; 2 数据表 2.1 新增 (1) 创建表 create table [if not exists…

Qt 开发 OpenGL 程序流程

在用 Qt 开发 OpenGL 程序时&#xff0c;整体的工作流程分为几个关键步骤&#xff0c;最终目的是将数据传递给 GPU 并开始渲染。这一过程涉及到从代码编写到与着色器连接的多个操作&#xff0c;下面我将详细讲解每个步骤。 1. 设置 Qt 项目 这个步骤是准备工作&#xff0c;你首…

长短期记忆网络(LSTM)学习指南

长短期记忆网络&#xff08;LSTM&#xff09;学习指南 1. 定义和背景 长短期记忆网络&#xff08;Long Short-Term Memory, LSTM&#xff09;是一种递归神经网络&#xff08;RNN&#xff09;的变体&#xff0c;旨在解决传统RNN在处理长期依赖关系时遇到的梯度消失或爆炸问题。…

仿12306项目(4)

基本预定车票功能的开发 对于乘客购票来说&#xff0c;需要有每一个车次的余票信息&#xff0c;展示给乘客&#xff0c;供乘客选择&#xff0c;因此首个功能是余票的初始化&#xff0c;之后是余票查询&#xff0c;这两个都是控台端。对于会员端的购票&#xff0c;需要有余票查询…

第十二届蓝桥杯 异或数列

原题&#xff1a; https://www.acwing.com/problem/content/3424/ 题目大意&#xff1a; A、B两人的数初始值均为0&#xff0c;他们轮流从X数组中取数&#xff0c;可以将该数与自己的数或对方的数进行异或操作&#xff0c;A先手&#xff0c;当X中的数被取完的时候谁的数大谁…

微服务的认识与拆分

微服务架构通过将应用分解为一组小的、独立的服务来实现&#xff0c;每个服务围绕特定业务功能构建&#xff0c;并能独立部署与扩展。这种架构增强了开发灵活性、提高了系统的可维护性和扩展性&#xff0c;使得团队可以更快地响应变化和市场需求。 目录 认识微服务 单体架构 …

高效编程指南:PyCharm与DeepSeek的完美结合

DeepSeek接入Pycharm 前几天DeepSeek的充值窗口又悄悄的开放了&#xff0c;这也就意味着我们又可以丝滑的使用DeepSeek的API进行各种辅助性工作了。本文我们来聊聊如何在代码编辑器中使用DeepSeek自动生成代码。 注&#xff1a;本文适用于所有的JetBrains开发工具&#xff0c…