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.pswp.cn/diannao/72742.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72742.shtml
英文地址,請注明出處:http://en.pswp.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…