游戏辅助工具开发教程-从入门到精通之A3_7篇

一 2nd, 2010 | Filed under GameCheat

作者:Figo

本节我们继续学习键盘和鼠标编程基础,这次讲解的是热键注册和如何模拟键盘输入等有关知识。

Hot一词在英语中有火辣、炙手可热的含义,其实表达的意思就是很惹眼,等价到编程中,就是说HotKey产生的消息优先级最高,它不用去排什么消息队列,只要一有热键消息立马向注册此热键的程序发出WM_HOTKEY消息,同时把该消息扔到消息队列的第一位,比如金山词霸中的取词翻译设置。提到热键就需要区加速键:前者是系统全局的,这就决定了每个热键只能注册一次;后者是进程相关的,不同进程可以拥有相同的加速键,比如我们经常用的Ctrl+C[复制]。我们可以这样类比一下:系统如果是互联网的话,热键就是一级域名,新浪和搜狐就不可能使用同样的网址访问;加速键就是二级域名,比如新浪博客和搜狐博客的用户可以重名,因为加速键的作用域是整个进程,不同的加速键可以是实现同样的功能,正如一个人可以在新浪开两个博客一样:)。

和域名类似,热键需要用户主动向系统申请注册,如果没有程序注册过那么你就拥有了系统范围该热键的响应权,反之会提示注册失败。注册使用的API为:

BOOL RegisterHotKey(
HWND hWnd, //用户按下热键后接收热键消息WM_HOTKEY的窗口
int id, //热键标识ID,此处可以理解为域名,必须全局唯一
UINT fsModifiers, //组合键,可选值为MOD_ALT、MOD_CONTROL、MOD_SHIFT、MOD_WIN和NULL以及它们的组合
UINT vk //虚拟键,如F1、Sh和2的虚拟键值
);
此处需要补充说明的是第二个参数,标识ID,系统对于该参数有数值范围的要求:应用程序范围区间[0x0000,0xBFFF];共享DLL范围区间[0xC000,0xFFFF]。为了便于获得此ID,系统提供一个叫做GlobalAddAtom的函数来帮助用户产生一个系统范围没有使用的符合范围要求的标识ID,该函数声明为:ATOM GlobalAddAtom( LPCTSTR lpString );
编程人员需要提供一个用于产生ID的字符串,执行成功则返回生成的ID数值,否则返回0。

注册的热键在程序退出时要注销,否则会影响别的程序使用同样的热键,热键注销函数是:
BOOL UnregisterHotKey( HWND hWnd, int id );
本函数需要传递的参数与注册热键的前两个相同。不过,清理工作除了要注销热键还有注销热键标识ID,使用函数:
ATOM GlobalDeleteAtom( ATOM nAtom );
需要传递的参数是标识ID,此函数要在注销热键函数之后调用,否则会出错。

下面我们在上节程序的基础上编写一个支持热键和命令行参数的版本,当用户没有通过命令行参数配置程序时,程序使用默认的热键Alt+F3来隐藏/显示窗口。除了上面讲解函数,本次源码还引入了以下的函数:
1HWND GetTopWindow( HWND hWnd );
该函数用于获取顶层窗口的句柄,成功则返回传入参数指定的子窗口的句柄;如果传入参数为NULL,则返回屏幕Z轴顶端窗口的句柄。调用失败则返回NULL。
2HWND SetFocus( HWND hWnd );
该函数用于让传入参数指定句柄标识的窗口获取焦点,此处的焦点你可以理解为鼠标点击了那个窗口后窗口的状态,一般情况用于焦点的窗口标题栏是高亮的,否则是暗灰的。调用成功返回值是顶层窗口句柄,否则为NULL。
我们使用上面两个函数来实现当我们编写的窗口隐藏时候恢复顶层窗口焦点。

当按下热键时,系统会把该消息传递给注册热键的进程处理,对应的消息是WM_HOYKEY,我们在该消息下做一些自己感兴趣的事情,本程序中我们是隐藏窗口,我同时提供了打开指定网页和程序的源码,不过暂时注释掉了,感兴趣的读者可以自己试试效果:源码和Bin文件,点击下载

该程序命令行参数的测试方法为,开始菜单->运行->输入cmd->程序拖入cmd程序中->按下空格->输入参数。

参数可选的是:altwinctrlshift。默认和参数输入错误情况下热键为ALT+F3:首次按下热键时窗口隐藏,再次按下热键时窗口显示。
1
对于热键我最后补充几句:当你注册的热键和其他程序的加速键相同时,比如你注册了Ctrl+S为热键,而Word中保存文件的加速键也是Ctrl+S,此时系统范围的热键将导致程序的加速键失效。

热键讲完就该讲模拟输入了,在很多辅助工具里面都用到了该功能,比如模仿用户点击、走路等等,可以通过修改封包实现,也可通过模拟输入达到目的。对于键盘和鼠标的模拟操作Windows提供了两种操作模式:
1、古时代的利剑:keybd_eventmouse_event
2、后现代的火枪:SendInput
利剑固然好用,但是人多的时候一把剑杀人太慢了,这也是微软的态度:对于前者是不推荐,因为当需要有规律才大量模拟时,它太低效了;而建议编程者在NT/2000/XP等后现代操作系统中使用后者。本节呢,我们就利用利剑来制作一个魔兽争霸的显示血条的工具,和魔兽版本无关,要实现的功能如下:
1、支持热键启动和停止外挂功能;
2、显示敌我双方血条。
2
效果图
3

火枪放在后面讲,因为后面安排了一个专题涉及到;本次讲下利剑keybd_eventmouse_event。先来看下这两
个API的声明:

VOID keybd_event(
    BYTE bVk,//虚拟键代码,如VK_F1
    BYTE bScan,//扫描码,一般用0填充
    DWORD dwFlags,//键盘动作标志位:0表示按下;KEYEVENTF_KEYUP表示释放。我们常用的就这两个。
    PTR dwExtraInfo //附加信息,用0填充
);
比如要模拟F1键按下又释放的过程,代码如下:
... ...
keybd_event( VK_F1,  0,  0 , 0 );
keybd_event( VK_F1,  0,  KEYEVENTF_KEYUP , 0 );
... ...
VOID mouse_event(
    DWORD dwFlags, //鼠标动作标志,即指明鼠标是左键按下还是起来;鼠标是否移动等等,可选的组合
                              //参数见下面注释1
    DWORD dx, //当动作标志位有MOUSEEVENTF_ABSOLUTE标志时,该位指明屏幕坐标系的X坐标
    DWORD dy, //指明Y坐标
    DWORD dwData, //当dwFlags有MOUSEEVENTF_WHEEL时,dwData为负表示鼠标中间的滚轮向远
                              //离用户的方向滚动,否则为相反,一般用来模拟滚动条上下移动;
                              //当dwFlags有MOUSEEVENTF_HWHEEL时,dwData为负表示鼠标中间的滚轮向
                              //右滚动,否则为相反,一般用来模拟滚动条左右移动。
    ULONG_PTR dwExtraInfo //鼠标附加信息,使用GetMessageExtraInfo函数获取。
);
注释1:
MOUSEEVENTF_ABSOLUTE //指明下面坐标参考系为屏幕坐标系
MOUSEEVENTF_MOVE //鼠标移动
MOUSEEVENTF_LEFTDOWN //左键按下
MOUSEEVENTF_LEFTUP //左键松开
MOUSEEVENTF_RIGHTDOWN //右键按下
MOUSEEVENTF_RIGHTUP //右键松开
MOUSEEVENTF_MIDDLEDOWN //中间滑轮按下
MOUSEEVENTF_MIDDLEUP //中间滑轮松开
MOUSEEVENTF_WHEEL //滑轮竖直方向滚动
MOUSEEVENTF_HWHEEL //滑轮水平方向滚动,一般用来模拟滚动条的左右移动

下面的代码模拟左键在屏幕坐标点(100,100)出左键单击鼠标:
... ...
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN, 100, 100, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP, 100, 100, 0, 0);
... ...
在魔兽争霸显示血条的工具中,我模拟键盘的中括号“[”和“]”给程序发送按键消息,因为在魔兽争霸中,
他们是显血的快捷键。记住,这两个模拟函数的模拟操作的接收者是拥有焦点的窗口,
所谓拥有焦点就是当前激活的程序。

魔兽辅助工具和源码:点击下载。

转载请注明出处:http://www.figoyao.com/blog/2010/01/02/321/
  1. 给上帝的笔记本种个马
    一 2nd, 201021:42

    终于实战了,哈哈
    这个显血辅助上面的图片是哪位呢?猜猜^..^

  2. Figo
    一 3rd, 201008:16

    @给上帝的笔记本种个马
    好奇害死加菲猫:)

  3. mpgsf
    一 3rd, 201009:47

    感谢楼主,好好学习。

  4. Dong Li
    一 3rd, 201010:56

    赞师兄执着技术。
    我就在李老师实验室碰过代码,以后就没接触了。
    愧。

  5. WGJourney
    一 3rd, 201012:10

    感谢您写这么好的东西来分享,我是一直梦想着自己能写游戏的修改程序,但是一直无从下手,我仔细看了你每篇的教程,但是我悟性不够有的地方还是很难理解。我昨天去买了本范磊的C++全方位学习这本书还有王爽的汇编语言,我打算结合着书看您写的A1和A2部分。
    老大,加油 我会努力追逐的~

  6. Figo
    一 3rd, 201014:07

    @Dong Li
    代码不是生活的全部:)

  7. mpgsf
    一 3rd, 201015:06

    天天来老师的博客,非常感谢老师的无私奉献,能给我们一个指引,老师能给个QQ或信箱么?方便有问题时直接请教。

  8. Figo
    一 3rd, 201021:15

    @mpgsf
    很官腔的答复下:QQ暂时就免了,我时间不是很充裕,不可能当你的私人教师:)邮箱在博客早已公布了,但是仍然不能保证及时回复,望理解。

  9. 尘风
    二 4th, 201014:58

    开个QQ学习群,让大家互相讨论
    群号:20372561

  10. 镇关西
    六 24th, 201010:40

    我觉得这是给我帮助最大的一章 感谢FIGO老师
    尘风 你的群加不进去噢 我新开了高级群 欢迎大家加入探讨游戏修改知识
    QQ高级群:72953225
    欢迎喜欢游戏修改的朋友加入