您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > VC++基于菜单与工具栏的程序创建
菜单菜单是重要的用户界面对象,用户通常从菜单栏中选择命令来使用应用程序。Windows98支持三种类型的菜单:(1)菜单栏(主菜单):菜单栏横放在窗口的顶部(2)弹出式子菜单:弹出式菜单是从主菜单下弹出的菜单(3)上下文菜单:通过鼠标右键弹出的自由浮动菜单1.菜单的机制与功能菜单可以用多种方法创建,一般存在在资源脚本中,在程序运行时才调入,就像其他资源一样。1.1菜单消息菜单被选中时发送消息给Windows,再由Windows传送给应用程序的消息映像。Win32API提供4个菜单消息,但在MFC消息映像中,只有两个菜单消息WM_COMMAND和ON_UPDATE_COMMAND_UI。MFC自动处理其他两个消息。(1)处理WM_COMMAND消息用户选中了菜单项会产生WM_COMMAND消息MFC的框架窗口类要确保每一个菜单项都有WM_COMMAND消息的处理函数,对缺少处理函数的菜单项,MFC使其变灰。消息映射ON_COMMAND项采用以下形式:ON_COMMAND(MenuID,ClassMethod)MenuID是菜单项的标识符,ClassMethod是处理菜单项WM_COMMAND消息定义的方法(命令处理函数)。(2)处理UPDATE_COMMAND_UI消息在许多情况下菜单项可能有多个状态。例如某一个时刻可用(正常),而某一个时刻不可用(菜单变灰);菜单项可以加注标记,以表明被选中或未被选中。UPDATE_COMMAND_UI是MFC所特有的,如果想根据应用程序的当前状态激活或者使菜单项无效,或者在程序运行的某一刻反映菜单项的可用性,就要由自己处理这条消息。此消息和Win32API的WM_INITPOPUPMENU消息相对应。ON_UPDATE_COMMAND_UI项采用以下形式:ON_UPDATE_COMMAND_UI(MenuID,ClassMethod)MenuID是菜单项的标识符,ClassMethod是处理菜单UPDATE_COMMAND_UI消息定义的方法(更新处理函数)该消息值适合弹出式菜单项的菜单项,而对于顶层菜单项则不适用。例如不能使用该消息来禁止“文件”菜单项。如果菜单项有更新处理函数,那么它被调用进行更新;如果没有,那么框架检查命令处理函数是否存在,若不存在,则使菜单变灰。必须提供一个菜单处理函数或更新函数。1.2基于菜单栏的程序设计1Menuitem程序为一个单文档的应用程序,程序启动后,单击“graph”菜单中的“rectangle”,则在当前的客户区中显示一个矩形;单击“graph”菜单中的“Ellipse”,则在当前的客户区中显示一个椭圆。(1)利用AppWizard,生成一个MFC的单文档工程“Menuitem”。(2)单击“Workspace”窗口的“ResourceView”标签,找到“Menu”项,双击“ID_MAINFRAME”,对菜单资源进行编辑。用右键单击菜单项最右边的虚线框,在弹出式菜单中选择“Propertis”命令,在“MenuItemProperties”窗体中在“Caption”一栏中输入“graph”用同样方法,设计其下的两个菜单项:第一个子菜单项,“ID”为“ID_GRAPH_REC”,“Caption”为“Rectangle”。第二个子菜单项,“ID”为“ID_GRAPH_ELLIPSE”,“Caption”为“Ellipse”。(3)在“CMenuitemView”类中加入一些数据成员:public:boolm_rectangle;boolm_ellipse;COLORREFm_crbk;(4)编辑“MenuitemView.cpp”文件中的构造函数,初始化数据成员,加入下面代码:CMenuitemView::CMenuitemView(){m_rectangle=TRUE;m_ellipse=FALSE;m_crbk=RGB(255,0,0);}(5)利用ClassWizard为视图类加入命令消息控制函数及更新命令UI消息控制函数。(6)编辑“MenuitemView.cpp”文件里的菜单命令控制函数。OnGraphRec函数用m_crbk颜色来填充客户区矩形,并设置布尔型变量m_rectangle、m_ellipse的值。VoidCMenuitemView::OnGraphRec(){CClientDCdc(this);CPennewpen,*oldpen;newpen.CreatePen(PS_SOLID,2,RGB(255,255,0));oldpen=dc.SelectObject(&newpen);CBrush*pNewBrush,*pOldBrush;pNewBrush=newCBrush;pNewBrush-CreateSolidBrush(m_crbk);pOldBrush=dc.SelectObject(pNewBrush);dc.Rectangle(40,20,200,50);m_rectangle=FALSE;m_ellipse=TRUE;dc.SelectObject(pOldBrush);dc.SelectObject(oldpen);deletepNewBrush;}对应的更新命令UI控制函数OnUpdateGraphRec根据变量m_rectangle的值来控制菜单的有效性状态,决定菜单项“rectangle”什么时候有效。voidCMenuitemView::OnUpdateGraphRec(CCmdUI*pCmdUI){pCmdUI-Enable(m_rectangle);}OnGraphEllipse函数用m_crbk颜色来填充客户区,并设置布尔型变量m_ellipse、m_rectangle的值。VoidCMenuitemView::OnGraphEllipse(){CClientDCdc(this);CPennewpen,*oldpen;newpen.CreatePen(PS_SOLID,2,RGB(255,255,0));oldpen=dc.SelectObject(&newpen);CBrush*pNewBrush,*pOldBrush;pNewBrush=newCBrush;pNewBrush-CreateSolidBrush(m_crbk);pOldBrush=dc.SelectObject(pNewBrush);dc.Ellipse(230,70,310,150);m_rectangle=TRUE;m_ellipse=FALSE;dc.SelectObject(pOldBrush);dc.SelectObject(oldpen);deletepNewBrush;}对应的更新命令UI控制函数OnUpdateGraphEllipse,根据变量m_ellipse的值来控制菜单的有效性状态,决定菜单项“ellipse”什么时候有效voidCMenuitemView::OnUpdateGraphEllipse(CCmdUI*pCmdUI){pCmdUI-Enable(m_ellipse);}1.3菜单消息的处理路径MFC中拥有菜单的框架窗口不必处理每一个菜单项的消息;相反,菜单消息可由拥有这个菜单命令资源的其他对象来处理。例如,CCmdTarget派生类对象(如窗口和视窗)以及应用对象(由CWinApp派生),对于支持文档/视窗架构的应用程序,文档对象和视窗对象也能处理菜单消息。尽管任何由CCmdTarget派生的类对象都能接受菜单消息,但并不是所有这类对象都可以同时接收到菜单消息,菜单消息是按照一定的路径传送的,下表列出了当MFC发送命令消息给非文档/视窗结构的应用,单文档应用以及多文档应用时,查找消息映射表的次序。查找消息映射表的次序程序类型搜索路径SDI单文档当前视图当前文档文档模板主框架窗口应用程序对象MDI多文档当前视图当前文档创建文档的文档模板活动的子框架窗口主框架窗口应用程序对象对话框当前对话框对话框的父窗口应用程序对象应用程序收到一个菜单命令时,它按照一定的顺序传递该命令,该顺序依次为:视窗类、文档类、主框架类和应用类。首先是视窗类获得处理该命令的机会,然后是文档类,再接着是主框架类,最后是应用类。如果某个类没有相应的菜单命令,则该命令返回给上一个类处理,直到返回到应用类。如果其中有一个类处理了该命令,则直接返回系统,其他类就没有机会再处理了。1.4弹出式菜单浮动的弹出式菜单是一种新的用户界面设计风格。用户按下鼠标右键,然后就会弹出一个浮动菜单。用资源编辑器和MFC库的CMenu::TrackPopupMenu函数可以创建弹出式菜单,该函数的原型:BOOLTrackPopupMenu(UNITnFlags,intx,inty,CWnd*pWnd,LPCRECTlpRct=NULL);其中参数nFlags为弹出式菜单的标志,例如若其值为TPM_RIGHTALIGN,表示创建的弹出式浮动菜单,其右边界位于X处;若其值为TPM_LEFTALIGN,表示其左边界位于X处,参数X与Y表示屏幕坐标。(1)浮动菜单的创建创建菜单对象需要两步。第一步,分配一个C++对象;第二部,初始化该对象。下面为创建并初始化一个CMenu类对象的典型代码://为浮动菜单申请一个对象空间CMenupContexMenu;//初始化CMenu对象pContexMenu.LoadMenu(IDR_MENU1);(2)浮动菜单的显示浮动菜单创建和初始化后,在用户单击了鼠标右键时显示。下面的WM_RBUTTONDOWN消息处理函数就可以显示出上面例子中的浮动菜单。voidMyMainFrame::OnRButtonDown(UNITnFlags,CPointpoint){//首先将客户区坐标转换成屏幕坐标ClientToScreen(&point);//在鼠标的位置显示浮动菜单CMenu*pMenu=pContexMenu-GetSubMenu(0);pMenu-TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);//调用缺省的处理函数CFrameWnd::OnRButtonDown(nFlags,point);}1.5弹出式菜单设计按照如下步骤创建弹出式菜单。(1)选择“Insert/Resource”菜单命令,将弹出“InsertResource”窗体,选中“Menu”选项,然后单击“New”,将产生一个空的“ID_MENU1”菜单。(2)双击选择“IDR_MAINFRAME”菜单,然后右键单击“graph”菜单项,在弹出式菜单中选择“Copy”命令。(3)双击选择“ID_MENU1”菜单,右键单击第一个空的菜单,在弹出菜单中选择“Paste”命令,将产生一个菜单项。(4)用ClassWizard在视图类中加入WM_RBUTTONDOWN消息控制函数,然后加入程序代码如下:voidCTest1View::OnRButtonDown(UINTnFlags,CPointpoint){CMenumenu;menu.LoadMenu(IDR_MENU1);ClientToScreen(&point);menu.GetSubMenu(0)-TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);}(5)编译运行程序,在运行的窗口中,右键单击,即可显示出弹出式菜单,并执行相应的命令。2.CMenu类2.1CMenu类简介MFC是靠CMenu来管理菜单的。CMenu对象可以代表每个Windows菜单,其中包括顶级菜单项以及与之相关联的弹出式菜单。当窗口的Create或LoadFrame函数被调用的时候,菜单的资源是直接附加到框架窗口的,CWnd成员函数GetMenu返回一个临时CMenu指针。利用该指针,可以自由地访问和更新菜单对象。ID_MAI
本文标题:VC++基于菜单与工具栏的程序创建
链接地址:https://www.777doc.com/doc-2854393 .html