C#采用mouse_event函数实现模拟鼠标功能

下面我通过代码为大家分享下C#模拟鼠标,具体内容如下:

想必有很多人在项目开发中可能遇见需要做模拟鼠标点击的小功能,很多人会在百度过后采用mouse_event这个函数,不过我并不想讨论如何去使用mouse_event函数怎么去使用,因为那没有多大意义。

static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo)
{
 int x = dx, y = dy;
 edit_position(dwFlags, dx, dy, ref x, ref y);
 IntPtr hWndFromPoint = WindowFromPoint(x, y);
 screen_to_client(hWndFromPoint, ref x, ref y);
 send_message(hWndFromPoint, dwFlags, cButtons, x, y);
}

上述代码你发现了什么?如果你发现说明你知道了本文到底在写什么东东 说不定你会有一些兴趣看下去,不过想到我如今混那么凄惨 在工地上做干活 不过也还好。

鼠标点击目标时会向鼠标所点击目标窗口投递消息,根据鼠标的按键、状态不同会投递不同的消息,一个完整的“鼠标左键单击”事件过程为“WM_LBUTTONDOWN +

WM_LBUTTONUP”即鼠标“先左键按下 + 后左键抬起”,由于mouse_event可以模拟鼠标点击过程而不是直接性一次完整的鼠标单击过程,所以同样存在“按下、抬起”

mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE, -450, 0, 1, 0); 
mouse_event在没有提供MOUSEEVENTF_MOVE量时光标不会移动到相对位置,“光标相对位置=光标现行位置+新光标位置”如果提供量“MOUSEEVENTF_ABSOLUTE”绝对位置,则会以“新光标位置”为准而不会添加“光标现行位置”

static void edit_position(int dwFlags, int dx, int dy, ref int x, ref int y)
{
 Point pos = MousePosition;
 x = x + pos.X;
 y = y + pos.Y;
 if ((dwFlags | MOUSEEVENTF_ABSOLUTE) == dwFlags)
  SetCursorPos(dx, dy);
 if ((dwFlags | MOUSEEVENTF_MOVE) == dwFlags)
  SetCursorPos(x, y);
}

edit_position函数主要用于对MOUSEEVENTF_MOVE于MOUSEEVENTF_ABSOLUTE

相对/绝对光标位置修改的一个支持

static void send_message(IntPtr hWnd, int dwFlags, int cButtons, int x, int y)
{
 if ((dwFlags | MOUSEEVENTF_LEFTDOWN) == dwFlags)
  SendMessage(hWnd, WM_LBUTTONDOWN, cButtons, MakeDWord(x, y));
 if ((dwFlags | MOUSEEVENTF_LEFTUP) == dwFlags)
  SendMessage(hWnd, WM_LBUTTONUP, cButtons, MakeDWord(x, y));
 if ((dwFlags | MOUSEEVENTF_RIGHTDOWN) == dwFlags)
  SendMessage(hWnd, WM_RBUTTONDOWN, cButtons, MakeDWord(x, y));
 if ((dwFlags | MOUSEEVENTF_RIGHTUP) == dwFlags)
  SendMessage(hWnd, WM_RBUTTONUP, cButtons, MakeDWord(x, y));
 if ((dwFlags | MOUSEEVENTF_MIDDLEDOWN) == dwFlags)
  SendMessage(hWnd, WM_MBUTTONDOWN, cButtons, MakeDWord(x, y));
 if ((dwFlags | MOUSEEVENTF_MIDDLEUP) == dwFlags)
  SendMessage(hWnd, WM_MBUTTONUP, cButtons, MakeDWord(x, y));
}

send_message函数主要用于模拟鼠标点击的过程,上面我提到“先左键按下 + 后左键抬起”在上面的代码中你会看的清楚的不得了,如果相反你可以去尝试一番会有什么后果与其说

不如你们自己做更要来的快些。

static int MakeDWord(int low, int high)
{
 return low + (high * Abs(~ushort.MaxValue));
}
static int Abs(int value)
{
 return ((value >> 31) ^ value) - (value >> 31);
}
MakeDWord / 合并整数,函数主要是把两个short合并为一个int,分为low、high两部分

static bool screen_to_client(IntPtr hwnd, ref int x, ref int y)
{
 bool bRetVal = false;
 Point lpptPos = new Point(x, y);
 if ((bRetVal = ScreenToClient(hwnd, ref lpptPos)))
 {
  x = lpptPos.X;
  y = lpptPos.Y;
 }
 return bRetVal;
}
screen_to_client函数故名思意,它主要用于把屏幕上的坐标转换到窗口客户上对应坐标
public const int WM_LBUTTONDOWN = 513; // 鼠标左键按下
public const int WM_LBUTTONUP = 514; // 鼠标左键抬起
public const int WM_RBUTTONDOWN = 516; // 鼠标右键按下
public const int WM_RBUTTONUP = 517; // 鼠标右键抬起
public const int WM_MBUTTONDOWN = 519; // 鼠标中键按下
public const int WM_MBUTTONUP = 520; // 鼠标中键抬起
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; // 绝对坐标 

[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
[DllImport("user32.dll", SetLastError = true)]
public static extern int SetCursorPos(int x, int y);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool ScreenToClient(IntPtr hWnd, ref Point lppt);
// [DllImport("user32", SetLastError = true)]
// public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

鼠标右键单击(静默):

代码如下:

mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 1, 0);

鼠标左键双击(静默):

代码如下:

mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 2, 0);

鼠标移动(相对位置):

代码如下:

mouse_event(MOUSEEVENTF_MOVE, 100, 50, 0, 0);

鼠标移动(绝对位置):

代码如下:

mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 50, 0, 0);

以上内容比较多请认真学习,希望能够帮助到大家。

(0)

相关推荐

  • 详解C#中通过委托来实现回调函数功能的方法

    委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针. 回调函数 c++中的回调函数,就是用函数指针来实现的.类似的,c#中用委托,来实现回调函数的功能. 回调函数为什么被称为回调函数?比如你调用了一个函数,那么就叫调用,但是如果你在调用一个函数的时候,还需要把一个函数提供给该函数,让这个函数来调用你的函数,那么你提供的这个函数就被称为回调函数(callback). 对于python这样的动态语言而言,就没有c#,c++提供特殊的语法实现回调函数,因为在pytho

  • C# 函数覆盖总结学习(推荐)

    覆盖类成员:通过new关键字修饰虚函数表示覆盖该虚函数. 一个虚函数被覆盖后,任何父类变量都不能访问该虚函数的具体实现. public virtual void IntroduceMyself(){...}//父类虚函数 public new void IntroduceMyself(){...}//子类覆盖父类虚函数 using System; using System.Collections.Generic; using System.Linq; using System.Text; nam

  • C#中Arraylist的sort函数用法实例分析

    本文实例讲述了C#中Arraylist的sort函数用法.分享给大家供大家参考.具体如下: ArrayList的sort函数有几种比较常用的重载: 1.不带参数 2.带一个参数 public virtual void Sort( IComparer comparer ) 参数 comparer 类型:System.Collections.IComparer 比较元素时要使用的 IComparer 实现. - 或 - null 引用(Visual Basic 中为 Nothing)将使用每个元数的

  • C#中析构函数、Dispose、Close方法的区别

    一.Close与Dispose这两种方法的区别 调用完了对象的Close方法后,此对象有可能被重新进行使用:而Dispose方法来说,此对象所占有的资源需要被标记为无用了,也就是此对象要被销毁,不能再被使用.例如常见.Net类库中的SqlConnection这个类,当调用完Close方法后,可以通过Open重新打开一个数据库连接,当彻底不用这个对象了就可以调用Dispose方法来标记此对象无用,等待GC回收. 二.三者的区别如图 析构函数 Dispose方法 Close方法 意义 销毁对象 销毁

  • C# 文件操作函数 创建文件 判断存在

    文件创建: 复制代码 代码如下: File.Create(Application.StartupPath + "\\AlarmSet.txt");//创建该文件 System.IO.Path.GetFileName(filePath)       //返回带扩展名的文件名 System.IO.Path.GetFileNameWithoutExtension(filePath)     //返回不带扩展名的文件名 System.IO.Path.GetDirectoryName(fileP

  • 全面解读C#编程中的析构函数用法

    析构函数用于析构类的实例. 备注 不能在结构中定义析构函数.只能对类使用析构函数. 一个类只能有一个析构函数. 无法继承或重载析构函数. 无法调用析构函数.它们是被自动调用的. 析构函数既没有修饰符,也没有参数. 例如,下面是类 Car 的析构函数的声明: class Car { ~Car() // destructor { // cleanup statements... } } 该析构函数隐式地对对象的基类调用 Finalize.这样,前面的析构函数代码被隐式地转换为以下代码: protec

  • 解析C#中的私有构造函数和静态构造函数

    私有构造函数 私有构造函数是一种特殊的实例构造函数.它通常用在只包含静态成员的类中.如果类具有一个或多个私有构造函数而没有公共构造函数,则其他类(除嵌套类外)无法创建该类的实例.例如: class NLog { // Private Constructor: private NLog() { } public static double e = Math.E; //2.71828... } 声明空构造函数可阻止自动生成默认构造函数.注意,如果您不对构造函数使用访问修饰符,则在默认情况下它仍为私有

  • C#采用mouse_event函数实现模拟鼠标功能

    下面我通过代码为大家分享下C#模拟鼠标,具体内容如下: 想必有很多人在项目开发中可能遇见需要做模拟鼠标点击的小功能,很多人会在百度过后采用mouse_event这个函数,不过我并不想讨论如何去使用mouse_event函数怎么去使用,因为那没有多大意义. static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo) { int x = dx, y = dy; edit_position(dw

  • python PyAutoGUI 模拟鼠标键盘操作和截屏功能

    简介 一款跨平台/无依赖的自动化测试工具,目测只能控制鼠标/键盘/获取屏幕尺寸/弹出消息框/截屏. 安装 pip install pyautogui 鼠标键盘控制 >>> import pyautogui >>> screenWidth, screenHeight = pyautogui.size() >>> currentMouseX, currentMouseY = pyautogui.position() >>> pyautog

  • python之模拟鼠标键盘动作具体实现

    上个月就打算开发个还算好玩的项目,但是一直没时间.这篇是此项目用到的一部分, 处理好此部分基本还差通信等方面的了.首先模拟鼠标键盘按下释放的动作,本人利用X11 这个库,所以要了解X11编程;其次,本身用c或者c++就可以实现了,但是由于本人是py 粉,所以总想把代码搬进python,所以本人就要实现python模块,本篇用的ctypes,以后会 把python的c扩展模块附上来的. 1.X11编程 首先简单的介绍一下X11吧,网上有介绍,本人就不重复了.我们知道X是以server与client

  • 模拟鼠标事件的实现思路及代码

    模拟鼠标事件,一般可以通过mouse_event()和SendInPut()两种方法.mouse_event()在windows后期版本中逐渐被SendInPut()取代.SendInPut()模拟鼠标移动的事件中,标志位取值不同,输入坐标的意义也不同.简单来说就是,添加MOUSEEVENTF_ABSOLUTE标志位表示鼠标移动是通过绝对坐标定位,此时的坐标要通过转换.光标在屏幕中被分成65535个小块,可以通过如下转换: 复制代码 代码如下: double fx = x *(65535.0f

  • C# SendInput 模拟鼠标操作的实现方法

    刚刚开始学习C#,想自己做一个网页游戏的挂.游戏里面有收钱的动作,一个建筑物一个建筑物的点,很累啊.于是想用C#模拟鼠标操作替我收钱,想着学习这个对以后的测试工作也有帮助,于是有了动力.学习过程也是曲折的,因为网上搜了半天资料很少.该游戏是Flash的,用sendmessage不行,因为取不到里面的对象.查到有些介绍Mouse_Event的文章,但是msdn上说已经过时.于是查到了SendInput函数. 废话少说,上代码: 首先看下 Win API 中SendInput函数描述: 复制代码 代

  • 用pywin32实现windows模拟鼠标及键盘动作

    因为要批量用某软件处理一批eps文件,所以要模拟鼠标及键盘动作,使其能够自动化操作. 复制代码 代码如下: #-*-coding:utf-8-*-import osimport timeimport win32guiimport win32apiimport win32confrom PIL import ImageGrab #os.startfile("D:\\artcut6\\Prog\\Artcut6.exe")#time.sleep(1) wdname1=u"文泰刻绘

  • PHP采用自定义函数实现遍历目录下所有文件的方法

    目录的遍历是PHP程序设计中经常会用到的一个功能,很多PHP项目都有这一功能模块.今天本文就来实例解析一下PHP采用自定义函数实现遍历目录下所有文件的方法.具体方法如下: 方法一:使用readir()遍历目录 实现代码如下: function listDir($dir) { if(is_dir($dir)) { if($handle = opendir($dir)) { while($file = readdir($handle)) { if($file != '.' && $file !

  • Python使用win32com实现的模拟浏览器功能示例

    本文实例讲述了Python使用win32com实现的模拟浏览器功能.分享给大家供大家参考,具体如下: # -*- coding:UTF-8 -*- #!/user/bin/env python ''' Created on 2010-9-1 @author: chenzehe ''' import win32com.client from time import sleep loginurl='http://passport.cnblogs.com/login.aspx' loginouturl

  • python模拟鼠标拖动操作的方法

    本文实例讲述了python模拟鼠标拖动操作的方法.分享给大家供大家参考.具体如下: pdf中的书签只有页码,准备把现有书签拖到一个目录中,然后添加自己页签.重复的拖动工作实在无趣,还是让程序帮我实现吧,我可以喝点水,休息一下了 1. Python代码 复制代码 代码如下: # # _*_ coding:UTF-8 _*_ __author__ = 'wp' import win32api import win32con import win32gui from ctypes import * i

  • Android用HandlerThread模拟AsyncTask功能(ThreadTask)

    前言 AsyncTask是个好东西,能处理绝大多数应用线程和更新UI的任务,由于其内部使用了静态线程池,如果你有一堆异步任务(例如全局定时更新数据.同一个Activity中多个AsyncTask同时执行)其中有不能马上执行完的情况(例如网络请求超时),那就糟了,其他任务都还等着呢,就会出现任务卡住的情况.此时就需要直接上Thread了,这里参考AsyncTask的API封装了一个ThreadTask,便于必要时代码替换,欢迎交流!  正文实例代码: import android.os.Handl

随机推荐