您的位置:首页 > 其它

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

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

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

[cpp] view plaincopy

// 删除默认的所有系统菜单项

static void DelAllMenu(HMENU hMenu)

{

int Menucount = ::GetMenuItemCount(hMenu);

for (int i = Menucount-1;i>-1;i--)

{

::DeleteMenu(hMenu,i, MF_BYPOSITION);

}

}

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

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

[cpp] view plaincopy

#define ID_NEW_MENUBAR_OPEN 5000

#define ID_NEW_MENUBAR_SAVE 5001

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

[cpp] view plaincopy

void CMainFrame::NewMenuBar()

{

CMenu menu;

menu.CreateMenu();

CString strMenu;

strMenu = _T("打开文件");

menu.AppendMenu(MF_ENABLED|MF_STRING,ID_NEW_MENUBAR_OPEN,strMenu);

strMenu = _T("保存文件");

menu.AppendMenu(MF_ENABLED|MF_STRING,ID_NEW_MENUBAR_SAVE,strMenu);

CString strMenuBarTitle;

strMenuBarTitle = _T("文件");;

m_wndMenuBar.InsertButton (CMFCToolBarMenuButton (0, menu, -1,strMenuBarTitle));

}

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

[cpp] view plaincopy

if (!m_wndMenuBar.Create(this))

{

TRACE0("Failed to create menubar/n");

return -1; // fail to create

}

m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);

HMENU hm = m_wndMenuBar.GetDefaultMenu();

// 删除默认菜单栏

if (NULL!=hm)

{

DelAllMenu(hm);

}

// 创建新的菜单栏

NewMenuBar();

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



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

[cpp] view plaincopy

// MainFrm.h : interface of the CMainFrame classafx_msg

// AFX_WM_RESETMENU消息的处理函数声明

LRESULT OnResetMenu(WPARAM,LPARAM);

// MainFrm.cpp : implementation of the CMainFrame class

// 消息宏中增加

ON_REGISTERED_MESSAGE(AFX_WM_RESETMENU,&CMainFrame::OnResetMenu)

LRESULT CMainFrame::OnResetMenu(WPARAM,LPARAM)

{

NewMenuBar();

return 0;

}

我们再删除程序的注册表相关项重新编译(使用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))。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: