VC菜单编程知识汇总
1.菜单编程的几个术语
顶层菜单-----出现在窗口顶端的菜单栏
顶层菜单项---顶层菜单里面的命令项(菜单项)
下拉菜单-----顶层菜单项被单击时出现的菜单
弹出菜单-----这种菜单很像下拉菜单,但是可以在屏幕任意位置弹出
菜单项-------出现菜单里的命令项
2.创建菜单的方法
1.用编程方法创建菜单调用CreateMenu、InsertMenu和其他CMenu函数讲个部分连接起来
2.将一系列定义菜单内容的数据结构(MENUITEMTEMPLATE)初始化,并用CMenu::LoadMenuIndirect创建菜单
3.创建菜单资源,并在应用程序运行时加载生成的菜单
3.加载并显示菜单
1.将菜单挂接到窗口的方法是将菜单的资源ID传递给CFrameWnd::Create
2.将菜单挂接到窗口的方法是用CFrameWnd::LoadFrame函数
3.构造一个CMenu对象,调用CMenu::LoadMenu加载菜单资源,然后再调用CWnd::SetMenu设置菜单
4.响应菜单命令
用户打开一个下拉菜单,菜单挂接的窗口就会收到一系列消息。首先传来的是WM_ITEMMENU消息,通知窗口选中一个最高级菜单项。在显示子菜单之前,窗口收到消息。有时Windows程序趁这个时候更新子菜单的菜单项,例如:在菜单项添加复选标记。在加亮条上下移动时,窗口接到WM_MENUSELECT消息,报告加亮条在菜单中的最新位置。选中菜单项时发送的WM_COMMAND消息。消息的参数wParam的低位字节保留所选菜单项的ID。
5.响应菜单命令范围
有时候用单个命令处理程序处理一组菜单项ID要比为每个ID提供一个独立成员函数更好些。在这种情况下,我们可以使用MFC ON_COMMAND_RANGE宏。
6.更新菜单中的菜单项
在应用程序中,必须不断更新菜单中的菜单项,例如,在某个菜单项前加复选标记。通常有两种方法:一,通过编程实现。二,利用MFC更新菜单项机制。通过消息映射表的ON_UPDATE_COMMAND_UI宏,可以给每个菜单项都提供更新函数,也可以利用MFC ON_UPDATA_COMMAND_RANGE宏为一组菜单项提供一个更新函数。
7.上下文菜单(也可叫弹出菜单)
单击鼠标右键后,在响应WM_RBUTTONDOWN消息之前会响应WM_CONTEXTMENU消息,Windows很容易实现上下文菜单的创建。我们可以在响应WM_CONTEXTMENU消息的函数中,利用MFC的CMenu::TrackPopupMenu显示一个子菜单。
VC菜单编程--创建菜单
详细讲解如何创建菜单
第一种方法:
用编程方法创建菜单调用CreateMenu、InsertMenu和其他CMenu函数讲个部分连解起来;
过程如下:用CreateMenu创建菜单,用CreatePupupMenu创建子菜单,并用AppendMenu将子菜单挂接到顶层菜单,最终形成一个顶层菜单和他的子菜单。下面的例子创建了一个菜单,这个顶层菜单菜单包含File,Edit两个顶层菜单项,其中File有一个Exit菜单项,Edit有Copy,Cut,Paste三个菜单项。
CMenu menuMain;
menuMain.CreateMenu(); //创建空的顶层菜单
CMenu menuPopup;
menuPopup.CreatePopupMenu();//创建空的弹出菜单
menuPopup.Appendmenu(MF_STRING,ID_FILE_EXIT,"Exit");
menuMain.AppendMenu(MF_POPUP,(UINT)menuPopup.Detach(),"File");//创建File弹出菜单
menuPopup.CreatePopupMenu();
menuPopup.Appendmenu(MF_STRING,ID_EDIT_COPY,"Copy");
menuPopup.Appendmenu(MF_STRING,ID_EDIT_CUT,"Cut");
menuPopup.Appendmenu(MF_STRING,ID_FILE_PASTE,"Paste");
menuMain.AppendMenu(MF_POPUP,(UINT)menuPopup.Detach(),"Edit");//创建Edit弹出菜单
SetMenu(&menuMain);//设置菜单
第二种方法:
将一系列定义菜单内容的数据结构(MENUTTEMTEMPLATE)初始化,并用CMenu::LoadMenuIndirect创建菜单。例子请参考MSDN的CMenu::LoadMenuIndirect,这种方法不常用。
VC编程菜单--Menu常用的成员函数
1.BOOL CreateMenu();
创建一个空的菜单,并将其附加到 CMenu 对象
2.BOOL CreateMenu();
创建一个空的弹出菜单,并将其附加到 CMenu 对象
3.BOOL LoadMenu(UINT nIDResource);
nIDResource 要添加到窗口上的菜单ID;
加载菜单上的资源,并将其附加到 CMenu 对象
4.static CMenu * PASCAL FromHandle(HMenu hMenu);
hMenu 指向菜单的句柄
返回指向菜单的指针
5.BOOL AppendMenu(UINT nFlag,UINT_PTR nIDNewItem=0,LPCTSTR lpstrNewItem=NULL);
nFlag 要添加菜单项的状态信息,经常取下面的值
nIDNewItem 菜单项的ID,如果nFlag取MF_POPUP,这是弹出菜单的句柄,若nFlag取
MF_SEPATATOR,则忽略这个参数
lpstrNewItem 指示新菜单项的内容
在菜单的末尾添加一个新的菜单项
6.BOOL InsertMenu(UINT nPosition,UINT nFlag,UINT_PTR nIDNewItem=0,
LPCTSTR lpstrNewItem=NULL);
nPosition 要插入菜单项的位置
其他参数和AppendMenu参数一致,请参考上面的AppendMenu
在指定的位置插入菜单项
7.BOOL ModifyMenu(UINT nPosition,UINT nFlag,UINT_PTR nIDNewItem=0,
LPCTSTR lpstrNewItem=NULL);
它的参数和InsertMenu参数一致,请参考上面的InsertMenu
8.BOOL Attach(HMENU hMenu);
hMenu 菜单句柄
将现有的Windows菜单附加到CMenu对象上
9.HMENU Detach();
将Windows菜单从CMenu对象上分离,并返回该菜单的句柄
10.BOOL DeleteMenu(UINT nPosition,UINT nFlags)
nPosition 要删除菜单项的位置
nFlags 如果取MF_BYCOMMANGD则按ID,如果取MF_BYPOSITION则按位置
将指定的菜单或菜单项删除
11.BOOL TrackPopupMenu(UINT nFlags,int x,int y,CWnd *pWnd,LPCRECT lpRect=0);
nFlag 指定弹出菜单的位置和其他的一些属性
x 指定菜单左边缘在屏幕的水平位置
y 指定菜单顶部在屏幕的竖直位置
pWnd 指定拥有菜单窗口的指针
lpRect 指向一个CRect结构的指针
在指定的位置弹出上下文菜单
12.UINT CheckMenuItem(UINT nIDCheckItem,UINT nCheck);
nIDCheckItem 取决于nCheck,或ID或位置
nCheck 指定按照位置访问还是按照ID访问,是选上还是不选上
在指定的菜单项加上复选标记或去掉复选标记
13.UINT GetMenuStae(UINT ID,UINT nFlags);
参数和CheckMenu一样,请参考CheckMenuItems
获得指定菜单项是否选中
14.UINT EnabledMenuItem(UINT nIDEnabletem,UINT nEnable);
指定菜单项是否可用
15.CMenu * GetSystemMenu(BOOL bRevert);
bRevert 如果是FALSE可以修该系统菜单,如果是TRUE撤销对系统菜单的修改
得到系统菜单的指针
VC编程菜单实例--在系统菜单中添加菜单项
实例说明:
系统菜单是用户右击标题栏(快捷键Alt+空格)时弹出的快捷菜单。如何在系统菜单上添加自己的菜单项呢?本实例将实现这个功能。
所用知识:
为了操作系统菜单,我们首先要获得系统菜单的句柄或指针,可以通过GetSystemMenu获得系统菜单的句柄或指针,然后用AppendMenu或InsertMenu添加一个菜单项,最后在系统对话框类的OnSysCommand方法中处理菜单项的命令。(函数的解释VC编程菜单--Menu常用的成员函数找到)。
实现过程
1.新建一个基于对画框的应用程序
2.在对话框类中定义一个菜单指针m_pMenu,指向系统菜单
3.在对话框类中的OnInitDialog中添加以下代码
m_pMenu=GetSystemMenu(FALSE);
m_pMenu->AppendMenuW(MF_SEPARATOR);
m_pMenu->AppendMenuW(MF_STRING,IDM_ADDMENU,L"添加的菜单项");
//添加菜单项,也可以使用InserMenu
if(nID==IDM_ADDMENU)
{
MessageBox(L"我是你刚添加菜单的响应");
}
//添加单击时的响应
VC菜单编程实例--通过手工编程创建菜单
实例说明:
从应用程序资源模板加载菜单并不是唯一的方法(可以看前面的文章,有创建菜单的所有方法),可以用CMenu的成员函数编程创建菜单,优点是可以动态改变菜单。本实例就讲解如何动态创建菜单,这种方法是很有用的,一定要掌握哦
所用知识:
可以用CMenu::CreateMenu创建菜单,用CMenu::CreatePopupMenu创建子菜单,并用CMenu::AppendMenu将子菜单挂接到顶层菜单,最终形成一个顶层菜单和他的子菜单。
实现过程:
1.新建一个基于对画框的应用程序
2.在对话框类中的OnInitDialog中添加以下代码
CMenu mainMenu;
mainMenu.CreateMenu();
//创建空的顶层菜单
CMenu popupMenu;
popupMenu.CreatePopupMenu();
//创建空的子菜单
popupMenu.AppendMenuW(MF_STRING,ID_FILE_EXIT,L"Exit");
mainMenu.AppendMenuW(MF_POPUP,(UINT_PTR)popupMenu.Detach(),L"File");
//创建Exit子菜单并将他挂接到File顶层菜单项下
popupMenu.CreatePopupMenu();
popupMenu.AppendMenuW(MF_STRING,IDM_EDIT_COPY,L"Copy");
popupMenu.AppendMenuW(MF_STRING,IDM_EDIT_CUT,L"Cut");
popupMenu.AppendMenuW(MF_STRING,IDM_EDIT_PASTE,L"Paste");
mainMenu.AppendMenuW(MF_POPUP,(UINT_PTR)popupMenu.Detach(),L"Edit");
//创建子菜单并将他挂接到Edit顶层菜单项下
SetMenu(&mainMenu);
//设置菜单
添加对各个菜单项的响应
3.在对话框类头文件中添加消息响应函数的声明
asx_msg void OnExit();
afx_msg void OnCopy();
afx_msg void OnCut();
afx_msg void OnPaste();
4.在对话框类中如下添加消息映射
ON_COMMAND(ID_FILE_EXIT,OnExit)
ON_COMMAND(IDM_EDIT_COPY,OnCopy)
ON_COMMAND(IDM_EDIT_CUT,OnCut)
ON_COMMAND(IDM_EDIT_PASTE,OnPaste)
在对话框类中添加消息映射成员函数
void CCreateMenuDlg::OnExit()
{
PostMessage(WM_QUIT);
}
void CCreateMenuDlg::OnCopy()
{
MessageBox(L"你单击了Copy");
}
void CCreateMenuDlg::OnCut()
{
MessageBox(L"你单击了Cut");
}
void CCreateMenuDlg::OnPaste()
{
MessageBox(L"你单击了Paste");
}
(说明:CCreateMenuDlg是对话框类)
VC菜单编程--手工添加菜单项的命令响应
具体实现过程如下:
1. 在响应菜单项的头文件中添加函数声明
2. 在响应菜单类的源文件消息映射中添加消息映射
3. 在响应菜单类的源文件中实现函数。
例子如下:(具体可以参考VC菜单编程实例--通过手工编程创建菜单)
1.添加添加函数声明
asx_msg void OnExit();
2.添加消息映射
ON_COMMAND(ID_FILE_EXIT,OnExit)
3.在响应菜单类的源文件中实现函数。
void CCreateMenuDlg::OnExit()
{
PostMessage(WM_QUIT);
}