# 使用mouse_event函数实现鼠标点击模拟
# 背景
如果你对外挂有过一些了解,那么鼠标、键盘的模拟功能,肯定是学外挂的入门必修技术。所谓的鼠标模拟、键盘模拟,就是不需要物理点击、物理按键,纯粹使用编程手段,实现和物理点击、物理按键相同功能的操作。
当然,根据使用的编程技术,不同模拟效果也不同。初学者必修的当然是在应用层使用mouse_event、keybd_event、SendMessage等函数实现,厉害的大牛,就会在内核层里进行操作。本文就不深入介绍了,先讲解简单介绍的使用mouse_event函数实现鼠标模拟。现在把实现思路和实现过程,写成文档分享给大家。
# 函数介绍
## SetCursorPos 函数
> 把光标移到屏幕的指定位置。
>
> 函数声明
>
> ```c++
> BOOL SetCursorPos(
> int X,
> int Y
> );
> ```
>
> 参数
>
> - X
>
> 指定光标的新的X坐标,以屏幕坐标表示。
>
> - Y
>
> 指定光标的新的Y坐标,以屏幕坐标表示。
>
> 返回值
>
> - 如果成功,返回非零值;
> - 如果失败,返回值是零,若想获得更多错误信息,请调用GetLastError函数。
## mouse_event 函数
> 综合鼠标移动和按钮点击。
>
> 函数声明
>
> ```c++
> VOID mouse_event(
> DWORD dwFlags, // motion and click options
> DWORD dx, // horizontal position or change
> DWORD dy, // vertical position or change
> DWORD dwData, // wheel movement
> ULONG_PTR dwExtraInfo // application-defined information
> );
> ```
>
> 参数
>
> - dwFlags
> 标志位集,指定点击按钮和鼠标动作的多种情况。此参数可以是下列值的某种组合:
>
> | VALUE | MEANING |
> | ---------------------- | ---------------------------------------- |
> | MOUSEEVENTF_ABSOLUTE | dX和dY参数含有规范化的绝对坐标。如果不设置,这些参数含有相对数据:相对于上次位置的改动位置。此标志可设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分 |
> | MOUSEEVENTF_MOVE | 这表示鼠标移动 |
> | MOUSEEVENTF_LEFTDOWN | 这表示鼠标左键按下 |
> | MOUSEEVENTF_LEFTUP | 这表示鼠标左键松开 |
> | MOUSEEVENTF_RIGHTDOWN | 这表示鼠标右键按下 |
> | MOUSEEVENTF_RIGHTUP | 这表示鼠标右键松开 |
> | MOUSEEVENTF_MIDDLEDOWN | 这表示鼠标中键按下 |
> | MOUSEEVENTF_MIDDLEUP | 这表示鼠标中键松开 |
> | MOUSEEVENTF_WHEEL | 这表示鼠标轮被滚动,如果鼠标有一个滚轮。滚动的数量由dwData给出 |
>
> - dx
> 指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
>
> - dy
> 指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
>
> - dwData
> 如果dwFlags为MOUSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。如果dwFlagsS不是MOUSEEVENTF_WHEEL,则dWData应为零。
>
> - dwExtralnfo
> 指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessageExtraInfo来获得此附加信息。
>
> 返回值
>
> - 无返回值。
# 实现原理
我们正常使用鼠标进行操作的时候,都是先将鼠标移动到要操作的位置,然后进行操作。
同样的,编码实现也是一样的,我们先要使用 SetCursorPos 函数,把光标移动到屏幕指定的位置坐标上,然后再使用 mouse_event 设置并执行操作的动作,例如鼠标左键按下、鼠标左键弹起等。这样,便完成模拟的操作。
其中,我们需要注意的是 mouse_event 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。
# 编码实现
## 鼠标左键单击
```c++
// 鼠标左键单击: 按下 和 弹起
BOOL SimulateMouse_LeftClick(int x, int y)
{
BOOL bRet = ::SetCursorPos(x, y);
if (bRet)
{
// 鼠标左键按下
::mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
// 时间间隔
Sleep(20);
// 鼠标左键弹起
::mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
return bRet;
}
```
## 鼠标左键双击
```c++
// 鼠标左键双击: 按下 和 弹起
BOOL SimulateMouse_LeftDoubleClick(int x, int y)
{
BOOL bRet = FALSE;
// 双击就是两个频率较快的单击组成
// 第一个单击操作
bRet = SimulateMouse_LeftClick(x, y);
// 时间间隔
Sleep(40);
// 第二个单击操作
bRet = SimulateMouse_LeftClick(x, y);
return bRet;
}
```
## 鼠标右键单击
```c++
// 鼠标右键单击: 按下 和 弹起
BOOL SimulateMouse_RightClick(int x, int y)
{
BOOL bRet = ::SetCursorPos(x, y);
if (bRet)
{
// 鼠标右键按下
::mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
// 时间间隔
Sleep(20);
// 鼠标右键弹起
::mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
}
return bRet;
}
```
## 鼠标右键双击
```c++
// 鼠标右键双击: 按下 和 弹起
BOOL SimulateMouse_RightDoubleClick(int x, int y)
{
BOOL bRet = FALSE;
// 双击就是两个频率较快的单击组成
// 第一个单击操作
bRet = SimulateMouse_RightClick(x, y);
// 时间间隔
Sleep(40);
// 第二个单击操作
bRet = SimulateMouse_RightClick(x, y);
return bRet;
}
```
# 程序测试
由于是一个功能性较强的程序,不能用截图的方式进行展示,所以,在此就没有贴图了,大家可以自己按照上面的原理和代码,自己写一个来感受感受吧。
# 总结
这个程序,主要是理解 SetCursorPos 和 mouse_event 这两个API函数的使用方式。其中,要注意的是 mouse_event 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。
在测试程序的时候,鼠标的双击操作一直测试不成功,后来,以管理员权限运行程序,测试双击操作,这时就成功了。所以,如果,测试程序的时候,达不到效果,可以试试以管理员权限运行程序测试看看。
# 参考
参考自《[Windows黑客编程技术详解](https://www.write-bug.com/article/1811.html "Windows黑客编程技术详解")》一书
精选_使用mouse_event函数实现鼠标点击模拟_源码打包
版权申诉
161 浏览量
2022-03-08
09:20:02
上传
评论
收藏 187KB ZIP 举报
工具盒子
- 粉丝: 58
- 资源: 1313