VC中如何操作菜单

一.消息的分类


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()
    {
     //定义所需的各种操作
    };
    到此手动增加菜单项的消息处理过程完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值