如何捕捉窗口按钮消息

时间:2024-03-26 16:23:32

如何捕捉一个未知窗口的按钮按下的消息?方法多种多样,这里我就介绍一种比较常见的方法——钩子。

原理上很简单也很容易理解,安装一个系统的全局钩子,过滤所有的系统消息,当然了,可以过滤制定的系统消息,比如按钮常用的发给窗口的WM_COMMAND消息,然后判断这个消息的一些属性,比如发给谁,谁发出的等,来判断这个消息是不是我们要找的消息。

首先第一步,我们要知道我们要监视的按钮发出了什么样的消息,这个任然可以用spy++查看,如下图:

如何捕捉窗口按钮消息

这个是宽带连接的窗口中“连接”按钮发送给宽带连接窗口的消息,注意其中有WM_COMMAND,这里监视的是宽带连接的消息。

那么我们就清楚了,“连接”按钮任然是使用WM_COMMAND消息的。下面第二步我们就要安装钩子监视这个消息,任然是用SetWindowsHookEx函数,但是使用的是WH_CALLWNDPROC类型的钩子,钩子的子程LRESULT CALLBACK KeyHookProc(int nCode,WPARAM wParam,LPARAM lParam)。

WH_CALLWNDPROC类型的钩子对应对应的钩子子程怎么写呢?查看MSDN我们发现子程是这样写的

nCode [in] Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and must return the value returned by CallNextHookEx. wParam [in] Specifies whether the message was sent by the current thread. If the message was sent by the current thread, it is nonzero; otherwise, it is zero. lParam [in] Pointer to a CWPSTRUCT structure that contains details about the message.

而CWPSTRUCT是这样定义的

typedef struct tagCWPSTRUCT {    L PARAM lParam;  / / 包含消息的附加说明    WPARAM wParam;  / / 包含消息的附加说明    UINT message ;  / / 消息    HWND hwnd ;  / / 接收消息的窗口句柄   } CWPSTRUCT ;


这下我们就知道了CWPSTRUCT中WParam 用来认证当前线程是否在发送消息。如果是的话,取非零值;否则,取0 。LParam 指向CWPSTRUCT 结构的指针,里面包含了消息相关的细节信息。所以当我们安装了一个全局钩子过滤所有的WM_COMMAND的消息之后可以通过lParam指向的tagCWPSTRUCT结构来判断是不是我们需要的消息,具体的钩子子程如下:

LPCWPSTRUCT lpmsg=(LPCWPSTRUCT)lParam; if(lpmsg->message==WM_COMMAND) { switch(LOWORD(lpmsg->wParam)) { case 0x0000636: //这个是“连接”按钮的控件ID,可以通过spy++得到 read(); //自定义函数 break ; } } return CallNextHookEx(0,nCode,wParam,lParam);

至于钩子怎么安装,就不要我在这边赘述了不知道的小朋友们可以去我之前的博客瞧瞧。

最后一句老话,菜鸟言论仅供娱乐。