在更改菜单之前,首先要把CMainFrame:: m_bAutoMenuEnable设为FALSE,不然就无法自己更改菜单的样式,而是被MFC自动的设为启动。
每个菜单可以通过ID索取,也可以通过序号索取,即COMMAND或POSITION;第一个菜单序号为0,依次类推;第一个菜单下的子菜单序号也从0开始;注意存在分隔符时,分隔符也有自己的序号。
1.获得菜单
用AfxGetMainWnd()得到主窗口的句柄,再调用GetMenu,得到主菜单的指针,但是如果直接用 AfxGetMainWnd()->GetMenu()就会出错,因为用AfxGetMainWnd()得到的是CFrameWnd或其它,是 CMainFrame的父类,要把把强化转化为当前的框架类CMainFrame才可以再获得菜单等其他资源。
CMenu * pmenu = ((CMainFrame *)AfxGetMainWnd())->GetMenu();
现在pmenu获得的主菜单是整个菜单项,然后用它来调用GetSubMenu()来获取其中的子菜单。自菜单的序号是从0开始的。
CMenu * psub = pmenu->GetSubMenu(0);
2.启用/禁用菜单
之后就可以用psub来更改子菜单中的按钮的状态了,方法是:
psub->EnableMenuItem(UINT uIDEnableItem, UINT uEnable);
uIDEnableItem是菜单项标识, uEnable是控制标志, 常用的控制标志有3个:
MF_DISABLED —— 禁止
MF_ENABLED —— 允许
MF_GRAYED —— 变灰
比如要让打开菜单项(标志为ID_FILE_OPEN)变灰并且禁用(其实纯变灰了就不能用了),那么在CMainFrame的OnCreate函数结束之前添加下面一些指令:
CMainFrame::m_bAutoMenuEnable=false; //重要
CMenu * pmenu = this->GetMenu();
CMenu * psub = pmenu->GetSubMenu(0);
psub->EnableMenuItem(ID_FILE_OPEN, MF_GRAYED | MF_DISABLED);
3.标志菜单
效果是在菜单前打勾:
psub ->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);
//CheckMenuItem()用来标记菜单,它有两种参数,另一种如下:
psub ->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED);
4.缺省菜单:
效果是使菜单字体变粗,也有两种形式:
GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE);
GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN);
5.为菜单添加图标:
m_bitmap.LoadBitmap(IDB_BITMAP1);
GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap, &m_bitmap)
6.不用系统菜单,全由自己创建
在MainFrame的OnCreate函数中,利用函数SetMenu(NULL)将菜单删除,然后自己编写代码加载自己的菜单,具体代码:
CMenu menu;//定义一个菜单对象
menu.LoadMenu(IDR_MAINFRAME);//加载我们自己创建的菜单
SetMenu(&menu);//将菜单设置到应用程序框架
menu.Detach();//将C++对象与菜单分离,使得menu对象析构时,菜单不被销毁
将默认的工具拦删除,自己创建一个工具拦,将其ID号和创建的菜单ID号保持一致。
7.添加弹出菜单
CMenu menu;
menu.CreatePopupMenu();
GetMenu()->AppendMenu(MF_POPUP, (UINT)menu.m_hMenu, “hello”);
//将菜单添加到最后
GetMenu()->InsertMenu(2, MF_BYPOSITION | MF_POPUP, (UINT)menu.m_hMenu, “hello world”);
//将新菜单插入到原第二个菜单后
menu.Detach();
8.添加菜单下的项:
menu.AppendMenu(MF_STRING, 111, “NUM1”);
menu.AppendMenu(MF_STRING, 112, “NUM2”);
menu.AppendMenu(MF_STRING, 113, “NUM3”);
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING, 114, “WELCOM”);
GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND| MF_STRING, 115, “WELL”);
9.删除菜单:
GetMenu()->DeleteMenu(2, MF_BYPOSITION);
10.删除菜单项:
GetMenu()->GetSubMenu(0)->DeleteMenu(1, MF_BYPOSITION);
(1)在View中调用GetMenu()之前需要先调用GetParent()在获取MainFrame的指针;
(2)动态生成菜单,如果不显示,需要刷新,调用GetParent()->DrawMenuBar();