MFC之菜单栏的相关使用14

1 菜单栏选项的打勾,加粗,禁用

首先我们需要知道菜单栏包含子菜单栏,依次使用下标去区分。然后拿到子菜单栏后,就可以操作里面的选项了。可以通过下标,选项的ID(在资源视图的菜单栏的图,点击选项右击属性即可获取)进行操作。

代码:
由于为了减少视图的工作量,并且根据上一篇菜单栏的消息路由,框架也可以处理菜单栏的消息,所以代码放在框架类的OnCreate处理,注意,是操作菜单栏本身的选项时放在菜单栏处理,当处理菜单栏里面选项的左中右键按下时,尽量放在视图处理,否则框架可能无法捕获,但是菜单栏的变量需要重新定义,不要Get获取菜单栏,否则出错。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}

	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

	// TODO: 如果不需要可停靠工具栏,则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	//1 获取菜单栏
	CMenu *menu = GetMenu();
	//2 获取第一个子菜单栏,0代表下标
	CMenu *submenu = menu->GetSubMenu(0);
	//3 操作子菜单中的选项
	//1) 添加勾勾
	submenu->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);//下标法
	submenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED);//ID法,需要去菜单栏拿取选项的ID并且参1改为命令宏,是对应使用的
	//2)让选项加粗(设置默认项),注意一个菜单栏只能有一个加粗,所以最后3将覆盖2加粗
	submenu->SetDefaultItem(2, TRUE);
	submenu->SetDefaultItem(3, TRUE);
	//3) 禁用选项,使选项变灰(注意分界线也算一个下标选项)
	CFrameWnd::m_bAutoMenuEnable = false;//这句一般放构造处理
	submenu->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);

	return 0;
}

结果可以看到,0,1打上勾。2被3覆盖加粗。4为分界线不需要处理。5被禁用了即打印。在这里插入图片描述

2 菜单栏的移除与加载自定义的菜单栏

我们在上面的例子中继续添加代码即可。重复的代码可以不用看。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}

	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

	// TODO: 如果不需要可停靠工具栏,则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	//1 获取菜单栏
	CMenu *menu = GetMenu();
	//2 获取第一个子菜单栏,0代表下标
	CMenu *submenu = menu->GetSubMenu(0);
	//3 操作子菜单中的选项
	//1) 添加勾勾
	submenu->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);//下标法
	submenu->CheckMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_CHECKED);//ID法,需要去菜单栏拿取选项的ID并且参1改为命令宏,是对应使用的
	//2)让选项加粗(设置默认项),注意一个菜单栏只能有一个加粗,所以最后3将覆盖2加粗
	submenu->SetDefaultItem(2, TRUE);
	submenu->SetDefaultItem(3, TRUE);
	//3) 禁用选项,使选项变灰(注意分界线也算一个下标选项)
	CFrameWnd::m_bAutoMenuEnable = false;//这句一般放构造处理
	submenu->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);

	//移除菜单栏
	SetMenu(NULL);

	//重新加载自己新建的菜单栏(需要自己去菜单栏操作,右击Menu文件夹插入Menu即可)
	CMenu menu2;
	menu2.LoadMenuW(IDR_MENU1);
	SetMenu(&menu2);
	menu2.Detach();//防止窗口创建后menu2被释放,再按选项

	return 0;
}

这是我自己自定义的菜单栏。
在这里插入图片描述

结果:
在这里插入图片描述

3 菜单栏的更新机制

菜单栏的选项类似Qt的绘图事件,都是会自动更新绘图,MFC的菜单栏也一样,每次按下某个选项后,都会自动更新菜单栏。因为菜单栏的更新机制是自动的,所以我们一般通过使用标志位来显示选项以达到自己的目的。例如下面案例,按下cc选项,使bb选项变亮。

继续上面的程序:
1)因为我们要使bb变亮,所以创建bb的UI处理程序。
在这里插入图片描述
在这里插入图片描述

2)又因为我们需要按下cc控制bb的亮度,所以需要添加消息的COMMAND回调函数。在这里插入图片描述

3)添加成员变量标志位bool类型。
在这里插入图片描述

4)编写代码。

//bb的自动更新回调
void CMainFrame::OnUpdateBbBb(CCmdUI *pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码

	//自动回调更新,不需要手动调用
	if (m_cc == true) {
		pCmdUI->Enable(TRUE);
	}
	else {
		pCmdUI->Enable(FALSE);
	}
}

//cc的按钮按下回调
void CMainFrame::OnBbCc()
{
	// TODO: 在此添加命令处理程序代码
	
	//按下cc键
	m_cc = !m_cc;//即m_cc = TRUE;
}

结果就是按下cc后,bb的亮度改变,不截图了。

4 左键弹出菜单栏快捷键

由于是鼠标按下事件,所以我们将函数放在视图中处理,放在框架会导致没反应。注意一下菜单栏的选项放在框架处理,选项的按下放在视图处理。

void CMenuView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//重新创建菜单栏,不要使用Get获取框架类的对象
	//CMenu *m = GetMenu();//在视图而非框架类中时,禁用
	CMenu menu;
	menu.LoadMenuW(IDR_MENU1);
	CMenu *submenu = menu.GetSubMenu(0);
	ClientToScreen(&point);//将相对于屏幕的坐标换成相对于窗口的坐标

	//按下左键,弹出子菜单栏,即左键就是该子菜单栏的快捷键
	submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this);

	CView::OnLButtonDown(nFlags, point);
}

结果,按下左键就相当于按下了bb子菜单栏。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值