一、基于windows 消息机制的鼠标键盘模拟
(一)、应用程序级模拟(只针对某个程序,我称之为局部模拟)
windows提供了几个这样的API函数可以实现直接向目标程序发送消息的功能,常用的有SendMessage和PostMessage,它们的区别是PostMessage函数直接把消息仍给目标程序就不管了,而SendMessage把消息发出去后,还要等待目标程序返回些什么东西才好。这里要注意的是,模拟键盘消息一定要用PostMessage函数才好,用SendMessage是不正确的(因为模拟键盘消息是不需要返回值的,不然目标程序会没反应),切记切记!
PostMessage函数的delphi声明如下: PostMessage( hWnd: HWND; {目标程序上某个控件的句柄} Msg: UINT; {消息的类型} wParam: WPARAM; {32位指定附加的消息特定的信息} lParam: LPARAM {32位指定附加的消息特定的信息} ): BOOL;
参数hwnd 是你要发送消息的目标程序上某个控件的句柄,参数Msg 是消息的类型,表示你要发送什么样的消息,最后wParam 和lParam这两个参数是随消息附加的数据,具体内容要由消息决定。
(二)、系统级模拟(针对所有程序的窗口,我称之为全局模拟)
模拟全局键盘消息常见的可以有以下一些方法:
1、 用API函数keybd_event,这个函数可以用来模拟一个键盘事件
2、 SendInput函数也可以模拟全局键盘鼠标事件。
3、SendInput与WInIo的对比
WinIo的有很多缺点,SendInput几乎没有这些缺点。SendInput的模拟要比WinIo简单的多。事件是被直接插入到系统消息队列的,所以它的速度比WinIo要快。系统也会保证数据的完整性,不会出现数据包混乱的情况。利用“绝对移动”可以将鼠标指针移动到准确的位置,同鼠标的配置隔离不会出现兼容性的问题。SendInput的缺点也是最要命的,它会被一些程序屏蔽。所以说在SendInput与WInIo都可以使用的情况下优先考虑SendInput。另外SendInput与WInIo可以接合使用,一些程序对鼠标左键单击敏感,可以使用WinIo模拟鼠标左键单击,其它操作由SendInput模拟。
4、用全局钩子也可以模拟键盘消息。如果你对windows中消息钩子的用法已经有所了解,那么你可以通过设置一个全局HOOK来模拟键盘消息,比如,你可以用WH_JOURNALPLAYBACK这个钩子来模拟按键。WH_JOURNALPLAYBACK是一个系统级的全局钩子,它和WH_JOURNALRECORD的功能是相对的,常用它们来记录并回放键盘鼠标操作。WH_JOURNALRECORD钩子用来将键盘鼠标的操作忠实地记录下来,记录下来的信息可以保存到文件中,而WH_JOURNALPLAYBACK则可以重现这些操作。当然亦可以单独使用WH_JOURNALPLAYBACK来模拟键盘操作。
二、驱动级模拟
驱动级的只能模拟全局按键,不可以后台的哦,如果你非要winio的话,只能激活游戏窗口,进行按键,不可以后台的。
有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入。而windows消息由于是队列形式的,消息在传递时会有不少延迟,有时1秒钟也就传递十几条消息,这个速度达不到游戏的要求。而DirectInput则绕过了windows消息,直接与键盘驱动程序打交道,效率当然提高了不少。因此也就造成,对这样的程序无论用PostMessage或者是keybd_event都不会有反应,因为这些函数都在较高层。对于这样的程序,只好用直接读写键盘端口的方法来模拟硬件事件了。要用这个方法来模拟键盘,需要先了解一下键盘编程的相关知识。
在DOS时代,当用户按下或者放开一个键时,就会产生一个键盘中断(如果键盘中断是允许的),这样程序会跳转到BIOS中的键盘中断处理程序去执行。打开windows的设备管理器,可以查看到键盘控制器由两个端口控制。其中&H60是数据端口,可以读出键盘数据,而&H64是控制端口,用来发出控制信号。也就是,从&H60号端口可以读此键盘的按键信息,当从这个端口读取一个字节,该字节的低7位就是按键的扫描码,而高1位则表示是按下键还是释放键。当按下键时,最高位为0,称为通码,当释放键时,最高位为1,称为断码。既然从这个端口读数据可以获得按键信息,那么向这个端口写入数据就可以模拟按键了!用过QbASIC4.5的朋友可能知道,QB中有个OUT命令可以向指定端口写入数据,而INP函数可以读取指定端口的数据。
参考文章
1、https://www.cnblogs.com/bjxsky/p/3656076.html
2、https://www.cnblogs.com/Loofah/p/4167615.html
3、https://jingyan.baidu.com/article/642c9d34e55bd9644b46f74e.html