2009-07-07 34 views
2

为了跟踪用户活动,我使用Windows Hook作为主应用程序线程,并监视WM_COMMAND消息等等。WndProc挂钩没有从菜单接收WM_COMMAND

我按照预期从对话框按钮,工具栏按钮,加速器和弹出菜单接收它们,但是我没有从主菜单接收它们。

奇怪的是,Spy ++确实显示接收它们的主窗口。什么可能是错的?

安装钩子:

currentHook = SetWindowsHookEx(WH_CALLWNDPROC, 
           HookProc, 0, GetCurrentThreadId()); 

HOOKPROC,简约:

LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp) 
{ 
    CWPSTRUCT cwp = *(CWPSTRUCT *)lp; 
    if (cwp.message == WM_COMMAND) 
    { 
     ATLTRACE("[hook!] WM_COMMAND id=%d\n", LOWORD(cwp.wParam)); 
    } 
    return CallNextHookEx(currentHook, nCode, wp, lp); 
} 

(实际的代码更复杂,需要检查重入等,但我已经remvoed它这个测试)

任何想法?

[编辑]我测试的主窗口是一个MFC应用程序,但是测试代码不使用任何MFC。

+0

只是一个建议,但是有可能使用GetWindowLong和GWL_WNDPROC获取现有的WNDPROC,使用SetWindowLong将新的WNDPROC设置为您自己的自定义WNDPROC,并且在新的WNDPROC中使用CallWindowProc调用旧WNDPROC?这样你将获得绝对的所有窗口消息,而不必担心钩子。我不知道是否有可能,但我原本试图解决这个问题。 – dreamlax 2009-07-07 11:58:41

+0

@dreamlax:我已经尝试子分类,这工作正常。不过,我不得不在每个“相关”窗口的Create/OnInitDialog中添加一行,在这一点上 - 我仍然想避免。 – peterchen 2009-07-07 13:17:39

回答

6

菜单命令已发布,未发送(是的,文档在这方面相当不清楚 - 但Spy ++说明了事实)。而WH_CALLWNDPROC挂钩只捕获发送的消息。

您应该可以使用WH_GETMESSAGE钩子拦截张贴的消息。如果您想要处理WM_COMMAND这两种形式,您将需要需要

0

您是否尝试跟踪WM_MENUCOMMAND?

+0

要求为菜单设置MNS_NOTIFYBYPOS - 但我想避免项目中的代码/资源更改为仪器。另外,我必须弄清楚哪些WM_MENUCOMMAND消息没有跟随WM__COMMAND消息 - 听起来很丑陋 – peterchen 2009-07-07 11:52:43