如何在MFC应用程序中自定义CMFCMenuBar

时间:2013-12-29 10:24:54

标签: c++ mfc menubar mfc-feature-pack

有没有办法在使用visual studio 2008样式创建的MFC应用程序的菜单栏中创建动态菜单项,菜单不是功能区,我有动态添加菜单的插件如何将它们添加到该菜单?我明白了

//this is the menubar that i want to update
CMFCMenuBar       m_wndMenuBar;

4 个答案:

答案 0 :(得分:2)

首先,您必须创建一个新的子菜单。它可以手工填充或从资源中加载。 然后创建一个新的菜单按钮并将子菜单附加到它。之后更新菜单栏。而已。

CMenu menu;

if(menu.LoadMenu(IDR_MY_MENU))
{
    m_wndMenuBar.InsertButton(CMFCToolBarMenuButton(0, menu, -1, _T("&MyMenu")), -1);

    m_wndMenuBar.AdjustLayout();
    m_wndMenuBar.AdjustSizeImmediate();
}

P.S。 menu可能是本地的,因为CMFCToolBarMenuButton构造函数会从中复制内容。

答案 1 :(得分:1)

您可能需要覆盖:

CMDIFrameWndEx::OnShowPopupMenu(CMFCPopupMenu* pMenuPopup)

并将占位符菜单项放在需要动态菜单的位置,然后用动态菜单替换占位符菜单项。

有关使用MFC附带的源代码的示例:

afxframeimpl.cpp

BOOL CFrameImpl::OnShowPopupMenu(CMFCPopupMenu* pMenuPopup, CFrameWnd* /*pWndFrame*/)

答案 2 :(得分:0)

理想的方法可能是完全构建一个CMenu对象,然后将其分配给菜单栏:这使得代码几乎与以前版本的VisualStudio兼容。

  1. CMenu定义中声明指向CMainFrame实例的指针:

    CMenu *m_pMainMenu
    
  2. NULL构造函数中将其设置为CMainFrame

    m_pMainMenu = NULL;
    
  3. CMainFrame::OnCreate()中,创建CMenu的实例,假设它之前是NULL

    SAFE_DELETE(m_pMainMenu);  
    m_pMainMenu = new CMenu;
    
  4. Modify it随意:

    pMainMenu->LoadMenu(),  
    pMainMenu->RemoveMenu(),  
    pMainMenu->AppendMenu(),  
    pMainMenu->InsertMenu(),  
    ...
    
  5. 最后,使用CreateFromMenu

    将菜单工具栏与此新菜单相关联
    m_wndMenuBar.CreateFromMenu(m_pMainMenu->m_hMenu);
    
  6. 不要忘记在m_pMainMenu析构函数中释放CMainFrame以避免泄漏:

    SAFE_DELETE(m_pMainMenu)
    
  7. 注意:这是一个非常方便和安全的宏:

    #define SAFE_DELETE(a) { if (a) { delete(a); a=NULL; } }
    

答案 3 :(得分:-1)

您可以在属性视图窗口中使用UPDATE_COMMAND_UI。 假设您使用“ID_TEXTCAPTURE”设置了“文本捕获”菜单,然后您想要使用“停止捕获”更改菜单。

-in留言地图

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWndEx)
    ON_WM_CREATE()
    ON_UPDATE_COMMAND_UI(ID_TEXTCAPTURE, &CChildFrame::OnUpdateTextcapture)
END_MESSAGE_MAP()

-event handler

void CChildFrame::OnUpdateTextcapture(CCmdUI *pCmdUI)
{
    if(pCmdUI->m_pMenu)
    {
        int pos;
        CMenu* mmenu = pCmdUI->m_pMenu;
        pos = FindMenuItem(mmenu, _T("Text Capture(&C)"));

        if (pos > -1 && IsCapture == TRUE)
        {
            UINT id = mmenu->GetMenuItemID(pos);

            //change menu text as 'Stop Capture'
            mmenu->ModifyMenu(id, MF_BYCOMMAND, id, _T("Stop Capture(&S)"));
            IsCapture = TRUE;
        }       
     }
 }


CChildFrame::FindMenuItem(CMenu* Menu, LPCTSTR MenuString)
{

    ASSERT(Menu);
    ASSERT(::IsMenu(Menu->GetSafeHmenu()));

    int count = Menu->GetMenuItemCount();
    for (int i = 0; i < count; i++)
    {

        CString str;
        if (Menu->GetMenuString(i, str, MF_BYPOSITION) && str.Compare(MenuString) == 0)
      return i;
    }
    return -1;
}