使用mouse_event函数实现鼠标点击模拟

Gameisover

发布日期: 2018-11-21 09:10:54 浏览量: 1342
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

背景

如果你对外挂有过一些了解,那么鼠标、键盘的模拟功能,肯定是学外挂的入门必修技术。所谓的鼠标模拟、键盘模拟,就是不需要物理点击、物理按键,纯粹使用编程手段,实现和物理点击、物理按键相同功能的操作。

当然,根据使用的编程技术,不同模拟效果也不同。初学者必修的当然是在应用层使用mouse_event、keybd_event、SendMessage等函数实现,厉害的大牛,就会在内核层里进行操作。本文就不深入介绍了,先讲解简单介绍的使用mouse_event函数实现鼠标模拟。现在把实现思路和实现过程,写成文档分享给大家。

函数介绍

SetCursorPos 函数

把光标移到屏幕的指定位置。

函数声明

  1. BOOL SetCursorPos(
  2. int X,
  3. int Y
  4. );

参数

  • X

    指定光标的新的X坐标,以屏幕坐标表示。

  • Y

    指定光标的新的Y坐标,以屏幕坐标表示。

返回值

  • 如果成功,返回非零值;
  • 如果失败,返回值是零,若想获得更多错误信息,请调用GetLastError函数。

mouse_event 函数

综合鼠标移动和按钮点击。

函数声明

  1. VOID mouse_event(
  2. DWORD dwFlags, // motion and click options
  3. DWORD dx, // horizontal position or change
  4. DWORD dy, // vertical position or change
  5. DWORD dwData, // wheel movement
  6. ULONG_PTR dwExtraInfo // application-defined information
  7. );

参数

  • 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 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。

编码实现

鼠标左键单击

  1. // 鼠标左键单击: 按下 和 弹起
  2. BOOL SimulateMouse_LeftClick(int x, int y)
  3. {
  4. BOOL bRet = ::SetCursorPos(x, y);
  5. if (bRet)
  6. {
  7. // 鼠标左键按下
  8. ::mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
  9. // 时间间隔
  10. Sleep(20);
  11. // 鼠标左键弹起
  12. ::mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
  13. }
  14. return bRet;
  15. }

鼠标左键双击

  1. // 鼠标左键双击: 按下 和 弹起
  2. BOOL SimulateMouse_LeftDoubleClick(int x, int y)
  3. {
  4. BOOL bRet = FALSE;
  5. // 双击就是两个频率较快的单击组成
  6. // 第一个单击操作
  7. bRet = SimulateMouse_LeftClick(x, y);
  8. // 时间间隔
  9. Sleep(40);
  10. // 第二个单击操作
  11. bRet = SimulateMouse_LeftClick(x, y);
  12. return bRet;
  13. }

鼠标右键单击

  1. // 鼠标右键单击: 按下 和 弹起
  2. BOOL SimulateMouse_RightClick(int x, int y)
  3. {
  4. BOOL bRet = ::SetCursorPos(x, y);
  5. if (bRet)
  6. {
  7. // 鼠标右键按下
  8. ::mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
  9. // 时间间隔
  10. Sleep(20);
  11. // 鼠标右键弹起
  12. ::mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
  13. }
  14. return bRet;
  15. }

鼠标右键双击

  1. // 鼠标右键双击: 按下 和 弹起
  2. BOOL SimulateMouse_RightDoubleClick(int x, int y)
  3. {
  4. BOOL bRet = FALSE;
  5. // 双击就是两个频率较快的单击组成
  6. // 第一个单击操作
  7. bRet = SimulateMouse_RightClick(x, y);
  8. // 时间间隔
  9. Sleep(40);
  10. // 第二个单击操作
  11. bRet = SimulateMouse_RightClick(x, y);
  12. return bRet;
  13. }

程序测试

由于是一个功能性较强的程序,不能用截图的方式进行展示,所以,在此就没有贴图了,大家可以自己按照上面的原理和代码,自己写一个来感受感受吧。

总结

这个程序,主要是理解 SetCursorPos 和 mouse_event 这两个API函数的使用方式。其中,要注意的是 mouse_event 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。

在测试程序的时候,鼠标的双击操作一直测试不成功,后来,以管理员权限运行程序,测试双击操作,这时就成功了。所以,如果,测试程序的时候,达不到效果,可以试试以管理员权限运行程序测试看看。

参考

参考自《Windows黑客编程技术详解》一书

上传的附件 cloud_download mouse_event_Test.7z ( 143.36kb, 12次下载 )

发送私信

修行的路总是孤独的,因为智慧必然来自孤独

8
文章数
11
评论数
最近文章
eject