MFC中与菜单相关的函数如下:
AppendMenu 在指定的菜单里添加一个菜单项
CheckMenuItem 复选或撤消复选指定的菜单条目
CheckMenuRadioItem 指定一个菜单条目被复选成“单选”项目
CreateMenu 创建新菜单
CreatePopupMenu 创建一个空的弹出式菜单
DeleteMenu 删除指定的菜单条目
DestroyMenu 删除指定的菜单
DrawMenuBar 为指定的窗口重画菜单
EnableMenuItem 允许或禁止指定的菜单条目
GetMenu 取得窗口中一个菜单的句柄
GetMenuCheckMarkDimensions 返回一个菜单复选符的大小
GetMenuContextHelpId 取得一个菜单的帮助场景ID
GetMenuDefaultItem 判断菜单中的哪个条目是默认条目
GetMenuItemCount 返回菜单中条目(菜单项)的数量
GetMenuItemID 返回位于菜单中指定位置处的条目的菜单ID
GetMenuItemInfo 取得(接收)与一个菜单条目有关的特定信息
GetMenuItemRect 在一个矩形中装载指定菜单条目的屏幕坐标信息
GetMenuState 取得与指定菜单条目状态有关的信息
GetMenuString 取得指定菜单条目的字串
GetSubMenu 取得一个弹出式菜单的句柄,它位于菜单中指定的位置
GetSystemMenu 取得指定窗口的系统菜单的句柄
HiliteMenuItem 控制顶级菜单条目的加亮显示状态
InsertMenu 在菜单的指定位置处插入一个菜单条目,并根据需要将其他条目向下移动
InsertMenuItem 插入一个新菜单条目
IsMenu 判断指定的句柄是否为一个菜单的句柄
LoadMenu 从指定的模块或应用程序实例中载入一个菜单
LoadMenuIndirect 载入一个菜单
MenuItemFromPoint 判断哪个菜单条目包含了屏幕上一个指定的点
ModifyMenu 改变菜单条目
RemoveMenu 删除指定的菜单条目
SetMenu 设置窗口菜单
SetMenuContextHelpId 设置一个菜单的帮助场景ID
SetMenuDefaultItem 将一个菜单条目设为默认条目
SetMenuItemBitmaps 设置特定位图,令其在指定的菜单条目中使用,代替标准的复选符号(√)
SetMenuItemInfo 为一个菜单条目设置指定的信息
TrackPopupMenu 在屏幕的任意地方显示一个弹出式菜单
TrackPopupMenuEx 与TrackPopupMenu相似,只是它提供了额外的功能
以下是几个关于菜单函数的类型定义
MENUITEMINFO 这个结构包含了菜单条目的信息
TPMPARAMS 这个结构用于TrackPopupMenuEx函数以支持额外的功能
//新建了一个基于单文档的工程,下面是与菜单操作相关的操作,知识讲解在代码中以注释的形式给出了
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("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
//1.标记菜单
//GetMenu()是CWnd类的成员函数,可以在框架窗口中获得指向菜单栏的指针
//GetSubMenu()可以获取一个菜单的子菜单,参数是子菜单的索引号,从左到右依次为0-1-2···
//各子菜单的菜单项从上之下的索引依次为0-1-2···,其中分割栏也是占据索引位置的
//CheckMenuItem(UINT nIDCheckItem,UINT nCheck)用于为菜单项添加或删除标记,其中第一个参数由第二个参数决定
//若第二个参数只含有MF_BYCOMMAND,则第一个参数必须是菜单项的命令ID,用索引无效
//同样地,若第二个参数只含有MF_BYPOSITION,则第一个参数必须是菜单项的索引,用其ID反而无效
//当然,如果第二个参数同时保护MF_BYCOMMAND和MF_BYPOSITION,则第一个参数可以是其索引或ID
GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);
GetMenu()->GetSubMenu(0)->CheckMenuItem(1,MF_BYPOSITION|MF_CHECKED);
//删除菜单的标记
GetMenu()->GetSubMenu(0)->CheckMenuItem(2,MF_BYCOMMAND|MF_BYPOSITION|MF_UNCHECKED);
//2.默认菜单项(一个子菜单只能有一个默认菜单项)
//SetDefaItem的第一个参数也是由第二个bool型参数决定的
GetMenu()->GetSubMenu(0)->SetDefaultItem(3,TRUE);
//3.图像标记菜单(先为CMainFrame添加一个成员变量m_bitmap)
//GetSystemMetrics(SM_CXMENUCHECK)和GetSystemMetrics(SM_CYMENUCHECK)分别得到菜单上标记图像的宽和高
//若加载的位图太大,只能显示一部分,则要适当修改位图大小
//CString str;
//str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));
//MessageBox(str);
m_bitmap.LoadBitmap(IDB_BITMAP);
GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(1,MF_BYPOSITION,&m_bitmap,&m_bitmap);
//4.设置菜单项状态
//UNIT EnableMenuItem(UINT nIDEnableItem,UINT nEnable)可设置菜单项的状态:能用、禁用、或变灰显示
//若要人为修改菜单栏状态奏效,必须在构造函数中将m_AutoMenuEnable设置为false
//菜单项设置为MF_DISABLED后菜单项看起来无变化但不会响应,因此常和MF_GRAYED组合,单独用MF_GRAYED也可以
GetMenu()->GetSubMenu(0)->EnableMenuItem(3,MF_BYPOSITION|MF_GRAYED);
//5.移除或装载菜单
SetMenu(NULL);//参数为空就可以移除菜单
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();//如果menu为局部变量,则把菜单项与菜单句柄分离,否则点击会出现异常
//6.添加菜单项目
CMenu menu1;
menu1.CreateMenu();
//若AppendMenu()的第一个参数是MF_POPUP,那么第二个参数就是顶级菜单的句柄,否则就是要添加的新菜单项的命令ID
//若AppendMenu()的第一个参数是MF_SEPARATOR,那么后面两个参数会被忽略
GetMenu()->AppendMenu(MF_POPUP,(UINT)menu1.m_hMenu,"New Item0");
//在子菜单中添加菜单项
menu1.AppendMenu(MF_STRING,0,"A");
menu1.AppendMenu(MF_SEPARATOR,1,"B");
menu1.AppendMenu(MF_STRING,2,"C");
menu1.Detach();//如果menu为局部变量,则把菜单项与菜单句柄分离,否则点击会出现异常
//7.插入菜单项目
CMenu menu2;
menu2.CreateMenu();
GetMenu()->InsertMenu(2,MF_POPUP|MF_BYPOSITION,(UINT)menu2.m_hMenu,"New Item1");
//在子菜单中添加菜单项
menu2.AppendMenu(MF_STRING,0,"C");
menu2.AppendMenu(MF_SEPARATOR);
menu2.AppendMenu(MF_STRING,2,"D");
menu2.Detach();
//在一个子菜单后面添加一个菜单项
GetMenu()->GetSubMenu(0)->InsertMenu(ID_APP_EXIT,MF_BYCOMMAND|MF_STRING,IDM_HELLO,"Hello");
//8.删除菜单项目
//删除的是子菜单还是子菜单的菜单项取决于调用DeleteMenu()的对象
GetMenu()->DeleteMenu(1,MF_BYPOSITION);//删除“编辑”子菜单
GetMenu()->GetSubMenu(1)->DeleteMenu(0,MF_BYPOSITION);//删除子菜单的菜单项
//9.动态添加菜单项的命令响应,以上面的"Hello"菜单项为例
//首先在Resource View里为Hello菜单项添加一个名为IDM_HELLO的ID,或者在Resource.h里手动添加#define IDM_HELLO 101
// 在响应这个菜单项命令的程序类的头文件添加响应函数原型
// 添加的位置在声明消息响应宏DECLARE_MESSAGE_MAP之上(afx_msg void OnHello();)
// 在响应这个菜单项命令的源程序前面的消息映射表中添加消息映射
// 添加的位置在注释宏之后,在END_MESSAGE_MAP()之前(ON_COMMAND(IDM_HELLO,OnHello))
// 最后实现菜单项响应函数的的定义体,如下的函数
return 0;
}
void CMainFrame::OnHello()
{
MessageBox("Hello");
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
// .MFC菜单更新机制:菜单项状态的维护依赖于CN_UPDATE_COMMAND_ID消息
// 当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CFrameWnd接管,
// 它会创建一个CCmdUINT对象,并与程序的第一个菜单项相关联,调用该对象的一个成员函数DoUpdate(),
// 这个函数发出CN_UPDATE_COMMAND_UI宏去捕获这个菜单项消息。若找到这一宏就调用响应的消息响应函数
// 去处理,在这个响应函数中可利用传递过来的CCmdUI指针去调用响应的函数设置菜单项的状态
// 上面的就是MFC采用的命令更新机制
// 我们可以利用ClassWizard在消息中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_ID
void CMainFrame::OnUpdateFileSave(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
//CCmdUI类有一个成员变量m_nID用于保存当前菜单项、工具栏按钮等对象的标识
if(pCmdUI->m_nID==ID_FILE_SAVE)//MFC在调用菜单命令更新函数是就确定了特定的菜单项,实际无需判断
//CCmdUI类还有一个成员变量m_nIndex保存当前菜单项的位置索引
//if(pCmdUI->m_nIndex==2)//注意菜单项和工具栏的索引值可能不一致,所以最后使用它们的ID值
pCmdUI->Enable(FALSE);//禁用菜单项“保存”
//我们可以发现菜单项和工具栏的“保存”都被禁用了
//菜单项和工具栏的“保存”的ID都是ID_FILE_SAVE
// 也就是说若要把工具栏的按钮和菜单项相关联,只要将它们的ID设置为同一个标志就OK了
}