CMFCMenuBar动态删除菜单和创建新菜单

  这里要提一下的是VS Feature Pack的应用程序其中的菜单栏操作主要由CMFCMenuBar来负责。因此下面的编码也主要针对该类来进行。


       首先我们实现编码实现删除默认的所有系统菜单项,其代码如下:


[cpp]  view plain copy
  1. // 删除默认的所有系统菜单项   
  2. static void DelAllMenu(HMENU hMenu)    
  3. {    
  4.     int Menucount = ::GetMenuItemCount(hMenu);    
  5.     for (int i = Menucount-1;i>-1;i--)    
  6.     {    
  7.         ::DeleteMenu(hMenu,i, MF_BYPOSITION);    
  8.     }      
  9. }    

或使用m_wndMenuBar.RemoveButton(i);实现删除菜单项


然后我们定义两个菜单资源ID:


[cpp]  view plain copy
  1. #define ID_NEW_MENUBAR_OPEN     5000  
  2. #define ID_NEW_MENUBAR_SAVE     5001  


为CMainFrame类添加一个创建菜单栏的成员函数:


[cpp]  view plain copy
  1. void CMainFrame::NewMenuBar()  
  2. {  
  3.     CMenu menu;  
  4.     menu.CreateMenu();  
  5.     CString strMenu;  
  6.     strMenu = _T("打开文件");  
  7.     menu.AppendMenu(MF_ENABLED|MF_STRING,ID_NEW_MENUBAR_OPEN,strMenu);  
  8.     strMenu = _T("保存文件");  
  9.     menu.AppendMenu(MF_ENABLED|MF_STRING,ID_NEW_MENUBAR_SAVE,strMenu);  
  10.     CString strMenuBarTitle;  
  11.     strMenuBarTitle = _T("文件");;  
  12.     m_wndMenuBar.InsertButton (CMFCToolBarMenuButton (0, menu, -1,strMenuBarTitle));  
  13. }  


我们在CMainFrame类的OnCreate函数调用这个函数,这里只给出部分代码:


[cpp]  view plain copy
  1. if (!m_wndMenuBar.Create(this))  
  2. {  
  3.     TRACE0("Failed to create menubar/n");  
  4.     return -1;      // fail to create  
  5. }  
  6. m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);  
  7. HMENU hm = m_wndMenuBar.GetDefaultMenu();  
  8. // 删除默认菜单栏  
  9. if (NULL!=hm)    
  10. {    
  11.     DelAllMenu(hm);    
  12. }    
  13.  // 创建新的菜单栏  
  14. NewMenuBar();  


现在我们看看效果如何,如下图:




        我们发现默认菜单栏去掉了,但是新的菜单栏并没有出来。到网上搜资料,但是并没有搜到适用的,看了看Visual C++ 2008 Feature Pack Demo中提供的DynamicMenu的源码,了解了要增加AFX_WM_RESETMENU消息的处理函数,在函数里调用创建菜单栏,具体增加的代码如下:


[cpp]  view plain copy
  1. // MainFrm.h : interface of the CMainFrame classafx_msg   
  2. // AFX_WM_RESETMENU消息的处理函数声明  
  3. LRESULT OnResetMenu(WPARAM,LPARAM);   
  4. // MainFrm.cpp : implementation of the CMainFrame class  
  5. // 消息宏中增加  
  6. ON_REGISTERED_MESSAGE(AFX_WM_RESETMENU,&CMainFrame::OnResetMenu)  
  7. LRESULT CMainFrame::OnResetMenu(WPARAM,LPARAM)  
  8. {  
  9.     NewMenuBar();  
  10.     return 0;  
  11. }  


       我们再删除程序的注册表相关项重新编译(使用VS Feature Pack开发删除注册表这一项非常重要,Feature Pack的界面设计保存思路实际上和BCG是一样的,把上次用户设定的界面配置信息都保存在注册表,如果不删除注册表相关项,往往不能更新界面,注册表相关项一般在HKEY_CURRENT_USER/Software/Local AppWizard-Generated Applications/你的工程名称(英文版VS),HKEY_CURRENT_USER/Software/应用程序向导生成的本地应用程序/你的工程名称(中文版VS))。


     我们再看看效果,如下图:





     你可能会发现菜单是灰的,那是没有添加菜单的命令响应函数的缘故。本文的编译环境为:Windows XP + sp3, VS C++ 2008 + sp1。



      后来查了一下MSDN对AFX_WM_RESETMENU消息的解释,如下:

 

Message

Description

[in] wParam

lParam (All parameters are [in] unlessotherwise stated.)

ReturnValue

AFX_WM_RESETMENU

Theframework sends this message to the menu owner (a frame window) when the user resetsan application frame menu during customization

The menu resource ID.Not used.Not used.

我们再删除程序的注册表相关项重新编译(使用VS Feature Pack开发删除注册表这一项非常重要,Feature Pack的界面设计保存思路实际上和BCG是一样的,把上次用户设定的界面配置信息都保存在注册表,如果不删除注册表相关项,往往不能更新界面,注册表相关项一般在HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\你的工程名称(英文版VS),HKEY_CURRENT_USER\Software\应用程序向导生成的本地应用程序\你的工程名称(中文版VS))。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值