《windows 程序设计》中所讲的:
当按钮被按下时,会产生 WM_COMMAND 消息;
当菜单项或者菜单项所对应的快捷键被按下时,也会产生 WM_COMMAND 消息。可是我用SPY++查了一下,除了“记事本”的菜单项产生 WM_COMMAND 消息以外,大部分程序的菜单项都不产生 WM_COMMAND 消息,而且好像所有的按钮都不产生WM_COMMAND消息。这是为什么啊?是不是控件的机制已经改变了?请大家给我讲讲吧!

解决方案 »

  1.   

    不会的,除非是自定义的窗口类才能控制不发送WM_COMMAND。
    至于标准的按钮和菜单,一般都是通过WM_COMMAND来传送命令的,而且在程序设计的时候也是通过处理WM_COMMAND来完成处理命令事件的。
    不妨把你如何使用Spy++的过程贴出来,让大家帮你分析一下。
      

  2.   

    WM_COMMAND消息是发送给父窗口的
      

  3.   

    菜单显示过程中的消息  用户单击菜单栏上的一项,父窗口接收到WM_INITITEM消息(在这个消息中可以绘制菜单),然后弹出菜单。当鼠标指向一个可以弹出子菜单的菜单项时,父窗口接收到WM_INITMENUPOPUP(可捕获此消息绘制子菜单),然后弹出子菜单。当鼠标在菜单上移动时,父窗口接收到WM_MENUSELECT消息,该消息中包含有当前的菜单项的索引号,可以对其进行引用。单击一个菜单项,产生WM_COMMAND消息,单击一个风格为MNS_NOTIFYBYPOS的菜单项,产生WM_MENUCOMMAND消息,该消息除了提供WM_COMMAND消息提供的数据外还额外添加了一个MENUINFO结构。右键弹出菜单发送WM_CONTEXTMENU消息。用户在一个菜单项上右击鼠标将产生WM_MENURBUTTONUP消息(例如在IE的收藏菜单的菜单项上右击弹出菜单的效果就可以通过捕获该消息实现)
      

  4.   

    多谢大家的讲解,我不知道WM_COMMAND消息是发送给父窗口的,所以用spy++的时候没有选择父窗体。 三楼的大哥讲解得很细,谢谢了。小弟还有一个问题,我想截获鼠标所点的菜单项的WM_COMMAND,应该怎样才能拦截到呢?(我以前用的是消息钩子,不过没有拦截到)。
      

  5.   

    如果在自己的进程里,重载父窗口的PreTranslateMessage
    switch(msg.message)  //具体忘了,看看就知道
    {
    case WM_COMMAND:
         return TRUE;
    }如果是其他进程,用hook注入
    ::SetWindowsHookEx(WH_MSGFILTER, lpfn, g_hModule, dwThreadID)
    lpfn是你自己的实现函数,里面和PreTranslateMessage一样
      

  6.   

    http://search.csdn.net/Expert/topic/1948/1948279.xml?temp=9.028262E-02