MFC——5.菜单

来源:互联网 发布:xampp mac使用教程 编辑:程序博客网 时间:2024/06/06 04:10

Lesson5:菜单

 

菜单是用户交互界面中一个重要的角色,本文主要讲解了菜单的使用方法,包括解析MFC的Frame,App,Doc,View类对菜单的响应顺序,菜单的基本操作和右键弹出菜单。

1.    MFC的类对菜单命令响应顺序

在MFC的资源里面有一个菜单项,可以在这里添加菜单。菜单设置里Pop-up类型的菜单成为弹出式菜单,这种菜单不能响应命令,一般默认顶层菜单都是弹出式菜单,它们会有子菜单,子菜单可以响应命令。当我们添加了菜单按钮并给了标识IDM_TEST后,在向导里的命令里选择与这个ID对应的命令消息,然后编辑代码。这里通过产生消息框进行测试。

void CMenuView::OnTest()

{

         //TODO:  在此添加命令处理程序代码

         AfxMessageBox("ViewClicked!");

}

上面的测试是在View类里的,那么对于同一个菜单,当在MFC的Frame,App,Doc,View类里分别添加函数后,事实上响应的先后顺序是View,Doc,Frame,App。我们看看MFC的消息分类。

 

【消息的分类】

标准消息:除WM_COMMAND之外,所有以WM_开头的消息(窗口重绘的WM_PAINT消息,窗口创建的WM_CREATE,键盘按键WM_CHAR消息等)。从CWnd派生的类,都可以接收到这类消息。

命令消息:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类,都可以接收到这类消息。

通告消息:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。从CCmdTarget派生的类,都可以接收到这类消息。

从从CWnd派生的类,可以接收标准消息、命令消息、通告消息。从CCmdTarget派生的类,可以接收命令消息、通告消息。

 

菜单命令消息的路由过程】 当点击菜单项时,框架类首先接收到这个消息,并把消息交给它的子窗口,view类,由视类进行处理。view类首先查看自己是否有成员函数处理此消息,如果能处理,就由调用相应的响应函数来处理,如果没有,由view类交给doc类处理,doc查找自己能否处理,如果能处理,就由调用相应的响应函数来处理,如果没有,就交还给view类,view类又交还给frame类。这时frame类查看自己能否处理此消息,如果能则处理,不能则交给应用App程序类来处理。

 

2.    菜单相关操作

对菜单进行修改是在frame框架类窗口的OnCreate函数里进行的。下面是一系列的菜单操作。

int CMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct)

{

         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("未能创建工具栏\n");

                   return-1;      // 未能创建

         }

         if(!m_wndStatusBar.Create(this))

         {

                   TRACE0("未能创建状态栏\n");

                   return-1;      // 未能创建

         }

         m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));

 

         //TODO:  如果不需要可停靠工具栏,则删除这三行

         m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

         EnableDocking(CBRS_ALIGN_ANY);

         DockControlBar(&m_wndToolBar);

 

         /*************1.标记菜单*****************/

       GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);         //逐层次访问子菜单(文件 0)的菜单项(新建 0)

         //GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED);  //以命令ID访问

 

 

         /****************        2.创建默认菜单*******************/

         //对于一个菜单的默认菜单,只能有一个,当设置多个的时候就只有一个生效

         GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE);    //设置默认的菜单项(表现为加粗)。第一个参数是依赖于第二个参数,如果第二个参数是false,第一个参数用命令的ID,如果第二个参数是true,则第一个参数是位置索引,分割栏也占一个索引

         //GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN,FALSE);   //其中,false是默认的,可以不写

         //GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);    //设置默认的菜单项时,如果用索引号,注意分栏也占一个号

        

         /*******************3.创建图形标记菜单************/

         CStringstr;      //以下三行是为了获得系统图标的大小,然后调整图标大小,使图标显示适当

         str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));

         MessageBox(str);          //标记的大小  

        //CBitmap m_bitmap 作为一个成员函数,写在成员变量里,不在这

         m_bitmap.LoadBitmap(IDB_BITMAP1);              //下载一副自己制作的位图

         GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION, &m_bitmap, &m_bitmap);   //将位图设置在菜单项前

 

         /**********************4.禁用菜单******************/

         GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION|MF_DISABLED|MY_GRAYED);       //(不能用时自动变灰)在设置同时,需要在frame的构造函数中m_bAutoMenuEnable = FALSE;

 

         /*以下是移除一个菜单后加载一个菜单*/

         //SetMenu(NULL);                    //当参数为NULL时,菜单被移除

 

         //CMenumenu;                          //定义一个菜单,如果用一个局部变量menu,可以用SetMenu设置菜单,但后面用要menu.Detach

         //menu.LoadMenuA(IDR_MAINFRAME);            //加载一个菜单

         //SetMenu(&menu);                                                //设置一个菜单   调用setmenu后一定要紧接着用菜单对象的detach将菜单句柄与菜单对象分开

         //menu.Detach();                     //将菜单句柄和c++对象断开,防止窗口重绘时候发生错误,menu对象析构时不会销毁菜单

         return0;

}

 

3.    右键弹出菜单

在资源中增加一个menu,并对菜单的每一个子菜单设置caption 和ID号。

增加鼠标右键点击的消息响应OnRButtonDown。

对子菜单编写命令处理函数,。

void CMenuView::OnRButtonDown(UINT nFlags,CPoint point)

{

         //TODO:  在此添加消息处理程序代码和/或调用默认值

         CMenumenu;                                //定义一个菜单 

         menu.LoadMenu(IDR_MENU1);                  //加载一个菜单资源

         CMenu*pPopup = menu.GetSubMenu(0);        //获取一个子菜单

         ClientToScreen(&point);                    //将客户区坐标转换为屏幕坐标

 

         pPopup->TrackPopupMenu(TPM_LEFTALIGN| TPM_RIGHTBUTTON, point.x, point.y, this);     //显示菜单

         //TrackPopupMenu第一个参数表示菜单显示的位置,第二三参数表示鼠标点击的位置,第四个表示菜单的拥有者,第五个是默认的,指示了一个区域,当点击区域外面时,菜单无效

         //当地四个选项说明拥有者后,菜单的子菜单的拥有者也是它

          CView::OnRButtonDown(nFlags,point);

}

  

1 0
原创粉丝点击