MFC的单文档中,动态添加顶级菜单

我的一个工具,使用vs2015mfc写的,单文档方式。

在打开一个文件的时候,想在当前的菜单中添加我自己的一个顶级菜单,文件关闭的时候,就删除它。

在插入之前的样子:

插入之后的样子:

以下为实现过程(以下都是在CMainFrame类中添加代码):

首先定义两个变量:

	int	m_plugMenuIndex;	// 如果为-1,则表示没有插入
	CMenu	m_menuFromPlug;

第一个变量用于记录这个顶级菜单插入的位置,第二个是插入的菜单内容,在OnCreateClient()初始化:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
   ...
   m_plugMenuIndex = -1;
   m_menuFromPlug.CreatePopupMenu();
}

当然,放在OnCreate()中初始化也可以。

添加菜单创建函数:

void CMainFrame::UpdateMenuFromPlug()
{
	int menuCount = m_vecMenu.size();
	if (menuCount == 0)
		return;

	CMenu *pmenu = GetMenu();
	unsigned int flag = MF_POPUP | MF_STRING | MF_BYPOSITION;

	// 先创建子菜单,注意,先删除之前加入的项,因为这些项在不同状态下可能会变化
	CString plugMStr = TEXT("高级功能");
	while (m_menuFromPlug.GetMenuItemCount())
	{
		m_menuFromPlug.DeleteMenu(0, MF_BYPOSITION);
	}

	int im;
	flag = MF_ENABLED | MF_STRING;
	for (im = 0; im < menuCount; im++)
	{
		m_menuFromPlug.AppendMenu(flag, IDM_PLUGMENUSTART + im, m_vecMenu[im].strText);
	}

	MENUITEMINFOW menuStru;
	memset(&menuStru, 0, sizeof(menuStru));
	menuStru.cbSize = sizeof(menuStru);
	menuStru.hSubMenu = m_menuFromPlug.GetSafeHmenu();
	menuStru.fMask = MIIM_SUBMENU | MIIM_STRING;
	menuStru.fType = MIIM_STRING;
	menuStru.dwTypeData = (LPWSTR)plugMStr.GetString();
	menuStru.cch = plugMStr.GetLength();

	m_plugMenuIndex = 3;	// 插到第三个位置
	if (!pmenu->InsertMenuItem(m_plugMenuIndex, &menuStru, MF_BYPOSITION))
	{
		// 插入菜单失败
		m_plugMenuIndex = -1;
	}
}

其中的m_vecMenu是要加入的菜单项列表,定义为:vector<CString> m_vecMenu; ,在合适的地方插入内容就可以了。

这个函数是先创建这个要插入的顶级菜单,在创建之前,需要删除之前插入的项,因为打开不同的文件时,插入的菜单项可能不一样,所以需要删除。如果你没有这些不同,那就没有必要删除它,自然,只要创建一次,后面也就不用再去创建它了。

这里插入的位置设置为第四项,如果最后在插入到系统菜单时失败,则置插入的位置为-1,这样在文件关闭时就不用删除它了。

在打开文件的接口中调用该函数 UpdateMenuFromPlug();

这样就完成了菜单的加载。

在文件关闭时,删除添加的菜单项,使菜单栏恢复打开文件之前的状态:

	if (m_plugMenuIndex >= 0)
	{
		CMenu *pmenu = GetMenu();
		pmenu->RemoveMenu(m_plugMenuIndex, MF_BYPOSITION);
		m_plugMenuIndex = -1;
		DrawMenuBar();
	}

注意,删除之后的 DrawMenuBar() 函数必需调用,否则菜单栏不会刷新,只有当窗口变化的时候它才会刷新,这样就影响了界面的显示效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值