用日志钩子处理键盘消息时的一个注意事项

来源:互联网 发布:cf卡数据恢复软件 mac 编辑:程序博客网 时间:2024/05/21 10:00

发现问题:

在日志钩子中调用GetKeyStateGetKeyboardState函数获取键盘状态信息,接着用OutputDebugString输出发现结果不正常。但是可以用ToAscii函数获取正确的字符信息,包括安下shiftCapital键的输出结果。

试着解释出现问题的原因:

Windows系统有一个系统消息队列,这个消息队列里的所有消息是输入设备动作产生的。

另外Windows为每个线程维护一个消息队列(如果有必要),Windows会检查系统消息队列里的所有消息,然后将系统消息队列里的消息派送到相应的线程消息队列,每个线程各自从自己的线程消息队列中获取消息处理。

JOURNALRECORD钩子只能是全局钩子,其对应的钩子函数记录系统消息队列中移除的所有消息:”The function records messages the system removes from the systemmessage queue.”

WH_KEYBOARD钩子可以是全局的或者局部的,其对应的钩子函数在线程从线程消息队列中取相关消息时被Windows调用:” The system calls this function whenever an application calls the GetMessageorPeekMessagefunction and there is a keyboard message (WM_KEYUPorWM_KEYDOWN)to be processed.”

 

所以对同一个消息,日志钩子的调用更先于键盘钩子,这造成了一些不同:

在键盘钩子函数里处理收到的WM_KEYUP消息时,如果调用GetKeyStateGetKeyboardState函数,查看返回值,会发现触发WM_KEYUP消息的按键的状态是按下的(返回值对应高位为1)。

但是在日志钩子里进行同样的处理,处理收到的WM_KEYUP消息时调用GetKeyStateGetKeyboardState函数,查看返回值,会发现触发WM_KEYUP消息的按键的状态是之前的,若是第一次按下此键,则返回值状态是释放状态(返回值对应高位为0)。

也就是说,用GetKeyStateGetKeyboardState函数检索虚拟键的状态,这个状态的变化发生在按键消息从系统消息队列中移除之后,消息到达应用程序之前。MSDN中有这样的描述:” The key status returned from this function changes as a threadreads key messages from its message queue.”

 

日志钩子函数的lParam参数说明:

lParam是一个EVENTMSG结构:

EVENTMSG      STRUCT

         message           DWORD            ?                          ;系统消息队列中将要移去的消息ID

         paramL              DWORD            ?                          ;消息的wParam参数

         paramH            DWORD            ?                          ;消息的lParam参数

         time                    DWORD            ?                          ;消息发生的时间

         hwnd                  DWORD            ?                          ;消息对应的窗口句柄

EVENTMSG      ENDS

.if      message>= WM_KEYFIRST  and  message <= WM_KEYLAST

         paramLand 00FFh 为虚拟键码

         paramLand 0FF00h为扫描码

         paramHand 00FFh 为扫描码

.endif

罗云彬老师的《windows环境下的32位汇编语言程序设计》日志钩子程序此处可能有问题,请看的同学注意。

 

题外话:这个问题困扰了我好几天,最近算是弄明白了点,但是并不是完全清楚,所以请看这篇文章的读者只做下参考。我以前完全没有Windows编程基础,最近学习Windows编程一直靠看罗老师的书和上网查资料,看了不到一个月,很多地方看的并不是明白,理解也不到位。

0 0
原创粉丝点击