1VisualC++游戏程序设计菜单编程一、上机目的:(1)掌握关于CMenu类成员函数的编程方法。(2)掌握动态加载子菜单。(3)掌握添加菜单项及其命令响应函数。(4)掌握用MSDN查找相关API函数。二、上机内容:以下题目都在VC++6.0环境下编程完成。1、电话本示例程序功能:在应用程序的窗口中,输入一行文字,这行文字的格式是:人名电话号码。在这行文字输入完成后按下回车键,就会在程序的菜单上的【帮助】菜单之后动态生成一个子菜单,并且刚才输入的人名将作为其中的一个菜单项来显示,然后可以继续上述过程,接着在程序窗口中输入下一行文字,但这时按下回车键后,并不需要再新添一个子菜单,而是直接在已添加的子菜单下添加菜单项,这个新菜单项的文本就是新输入的人名。当单击这个动态生成的子菜单中的某个菜单项时,程序就会把相应的人名和电话号码显示在程序窗口上。操作步骤:(1)新建一个MFC的单文档工程,工程名为:Menu2;(2)在CMainFrame类的OnCreate函数中添加代码:(3)添加动态子菜单的实现:为了在窗口中显示键盘输入的文字内容,视类需要捕获WM_CHAR消息,这可2以利用类向导完成,程序运行时,只是在第一次输入一行文字后按下回车键时,需要在菜单栏上添加一个动态子菜单,以后只是向这个子菜单添加菜单项。为视图类添加一个int类型的变量m_nIndex,在构造函数中初始化为-1,用来指示当前是第几次按下回车键。另外,还需要为视图类增加一个CMenu类型的成员变量m_menu,用于创建新的子菜单使用。然后在WM_CHAR消息响应函数中需要进行判断,只有是第一次按下回车键时,才为程序添加一个新的子菜单。代码如下:(4)我们运行代码,发现敲入的几个字符,然后按回车键,这时将会发现Menu2程序的菜单栏上并没有添加PhoneBook子菜单,但当我们把鼠标移动到应该显示这个子菜单的位置时,或者程序窗口尺寸发生变化之后,这个子菜单就出现了。为什么会这样呢?为什么先前在CMainFrame类的OnCreate函数中进行的菜单操作会立即显示结果?这时因为CMainFrame类的OnCreate函数的作用是实现窗口的创建,也就是说,在调用这个函数时,程序的窗口还未创建和显示,所以这个函数中对窗口上的菜单所做的修改会立即在程序界面上呈现出来。但是在窗口创建并显示完成之后,再去修改程序菜单的内容时,需要对菜单栏进行一次重绘操作才能显现修改的结果。CWnd类提供了一个DrawMenuBar成员函数用来完成菜单栏的重绘操作。修改后代码如下:(5)运行程序,随意输入几个字符,将会发现程序的状态和刚才一样,程序的菜单栏上还是没有出现PhoneBook子菜单,当我们把鼠标移动到应该显示这个子菜单的位置时,或者程序窗口的尺寸发生变化之后,这个子菜单就出现了。这又是什么原因呢?我们发现在视图类中调用DrawMenuBar这个函数,菜单属于框架类窗口的,因此,应该让框架类窗口去重绘菜单栏。这样的话,在3CMenu2View类的OnChar函数中,就应该先利用GetParent函数获得视类的父窗口:框架类窗口,然后再利用该窗口对象去调用DrawMenuBar函数,修改后代码如下:(6)显示输入的字符我们在视图类中增加一个CString类型的成员变量,用来保存输入的字符。成员变量为m_strLine。接着在视图类的构造函数中将这个变量初始化为空。m_strLine=””;然后在OnChar函数中就可以把当前的输入的字符先添加到m_strLine变量中,再利用CDC类的TextOut函数在窗口(0,0)位置处输出。具体代码如下:运行程序输入abc12345678按下回车键,将会发现程序的菜单栏上立即多了一个子菜单:PhoneBook。当我们再次输入字符时,发现字符是接着刚才那行文字输出的。这时因为程序中将输入的字符不断地添加到用来保存输入字符的字符串变量:m_strLine中,这样它就会把以前的输入内容也显示出来,正确的做法是按下回车键后,将m_strLine这个变量中的内容清空。修改后的代码如下。4再次测试,将会发现出现一个问题:再次输入的文字是在上次输入的文字之上显示的,我们将希望将上次显示的内容清除掉,再显示当前输入的文字。有多种方法可以实现窗口上文字的擦除,这里,我们利用CWnd类有一个名为Invalidate的成员函数,该函数的作用是让窗口的整个客户区无效,这样,当下一条WM_PAINT消息发生时,窗口就会被更新。voidInvalidate(BOOLbErase=TRUE);请参考MSDN理解该函数。在m_strLine.Empty()代码之后加上下面这行代码,即给Invalidate函数传递一个TRUE值,让视图类窗口重绘并擦除窗口的背景。这样,在显示新一行输入字符串时,窗口上已显示的上一次输入的文字已消失了。Invalidate();再次测试Menu2程序,可以发现当按下回车键后,先前输入的文字从窗口上消失了。接下来再输入字符时,窗口就会显示新的输入字符。(7)添加菜单项及其命令响应函数接下来需要实现现在输入人名、空格、电话号码,并当按下回车键后,把输入的人名作为菜单项的文本添加到PhoneBook子菜单下这一功能。代码如下:5大家可以运行测试(8)下面就要实现当单击这些菜单时,应在程序窗口中显示对应的字符串,即:人名电话号码。那么在程序中就应该将所有输入的字符串都保存起来。我们可以定义字符串数组来保存用户输入的所有字符串,但是不知道用户输入多少。数组大小无法确定。MFC为我们提供了一些非常有用的集合类,这些集合类类似于数组的集合类,这个集合类支持CString对象的数组。为了增加一个字符串元素,可以利用该集合类的Add成员函数:IntAdd(LPCTSTRnewElement);//查找MSDN理解它当需要返回一个集合元素时,可以利用集合类的GetAt成员函数,这个函数如下所示:CString::GetAt(intnIndex)const;下面我们为CMenuView类定义一个公有的CStringArray类型的成员变量:m_strArray,用来保存所有输入的字符串。至于为什么将m_strLine声明为公有的。对应的代码如下:6程序的要求是当单击动态添加的人名菜单项时,程序要在窗口中显示对应的字符串:人名电话号码。首先动态添加的菜单项进行命令捕获。首先,在Menu2工程中,在资源编辑器打开程序的菜单。然后在【帮助】子菜单后面添加一个新的子菜单,名称可以任意,例如abc,接着为它添加几个菜单项。菜单项名称菜单项ID1IDM_PHONE12IDM_PHONE23IDM_PHONE34IDM_PHONE4在Menu2程序的Resource.h文件,在其中可以看到如下几行代码:#defineIDM_PHONE132771#defineIDM_PHONE232772#defineIDM_PHONE332773#defineIDM_PHONE432774然后利用ClassWizard为CMenu类分别添加以上这四个菜单项的命令响应函数,其中在消息列表中都选择COMMAND消息。接下来,我们在菜单编辑器中删除刚才新添加的子菜单abc。但是将会发现他们的命令响应函数在源文件中保存了下来。在OnChar函数中找到动态添加菜单项的代码,即调用AppendMenu函数的那行代码,把其中菜单ID参数改成IDM_PHONE1,即m_menu.AppendMenu(MF_STRING,IDM_PHONE1+m_nIndex,m_strLine.Left(m_strLine.Find('')));依次类推,可以看到CMenu2View类的头文件中消息映射函数的声明代码:同时发现在源文件中发现:7经过以上几步,Menu2程序的CMenu2View类就有了四个动态菜单项的命令响应函数。比如第一个:voidCMenu2View::OnPhone1(){//TODO:AddyourcommandhandlercodehereCClientDCdc(this);dc.TextOut(0,0,m_strArray.GetAt(0));}依次类推其他三个函数。(9)框架类窗口截获菜单命令消息下面让程序动态添加的菜单项命令由框架类来捕获。经过“菜单命令的路由”过程,交由OnCommand函数来处理的,这个函数中将完成命令消息的路由。CWnd::OnCommandvirtualBOOLOnCommand(WPARAMwParam,LPARAMlParam);ReturnValueAnapplicationreturnsnonzeroifitprocessesthismessage;otherwise0.ParameterswParamThelow-orderwordofwParamidentifiesthecommandIDofthemenuitem,control,oraccelerator.Thehigh-orderwordofwParamspecifiesthenotificationmessageifthemessageisfromacontrol.Ifthemessageisfromanaccelerator,thehigh-orderwordis1.Ifthemessageisfromamenu,thehigh-orderwordis0.8lParamIdentifiesthecontrolthatsendsthemessageifthemessageisfromacontrol.Otherwise,lParamis0.我们在CMainFrame类添加一个虚函数:我们单击编辑存在按钮,写出如下代码:9如果出现错误,请做如下修改:大家想想为什么这样?三、上机心得主要写感想,这次上机过程的情况。包括遇到的难点,和上机的运行情况和同学们交流情况。(至少写6行文字以上)