一种是针对弹出菜单操作,一种是针对菜单项的动态操作。
重新建立一个单文档工程,进行添加菜单项目,之前在资源编辑器中添加完成的,现在通过代码进行动态添加菜单项目。
CMenu类提供了一个成员函数:AppendMenu函数,把一个新菜单项目添加到指定菜单项目的末尾。
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );
第一个参数:指定新添加菜单项目的状态信息
第二个参数取决于第一个参数:若第一个参数为MF_POPUP,它就是一个顶层菜单的句柄;否则就是一个新建菜单项的命令ID。若为 MF_SEPARATOR(分隔栏),它的值将会被忽略。
取决于第一个参数:MF_STRING,表示新建菜单项目文本的指针。
为了添加菜单,首先得创建一个菜单对象,CMenu类提供了一个成员函数:CreatePopupMenu函数来实现,创建一个弹出菜单;在CMainFrame类的OnCreate函数中实现动态菜单的添加。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{....
CMenu menu;
menu.CreateMenu();
GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"Test");
return 0;
}
因为CMenu对象m_hMenu成员变量是菜单句柄,其类型是HMENU,所以需要强制类型转换;因为menu是局部变量,所以需要完成菜单的添加以后,加上:menu.Detach();
在两个子菜单或者两个菜单项之间添加一个子菜单或者菜单项。利用CMenu类的InsertMenu函数完成。
BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );
第一个参数取决于第二个参数:若第二个参数为MF_BYCOMMAND,那么它就是一个菜单命令标识,表示所标识的菜单项之前插入;若为MF_BYPOSITION,表示指定位置的菜单项之前插入。
在编辑和查看子菜单之间插入Test,插入位置应该是2。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{....
CMenu menu;
menu.CreateMenu();
GetMenu()->InsertMenu(2,MF_BYPOSITION|MF_POPUP,(UINT)menu.m_hMenu,"Test");
menu.Detach();
}
在插入的子菜单中添加菜单项:
在InsertMenu函数后面添加AppendMenu函数。
menu.AppendMenu(MF_STRING,111,"Hello");
menu.AppendMenu(MF_STRING,112,"Bye");
menu.AppendMenu(MF_STRING,113,"Mybole");
给文件子菜单下面添加一个菜单项:
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Welcome");
在文件新建和打开菜单项之间插入一个菜单项:
GetMenu()->GetSubMenu(ID_FILE_OPEN,MF_BYCOMMAND|MF_STRING,115,"vc编程");
CMenu类提供了一个DeleteMenu成员函数:
BOOL DeleteMenu( UINT nPosition, UINT nFlags );
在CMainFrame类中添加以下代码:
删除一个子菜单:
GetMenu()->DeleteMenu(1,MF_BYPOSITION);
删除一个菜单项:
GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);
以Test菜单下的Hello菜单项为例,如何为动态添加的菜单项添加命令消息响应函数。
首先创建一个菜单资源ID:
FileView->Header Files->Resource.h
在头文件里面添加:#define IDM_HELLO 111
然后在添加Hello菜单项的AppendMenu语句修改为:
下面按照MFC消息响应机制的三步来完成Hello菜单命令消息响应:
1、在响应菜单项命令的程序类(CMainFrame)的头文件中添加响应函数的原型,添加位置在DECLARE_MESSAGE_MAP()上面,两个AFX_MSG注释宏下面。
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
afx_msg_void OnHello();
DECLARE_MESSAGE_MAP()
2、在响应菜单项命令的程序类(CMainFrame)的源文件中的消息映射表中添加消息映射。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code !
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMMAND(IDM_HELLO,OnHello);
END_MESSAGE_MAP()
#endif //_DEBUG
void CMainFrame::OnHello()
{
MessageBox("Hello");
}
/
// CMainFrame message handlers