none
多文档应用程序中关于菜单的问题 RRS feed

  • 问题

  • 做了一个多文档的应用程序,做了2个菜单资源 IDR_MAINFRAME和IDR_MAINFRAME1,在启动应用程序的时候:

    pDocTemplate = new CMultiDocTemplate(
    IDR_MAINFRAME1,
    RUNTIME_CLASS(CDocEditorDoc),
    RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
    RUNTIME_CLASS(CDocEditorView));
    if (!pDocTemplate)
    return FALSE;
    AddDocTemplate(pDocTemplate);

    在主框架创建的时候使用了另一个菜单资源

    // 创建主菜单
    CXTPMenuBar* pMenuBar = pCommandBars->SetMenu(_T("菜单"),IDR_MAINFRAME);
    if (!pMenuBar)
    {
    TRACE0(_T("创建主菜单失败\n"));
    return -1;
    }

    当我在程序中要手动控制菜单上的子菜单的置灰和不置灰,

    CMenu* pMenu = GetMenu();

    if(pMenu)

    {

    CMenu* pSubMenu = pMenu->GetSubMenu(0);
    if(pSubMenu)
    {
    UINT disable = (MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
    pSubMenu->EnableMenuItem(ID_FILE_NEWFILE,disable);
    pSubMenu->EnableMenuItem(ID_FILE_OPEN,disable);

    }

    }

    我要在打开一个文件的时候,获取菜单的指针,然后设置新建和打开两个子菜单为置灰,不能触发他们,不能使用ON_COMMAND_UPDATE_UI消息,因为我要将这个应用程序的主框架嵌入到ocx控件中。

    现在的问题是,如何获取这个菜单指针,现在获取的方式是pMenu  = NULL,我该如何获取?


    2013年12月24日 6:54

答案

  • 调试的时候g_nClientUnit  一直等于1,也执行了pCmdUI->Enable(FALSE);

    现在退出菜单的update消息响应了,原因是还没有到CDocEditorApp类处理,在其他地方就截获处理了,是消息处理的顺序影响了。现在退出菜单的置灰已经解决了,还没有解决的问题是OnUpdateRecentFileMenu,我想让他置灰?

    void CDocEditorApp::OnUpdateRecentFileMenu(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);
    
    }


    2013年12月27日 2:03
  • 经验尚浅,好像看到exit的更新消息在CDocument中系统默认处理了,我就在视图类里边提前响应了更新消息。

    OnUpdateRecentFileMenu()对应的是最近文件列表菜单0-16个不等,根据最近打开文件数量来动态的形成菜单,系统有自己的处理,我自己写的更新消息不起作用。至今也有没禁止掉最近文件列表子菜单。

    2014年1月16日 8:26

全部回复

  • 轻飏之风,

    你好!

    >>我要在打开一个文件的时候,获取菜单的指针,然后设置新建和打开两个子菜单为置灰,不能触发他们,不能使用ON_COMMAND_UPDATE_UI消息,因为我要将这个应用程序的主框架嵌入到ocx控件中。

    请问你是指ON_UPDATE_COMMAND_UI 吗?

    可是,根据这个帖子 Knowing the Menu ID how can I get a pointer to that menu in MFC 中的回复:

    “For each menu item there will be two handlers - one for ON_COMMAND and one for ON_UPDATE_COMMAND_UI.

    ON_COMMAND handler is called when the menu is clicked.
    ON_UPDATE_COMMAND_UI handler is called just before the menu is shown.
    Maintain a bool variable in the class. Let's call it checkMenu.So initially initialize it to false.
    In the ON_COMMAND handler, toggle this bool variable between true and false.
    In the ON_UPDATE_COMMAND_UI handler check the bool variable and decide if the menu has to checked or unchecked.”

    我想,最好还是使用 ON_UPDATE_COMMAND_UI .

    EDIT:

    以下为这个问题的一些相关链接,仅供参考:

    I need to Manipulate the Main Menu of an MFC MDI app, but...

    how to get the menu handle/pointer from view?

     

     


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2013年12月25日 5:30
    版主
  • 如果是要使用 ON_UPDATE_COMMAND_UI ,我想禁止掉新建、打开、退出等的标准命令,在更新消息函数中,不起作用?

    switch(nID)
    {
    case ID_FILE_NEWFILE:
    case ID_FILE_OPEN:
    case ID_FILE_CLOSE:
    case ID_FILE_CLOSEALL:
    case ID_STYLE_PRINT:
    case ID_FILE_PRINT:
    case ID_FILE_MRU_FILE1:
    case ID_FILE_MRU_FILE2:       
    case ID_FILE_MRU_FILE3:     
    case ID_FILE_MRU_FILE4:    
    case ID_FILE_MRU_FILE5:     
    case ID_FILE_MRU_FILE6:    
    case ID_FILE_MRU_FILE7:      
    case ID_FILE_MRU_FILE8:     
    case ID_FILE_MRU_FILE9:      
    case ID_FILE_MRU_FILE10:    
    case ID_FILE_MRU_FILE11:    
    case ID_FILE_MRU_FILE12:    
    case ID_FILE_MRU_FILE13:    
    case ID_FILE_MRU_FILE14:    
    case ID_FILE_MRU_FILE15:  
    case ID_FILE_MRU_FILE16:
    case ID_APP_EXIT:
    pCmdUI->Enable(FALSE);
    break;
    }

    2013年12月25日 6:51
  • 你好!

    感谢你的反馈。

    >>如果是要使用 ON_UPDATE_COMMAND_UI ,我想禁止掉新建、打开、退出等的标准命令,在更新消息函数中,不起作用?

    请问你现在的具体问题是什么?

    可否具体陈述一下?


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年12月25日 9:11
    版主
  • 目前是两个菜单,没有打开文档之前,显示的是一个菜单;打开文档之后,显示的是另外一个菜单。我想将新建、打开、关闭、全部关闭、文件列表、退出菜单禁止。我给标准命令增加了更新函数,发现新建、打开、关闭、全部关闭菜单都变灰了;但是文件列表在显示任何菜单时,都没有禁止掉菜单;退出菜单只能在没有打开文档的菜单中禁止掉了,打开文档之后的菜单没有禁止掉?我想把文件列表菜单和退出菜单不管在显示哪种菜单时,都禁止掉?

    代码:

    头文件声明:

    afx_msg void OnUpdateNewFile(CCmdUI* pCmdUI);
    afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI);
    afx_msg void OnUpdateFileClose(CCmdUI* pCmdUI);
    afx_msg void OnUpdateFileCloseAll(CCmdUI* pCmdUI);
    afx_msg void OnUpdateAppExit(CCmdUI* pCmdUI);
    afx_msg void OnUpdateRecentFileMenu(CCmdUI* pCmdUI);

    消息映射:

    ON_UPDATE_COMMAND_UI(ID_FILE_NEWFILE,&CDocEditorApp::OnUpdateNewFile)
    ON_UPDATE_COMMAND_UI(ID_FILE_OPEN,&CDocEditorApp::OnUpdateFileOpen)
    ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE,&CDocEditorApp::OnUpdateFileClose)
    ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEALL,&CDocEditorApp::OnUpdateFileCloseAll)
    ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, &CDocEditorApp::OnUpdateRecentFileMenu)
    ON_UPDATE_COMMAND_UI(ID_APP_EXIT, &CDocEditorApp::OnUpdateAppExit)

    函数实现:

    void CDocEditorApp::OnUpdateNewFile(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);

    }
    }
    void CDocEditorApp::OnUpdateFileOpen(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);

    }

    }
    void CDocEditorApp::OnUpdateFileClose(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);

    }
    }
    void CDocEditorApp::OnUpdateFileCloseAll(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);

    }
    }
    void CDocEditorApp::OnUpdateRecentFileMenu(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);

    }
    else
    {
    CWinApp::OnUpdateRecentFileMenu(pCmdUI);
    }

    }
    void CDocEditorApp::OnUpdateAppExit(CCmdUI* pCmdUI)
    {
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);
    }
    }

    我在调试的时候将g_nClientUnit  = 1;他是全局变量,在没有关闭应用程序的过程中g_nClientUnit  一直等于1

    显示效果

    2013年12月26日 1:48
  • >>我在调试的时候将g_nClientUnit  = 1;他是全局变量,在没有关闭应用程序的过程中g_nClientUnit  一直等于1

    请问,你在以下代码中设置断点后,可以看到g_nClientUnit 仍是以1 传入的吗?

    void CDocEditorApp::OnUpdateAppExit(CCmdUI* pCmdUI)
     {
             if(g_nClientUnit != 0)
                 {
                     pCmdUI->Enable(FALSE);
                 }
     } 


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年12月26日 9:39
    版主
  • 调试的时候g_nClientUnit  一直等于1,也执行了pCmdUI->Enable(FALSE);

    现在退出菜单的update消息响应了,原因是还没有到CDocEditorApp类处理,在其他地方就截获处理了,是消息处理的顺序影响了。现在退出菜单的置灰已经解决了,还没有解决的问题是OnUpdateRecentFileMenu,我想让他置灰?

    void CDocEditorApp::OnUpdateRecentFileMenu(CCmdUI* pCmdUI)
    {
    if(!pCmdUI)
    {
    return;
    }
    if(g_nClientUnit != 0)
    {
    pCmdUI->Enable(FALSE);
    
    }


    2013年12月27日 2:03
  • 你好,

    请问,你的exit消息响应函数是如何被截获处理的?怎样通过更改消息处理顺序实现的呢?

    OnUpdateRecentFileMenu对应的是哪个菜单项?可不可以通过类似的办法来实现?

    void CDocEditorApp::OnUpdateRecentFileMenu(CCmdUI* pCmdUI)
     {
            if(!pCmdUI)
              {
                 return;
              }
            if(g_nClientUnit != 0)
             {
                pCmdUI->Enable(FALSE);
    
              }
           else
             {
                CWinApp::OnUpdateRecentFileMenu(pCmdUI);
             }
    }

    另外,其它类中是否使用 OnUpdateRecentFileMenu ?

    可以设置断点跟踪消息处理。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年12月27日 3:28
    版主
  • 你好,

    请问你的问题得到解决了吗?

    因为此贴没有及时跟进,我暂时将其类型改为“常规讨论”。

    如果你的问题已经得到解决,可以点击上方改回“问题”,在此处分享你的解决方案,然后“标记为答复”。

    谢谢。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年1月6日 9:21
    版主
  • 经验尚浅,好像看到exit的更新消息在CDocument中系统默认处理了,我就在视图类里边提前响应了更新消息。

    OnUpdateRecentFileMenu()对应的是最近文件列表菜单0-16个不等,根据最近打开文件数量来动态的形成菜单,系统有自己的处理,我自己写的更新消息不起作用。至今也有没禁止掉最近文件列表子菜单。

    2014年1月16日 8:26