ON_UPDATE_COMMAND_UI可以对弹出窗口用吗?

解决方案 »

  1.   

    右键菜单不响应ON_UPDATE_COMMAND_UI,如果你想控制右键菜单状态,在弹出前控制
      

  2.   

    在TrackPopupMenu调用前,向程序的主框架窗口发送一条WM_INITMENUPOPUP消息,用PostMessage, 具体格式要看帮助中的WM_INITMENUPOPUP。
      

  3.   

    右键菜单不响应ON_UPDATE_COMMAND_UI?
    我的程序却响应了:(。只是在菜单消失之后响应,而我想在菜单拉出之前就要控制。
      

  4.   

    在TracePopupMenu()调用之后直接进行控制不行吗?
      

  5.   

    TracePopupMenu()相当于DoModal()
    无法设置菜单状态
      

  6.   

    右键菜单的弹出应该由wm_contextmenu消息维护,她的坐标不用编成窗口坐标,非常方便
      

  7.   

    不要在WM_LBUTTONUP中调用TrackPopupMenu,而应在WM_CONTEXTMENU调用.
      

  8.   

    我做过一个菜单控件窗口。发现WM_UPDATE_COMMAND_UI是主框架窗口的OnIdlUpdateCommandUI函数执行时发出的。需要update command state的窗口,在WndProc函数中处理CN_UPDATE_COMMAND_UI消息(或CN_COMMAND_UI or CN_COMMAND, i'm not sure now), 此消息是在WM_UPDATE_COMMAND_UI消息之前发送的。一般的窗口不处理此消息,控制弹出菜单的窗口需自行处理该消息。而此时主框架窗口的对象指针被传了进来。在控制消息的过程中,你得逐个菜项去UpdateCommandState,调用方法:自己声明一个CCmdUI对象state,把菜单项的信息放进来,然后state.DoUpdate(pTarget, bDisableIfNoHandler), 其中pTarget和bDisableIfNoHandler是CN_UPDATE_COMMAND_UI消息传进来的。在state.DoUpdate()完成过程中,会触发WM_UPDATE_COMMAND_UI消息。当然,此消息的触发不光是菜单,更还会有ToolBar等所有具有发出WM_COMMAND消息的对象触发的。而UpdateCommandState不会由CMenu的对象自行动作。最后得说一下WM_INITPOPUPMENU会触发一个OnIdlUpdateComamndUI动作。这就是说,既使在TrackPopupMenu执行前就有OnUpdateCommandUI被执行到,如果没有你其控制窗口的配合,也不会改变菜单项的状态。以上方法实在太复杂,也太难描述清楚,但你可以用勾子勾得所有菜单弹出后的消息(就是你所说的象DoModal()之后的所有消息)。用以下语句:
    HHOOK hMsgHook = ::SetWindowsHookEx(WH_MSGFILTER,//这里可以是其它值,根据你自己的需要
    MenuInputFilter, NULL, AfxGetApp()->m_nThreadID); 
    pWndMsgWillBeHandled->PostMessage(WM_INITMENUPOPUP, (WPARAM)pMenuBePopup->GetSafeHmenu(),MAKELONG(iPos, bSysMenu)); //iPos = 0
    DWORD comm = ::TrackPopupMenu(pMenuBePopup->GetSafeHmenu(),
     TPM_LEFTALIGN  and  TPM_NONOTIFY  and  TPM_RETURNCMD,
     leftCoordinateOfScreen,
     topCoordinateOfScreen,
     0,
     pWndMsgWillBeHandled->GetSafeHwnd(),
     NULL);
     pWndMsgWillBeHandled->PostMessage(WM_COMMAND, comm);
     ::UnhookWindowsHookEx(hMsgHook);消息勾子函数:
    LRESULT CALLBACK MenuInputFilter(int code, WPARAM wParam, LPARAM lParam)
    {
     return (
    YourOnMenuInput( *((MSG*)lParam) )
    ) ? TRUE : CallNextHookEx(hMsgHook, code, wParam, lParam);
    }当然,你的hMsgHook最好是全局变量,在YourOnMenuInput(MSG*)中,你可以处理一切消息。