VC中操作菜单的方法

来源:岁月联盟 编辑:zhu 时间:2009-02-15

一.消息的分类
1.标准消息
除WM_COMMAND之外,所有以WM_开头的消息。从CWnd派生的类,都可以接收到这类消息。
2.命令消息
来自菜单,加速建或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识来区分不同的命令消息;从CCmdTarget派生来的类,都可以接收到这类消息。
3.通告消息
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。
从CCmdTarget派生的类,都可以接收到这类消息。

二.菜单的操作函数介绍
对于菜单的操作大家比较熟悉,平时在使用电脑时,经常会使用到菜单,其实对于菜单的所有基本操作,在MFC中都有相应的函数来对应。


1.CMenu* GetMenu() const,获取当前主框架下的菜单栏指针.它是CWnd的成员函数

2.CMenu::GetSubMenu ,CMenu* GetSubMenu( int nPos ) const;获取主菜单下的子菜单(一般是弹出菜单)指针。其中nPos指示弹出菜单的位置,0表示一个子菜单,1表示第二个,依次类推。GetSubMenu是CMenu的成员函数,它的返回值还是指向CMenu类的指针。
在CMainFrame类的成员函数OnCreate中写如下代码:GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_CHECKED|MF_BYPOSITION);
需要说明的是CheckMenuItem()函数.,其原型定义为UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );其中nIDCheckItem保存需要复选的菜单项的位置,nCheck用来决定是否复选菜单项和表示菜单项位置的方式,MF_CHECKED或者MF_UNCHECKED与MF_BYPOSITION或者MF_BYCOMMAND连用。MF_CHECKED表示复选上菜单项,MF_UNCHECKED则相反。MF_BYPOSITION表示函数第一个参数使用0,1等数字参数表示菜单项的位置,MF_BYCOMMAND则表示使用菜单项的标识符表示菜单项的位置。
上面的函数是选择主菜单栏下的第一个弹出菜单,在弹出菜单下的一个个菜单项。之后对这个菜单项进行复选操作,完成复选。
这个操作中包含以下的类关系:CMainFrame从CWnd派生而来,在CMainFrame的成员函数OnCreate()中可以使用CWnd的成员函数GetMenu(),获取主框架下菜单的指针,然后使用菜单类的成员函数GetSubMenu获取弹出菜单的菜单指针,最后使用菜单类的成员函数CheckMenuItem完成菜单项的复选操作。


3.在知道了如何使用GetMenu()和GetSubMenu()函数后,我们可以开始熟悉一些CMenu的操作函数,对具体的菜单项进行操作。
CMenu::SetDefaultItem
BOOL SetDefaultItem( UINT uItem, BOOL fByPos = FALSE )
第一行表示SetDfaultItem函数是CMenu类的成员函数,第二行是SetDefaultItem函数原型的说明,以后在对函数讲解时,一般以这种方式列出,这也是微软MSDN的函数说明规范。在函数中uItem用来标识操作菜单项的位置,第二个参数决定第一个参数以何种方式标识菜单项位置,默认不是以位置方式标识,即是以标识符的方式标识。使用方法:
GetMenu()->GetSubMenu(0)->SetDfaultItem(0,TRUE);

4.定制自己的菜单资源(在window中资源都由句柄唯一标识)
首先定义一个CMenu对象
CMenu menu; //定义一个菜单对象
SetMenu(NULL); //将当前的菜单移走
menu.LoadMenu(IDR_MAINFRAME); //加载自己的菜单资源,把它和菜单对象联系起来
SetMenu(&menu); //设置当前的菜单为menu对象,并且使window重画以反映菜单的 //变化
menu.Detach(); //使菜单资源的句柄和菜单对象分离,以防本地变量menu释放后 //,使菜单资源释放

5,菜单项状态的维护
对于菜单项状态如可以使用,不能使用和变灰等状态,可以使用CMenu的EnableMenuItem函数来实现。
其实菜单项状态的维护是依赖于CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。我们可以通过手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。
使用MFC的类向导,建立菜单中,新建、打开、保存的消息处理,选择其中的ON_UPDATE_COMMAND_UI消息,就可以编写程序来控制菜单项的状态。例如对于菜单项中的<剪切>项操作代码如下:void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(2==pCmdUI->m_nIndex)
pCmdUI->Enable();
}
对于每个菜单项,所建立的ON_UPDATE_COMMAND_UI消息,都有一个CCmdUI* pCmdUI参数,利用pCmdUI可以使用CCmdUI的数据成员和成员函数来对菜单项进行相关的操作。m_nIndex是菜单项,工具栏按钮或者其他用户接口对象的索引,这些对象由pCmdUI指定。对于程序中的第一行,剪切项的位置是2,Enable()是使剪切项可用。还有其他的成员函数和数据成员说明如下:
CCmdUI::SetCheck
virtual void SetCheck( int nCheck = 1 );这个函数用来设定菜单项的合适的选择状态,默认下是1,表示选中;0表示不选中;2表示不确定的。
CCmdUI::SetText
virtual void SetText( LPCTSTR lpszText );
设置用户接口项的文本显示内容。
CCmdUI::m_nID
菜单项,工具栏按钮或者其他用户接口对象的ID标识号,这些对象由pCmdUI指定。
在使用m_nIndex时注意,不同的对象索引是不同的。如:
if(2==pCmdUI->m_nIndex)//这个索引只是对于菜单项有效,对于工具栏中的剪切按钮无效,因为 //工具栏中的索引不是2;
pCmdUI->Enable();
if(4==pCmdUI->m_nIndex)//这时工具栏中的按钮才有效了,假定工具栏上按钮索引是4
pCmdUI->Enable();

6.增加右键弹出菜单功能
方法一:可以在 工程->增加到工程->conponents and controls
在出现的文件选择栏中 选择Visual C++ Components文件夹,再选择popmenu资源文件即可。这样就建立了弹出菜单。
方法二:在CView中增加鼠标右键点击的消息处理函数,在函数中加载一个弹出菜单即可。
可以使用下面的代码:

void CMenuView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMenu menu;
menu.LoadMenu(IDR_MENU2);
ClientToScreen(&point);
CMenu* pPopup = menu.GetSubMenu(0);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
GetParent());
CView::OnRButtonDown(nFlags, point);
}
具体使用的函数可以在msdn中查看。

7.手动增加菜单项的消息处理(动态加载菜单项)。

在主框架下动态增加菜单项:如在CMainFrame::OnCreate()中增加如下代码
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,113,"WindowsXp");
以上表示在文件的下拉菜单项的最后追加一项菜单项,它的ID号为113,名字是WindowsXp。但是它并不是静态的菜单资源,是在程序运行过程中动态加载的,不能使用类向导来增加它的OnCommand消息处理,只能手动增加。步骤如下:
1> 先到Resource.h中增加菜单项资源的定义
2> #define IDM_WNDXP 113
3> 然后到CMainFrame.h中增加afx_msg void OnWindows();声明消息映射;
4> 再到BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_COMMAND(IDM_WNDXP,OnWindows)
END_MESSAGE_MAP()
之间定义消息映射(已经添加好了);
5> 最后定义OnWindows函数
void CMainFrame::OnWindows()
{
//定义所需的各种操作
};
到此手动增加菜单项的消息处理过程完成。

上一篇:VC数据类型
下一篇:VC中的TRACE宏