各位大虾,我在对话框中使用菜单,这个菜单是按一个按钮时弹出,我用在codeguru.com中获得的一个类:CBmpMenu,使得点击一个按钮,就弹出菜单,现在我要实现对于菜单某一项点一下,打上勾,再点一下,取消勾,我使用http://www.csdn.net/expert/topic/159/159863.shtm(急死人了50分!!如何在给对话框菜单中的选项打上选定小勾(checked)??)中jerry_mouse() 的方法,却没有反应,但如果将此菜单编程对话框系统菜单,(不使用点击按钮弹出方式)就可以搞定。我不只是为什么?
附:代码:例如,实现菜单IDR_MENU_OPTION1中项Set Timer的打勾void CMyDlg::OnBtnOpenMenu1() //button点击,打开菜单!
{
// TODO: Add your control notification handler code here
  CBmpMenu oMenu;
oMenu.LoadMenu(IDR_MENU_OPTION1); CPoint pt;
GetCursorPos(&pt);
oMenu.TrackPopupMenu(0, pt.x, pt.y, this);
}void CMyDlg::OnUpdateMenuSetTimer(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
    CBmpMenu oMenu;
    oMenu.LoadMenu(IDR_MENU_OPTION1);
    if (btest==true)
oMenu.CheckMenuItem(ID_MENU_SETTIMER,MF_CHECKED);
    else oMenu.CheckMenuItem(ID_MENU_SETTIMER,MF_UNCHECKED);
}void CMyDlg::OnMenuSetTimer() 
{// TODO: Add your command handler code here
btest=!btest;//btest的初始值为false;}多谢帮忙!

解决方案 »

  1.   

    这个问题以前遇到过,但总是解决不了,sigh....
      

  2.   

    问题可能在CBmpMenu类本身,仔细看他的代码把!!!
      

  3.   

    PRB: Update Command UI Handlers Do Not Work for Menu Attached to a Dialog Box 
    ID: Q242577 
    --------------------------------------------------------------------------------
    The information in this article applies to:Microsoft Visual C++, 32-bit Editions, version 6.0, used with:
    The Microsoft Foundation Classes (MFC)--------------------------------------------------------------------------------
    SYMPTOMS
    Changing the state (enable/disable, check/uncheck, change text) of a menu item from its command user-interface (UI) handler does not work correctly if the menu is attached to a dialog box: 
    void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI) 
    {
        pCmdUI->Enable(FALSE); //Not calling the command handler, but does not show as disabled.
        pCmdUI->SetCheck(TRUE); // Does not show check  before the text.
        pCmdUI->SetRadio(TRUE); // Does not show dot before the text.
        pCmdUI->SetText("Close"); //Does not change the text.
    } CAUSE
    When a drop-down menu is displayed, the WM_INITMENUPOPUP message is sent prior to displaying the menu items. The MFC CFrameWnd::OnInitMenuPopup function iterates through the menu items and calls the update command UI handler for the item, if there is one. The appearance of each menu item is updated to reflect its state (enabled/disabled, checked/unchecked).The update UI mechanism doesn't work for a dialog box-based application because CDialog has no OnInitMenuPopup handler and it uses CWnd's default handler, which does not call update command UI handlers for menu items. RESOLUTION
    Use the following steps to resolve this problem: Add an ON_WM_INITMENUPOPUP entry to the message map: BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
    //{{AFX_MSG_MAP(CTestDlg)
                            ........................
                            ........................
    //}}AFX_MSG_MAP ON_WM_INITMENUPOPUP()
    END_MESSAGE_MAP() Add a OnInitMenuPopup member function to your dialog box class and copy the following code (note that this code is taken largely from CFrameWnd::OnInitMenuPopup in WinFrm.cpp): void CTestDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu)
    {
        ASSERT(pPopupMenu != NULL);
        // Check the enabled state of various menu items.    CCmdUI state;
        state.m_pMenu = pPopupMenu;
        ASSERT(state.m_pOther == NULL);
        ASSERT(state.m_pParentMenu == NULL);    // Determine if menu is popup in top-level menu and set m_pOther to
        // it if so (m_pParentMenu == NULL indicates that it is secondary popup).
        HMENU hParentMenu;
        if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
            state.m_pParentMenu = pPopupMenu;    // Parent == child for tracking popup.
        else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
        {
            CWnd* pParent = this;
               // Child windows don't have menus--need to go to the top!
            if (pParent != NULL &&
               (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
            {
               int nIndexMax = ::GetMenuItemCount(hParentMenu);
               for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
               {
                if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
                {
                    // When popup is found, m_pParentMenu is containing menu.
                    state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
                    break;
                }
               }
            }
        }    state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
        for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
          state.m_nIndex++)
        {
            state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
            if (state.m_nID == 0)
               continue; // Menu separator or invalid cmd - ignore it.        ASSERT(state.m_pOther == NULL);
            ASSERT(state.m_pMenu != NULL);
            if (state.m_nID == (UINT)-1)
            {
               // Possibly a popup menu, route to first item of that popup.
               state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
               if (state.m_pSubMenu == NULL ||
                (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
                state.m_nID == (UINT)-1)
               {
                continue;       // First item of popup can't be routed to.
               }
               state.DoUpdate(this, TRUE);   // Popups are never auto disabled.
            }
            else
            {
               // Normal menu item.
               // Auto enable/disable if frame window has m_bAutoMenuEnable
               // set and command is _not_ a system command.
               state.m_pSubMenu = NULL;
               state.DoUpdate(this, FALSE);
            }        // Adjust for menu deletions and additions.
            UINT nCount = pPopupMenu->GetMenuItemCount();
            if (nCount < state.m_nIndexMax)
            {
               state.m_nIndex -= (state.m_nIndexMax - nCount);
               while (state.m_nIndex < nCount &&
                pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
               {
                state.m_nIndex++;
               }
            }
            state.m_nIndexMax = nCount;
        }

    STATUS
    This behavior is by design. MORE INFORMATION
    The update command UI handler is also called from CWnd::OnCommand to make sure that command has not become disabled before routing. This is why the command handler is not called for a disabled menu item even though it is not grayed (unavailable). Menu items are not drawn to reflect their status in this case. This is the related code from the Wincore.cpp file: 
       // Make sure command has not become disabled before routing.
       CTestCmdUI state;
       state.m_nID = nID;
       OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);
       if (!state.m_bEnabled)
       {
          TRACE1("Warning: not executing disabled command %d\n", nID);
          return TRUE;
       } 
    Steps to Reproduce Behavior
    Create a dialog-based application by using AppWizard.
    Create a new menu resource and add the File and File/Exit menu items to it.
    Set this menu as the menu for the dialog box in properties.
    Add an UPDATE_COMMAND_UI handler for File/Exit menu item by using ClassWizard, and then add either one of the statements to the handler.
    pCmdUI->Enable(FALSE); //Not calling the handler, but does not show as disabled
    pCmdUI->SetCheck(TRUE); // Does not show check  before the text.
    pCmdUI->SetRadio(TRUE); // Does not show dot before the text.
    pCmdUI->SetText("Close"); //Does not change the text. Build and run the application.REFERENCES
    For additional information, click the article number below to view the article in the Microsoft Knowledge Base: Q141751 SAMPLE: Adding Control Bars to Dialog Boxes in MFC 
    &copy; Microsoft Corporation 9/29/1999, All Rights Reserved.
    Contributions by Sreedhar Pelluru, Microsoft Corporation
    Additional query words: WM_INITMENUPOPUP ON_UPDATE_COMMAND_UI Keywords : kbDlg kbMenu kbMFC KbUIDesign kbVC600 kbDSupport kbGrpMFCATL 
    Version : winnt:6.0 
    Platform : winnt 
    Issue type : kbprb 
    Technology : kbvc 
    Last Reviewed: February 4, 2000
    &copy; 2000 Microsoft Corporation. All rights reserved. Terms of Use.
     --------------------------------------------------------------------------------
    Send feedback to MSDN.Look here for MSDN Online resources.