




已阅读5页,还剩124页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MFC微软基础类,MFC(MicrosoftFoundationClass)微软基础类是一个由Microsoft公司设计的类库。MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员要做的就是通过接口把具体应用程序特有的东西填入这个轮廓。MFC的目的是让应用程序员在应用程序框架的基础上建立Windows下的应用程序,这种方法相对于SDK来说更为简单。采用MFC方式编程提高了Windows应用程序的开发效率。认识MFC只是一个过程、一个手段,最终目的是为了良好并熟练地运用MFC。,采用MFC编程的优点,使用标准化的程序代码结构,有利于程序员之间的交流。VisualC+为MFC提供了大量的工具支持,提高了编程效率。如利用MFCAppWizard创建MFC应用程序框架,利用ClassWizard方便地对Windows消息进行管理。MFC应用程序的效率较高,只比传统的WindowsC程序低5%左右。并且,在MFC应用程序中还允许混合使用传统的WindowsAPI函数。其它优势:完全支持Windows所有的函数、控件、消息、菜单及对话框;具有良好的稳定性和可移植性,更符合微软的风格等。,MFC体系结构,MFC主要组成部分:类、宏和全局函数。类是MFC中最主要的内容。MFC类是以层次结构方式组织起来的。MFC中的类分成两部分,除了一些辅助类,大多数的MFC类是直接或间接从根类CObject派生而来。几乎每一个派生层次都与一具体的Windows实例相对应,如文档类、窗口类和视图类等。MFC宏主要功能:消息映射、运行时对象类型服务、诊断服务、异常处理。MFC约定:全局函数以“Afx”为前缀,全局变量以“afx”为前缀。,学习MFC的方法,首先要对Windows编程概念和API函数有一定的了解,如WindowsAPI有哪些功能和哪些常用的数据结构等。学会抽象地把握问题,不求甚解,不要一开始学习VisualC+就试图了解整个MFC类库。从理解和使用两个方面学习MFC,理解MFC应用程序的框架结构。先大体上了解MFC的概念、组成和基本约定,从简单的类入手,结合程序设计,由浅入深,循序渐进、日积月累。编程时如果MFC某个类能完成所需要的功能,可以直接调用已有类的方法(成员函数)。否则,可以利用面向对象技术中的“继承”方法对MFC类的行为进行扩充和修改,从MFC中已有的类派生出自己需要的类。学习MFC,另一点就是不要过分依赖于向导(Wizard)工具。向导能做许多工作,但同时掩饰了太多的细节。,MFC应用程序生成,MFC中的常用类,CObject、CCmdTarget、CWinThread、CWinApp、CWnd、CFrameWnd、CDialog、CView、CStatic、CButton、CListBox、CComboBox、CEdit、CScrollBarMFC中的大部分类都是从基类CObject中继承的,该类包含大部分MFC类所通用的数据成员和成员函数;CWinApp类是在建立应用程序时需要用到的,并且在任何程序中都只用一次;CWnd类汇集了Windows中的所有通用特性、对话框和控制。CFrameWnd类是从CWnd中继承的,并实现了标准的框架应用程序;,CDialog可分别处理无模式和有模式两种类型的对话框。CView用于让用户通过窗口来访问文档。,在MFC应用程序的CWinApp派生类对象theApp是一个全局变量,代表了应用程序运行的主线程。它在程序整个运行期间都存在,它的销毁意味着运行程序的消亡。MFC应用程序启动时,首先创建应用程序对象theApp,这时将自动调用应用程序类的构造函数初始化对象theApp,然后由应用程序框架调用MFC提供的AfxWinMain()主函数。AfxWinMain()主函数首先通过调用全局函数AfxGetApp()获取应用程序对象theApp的指针pApp,然后通过pApp调用应用程序对象的有关成员函数,完成程序的初始化和启动工作,最后调用成员函数Run(),进入消息循环。程序运行后将收到WM_PAINT消息,调用OnPaint()函数绘制客户区窗口。如果Run()收到WM_QUIT消息,则结束消息循环,然后调用函数ExitInstance(),结束程序运行。,MFC应用程序的生与死,hello程序流程,MFC应用程序对象之间的关系,MFC应用程序运行后各函数的调用关系,InitInstance()函数是派生类唯一需要重载的函数,它负责应用程序的初始化。,CWinApp类,CWinApp类提供了用户与Windows应用程序之间进行交流的接口。在生成类的对象后,对象自动建立与Windows系统的连接、接收Windows传送的消息,并交给程序中相应的对象去处理,这就免去了程序员的许多工作,使得开发C+的Windows程序变得简单方便。CWinApp类的对象theApp将自动创建一个主线程,主线程中有一个循环体,用来不断的从应用消息队列中提取消息,并发送回操作系统,让操作系统调用窗口过程函数,实现消息响应。CWinApp类通过消息映射宏的方式,方便开发人员完成消息与响应函数之间的对应关系,大大简化了编程难度与复杂度。,CMainFrame类,类CMainFrame是由MFC中的CFrameWnd派生的,所以它也是一个框架窗口。CMainFrame是类CXXView的父类,即CXXView类的对象显示在主框架窗口的客户区中。在类CMainFrame中,系统已经从类CFrameWnd中继承了处理窗口的一般事件的Windows消息,如改变窗口的大小、窗口最小化等的成员函数,因此编程时程序员不必关心此类消息的处理,从而减轻了程序员的负担。当然,如果确实需要重新编写此类消息的成员函数,则需要对原有的成员函数进行重载。,当程序的一个实例被运行时,系统将根据前面在CWinApp类中介绍的文档模板对象自动生成类CMainFrame、CXXView、CXXDoc的对象,而不需要程序员主动地去创建这些类的对象。,类CXXView与CXXDoc,这两个类是密切相关的,文档是由文档模板对象生成的,并由应用程序对象管理,而用户则是通过与文档相联系的视窗对象来存储、管理应用程序中的数据,用户与文档之间的交互是通过与文档相关联的视窗对象进行的。生成一个新的文档时,MFC程序同时生成一个框架窗口,并且在框架窗口的客户区中生成一个视窗对象作为框架窗口的子窗口,这个子窗口以可视化的方式表现文档中的内容。视窗的重要功能就是负责处理用户的鼠标、键盘等操作,通过对视窗对象的处理达到处理文档对象的目的。,MFC通用控件类和窗口类,绘图类,CClientDC类:一般用来方便地创建和销毁一个设备环境。CClientDC通常在堆栈上创建。析构函数自动调用ReleaseDC(),不会导致内存资源泄漏.CWindowDC类:与CClientDC类相似,但它的工作范围是窗口的非客户区。CPaintDC类:仅允许绘制无效的窗口客户区而不是绘制整个窗口,CWnd:BeginPaint()与CWnd:EndPaint()配对使用;CMetaFileDC类:用于创建元文件,元文件是一种磁盘文件,它包含了所有的绘图行为以及绘制图像所需要的绘图模式。,常用的MFC文件和库文件,进入下一节,MFC消息管理,MFC应用程序消息处理的方式与SDK应用程序有所不同。MFC应用程序框架截取了Windows向应用程序发出的消息,再确定将消息发送给哪一个对象,可以根据需要利用函数重载对消息进行处理,但不需要处理的消息将由应用程序框架自动处理。消息管理包括消息的发送和处理。对于消息发送,MFC提供了类似于API函数功能的消息发送函数,而MFC消息处理的内部机制则相对复杂一些。从编程的角度出发,我们只需了解其大致的原理。,MFC的消息分类,标准Windows消息:以WM_前缀(但不包括WM_COMMAND)开始的消息,包括鼠标消息、键盘消息和窗口消息,如WM_MOVE、WM_PAINT等。控件通知(ControlNotification)消息:对控件操作引起的消息,是控件和子窗口向其父窗口发出的WM_COMMAND通知消息。例如,当用户修改了编辑控件中的文本后,编辑控件向其父窗口发送WM_COMMAND通知消息。命令(Command)消息:由菜单项、工具栏按钮、快捷键等用户界面对象发出的WM_COMMAND消息。命令消息与其它消息不同,它可被更广泛的的对象如文档、文档模板、应用程序对象、窗口和视图等处理。自定义消息,MFC消息映射机制,MFC采用消息映射(MessageMap)机制取代C/C+语言中的switch-case结构来处理消息。MFC消息映射机制包括一组消息映射宏,一条消息映射宏把一个Windows消息和其消息处理函数联结起来。在类定义的结尾用DECLARE_MESSAGE_MAP()宏来声明使用消息映射。在类的实现源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏来定义消息映射。ON_COMMAND宏:消息映射宏的第一个参数为消息ID,第二个参数为消息处理函数。如ON_COMMAND(ID_FILE_NEW,CWinApp:OnFileNew)。MFC使用ClassWizard帮助实现消息映射功能。,例子:在AppWizard产生的应用程序类的源码中,应用程序类的定义(头文件)包含了类似如下的代码:/AFX_MSG(CTttApp)afx_msgvoidOnAppAbout();/AFX_MSGDECLARE_MESSAGE_MAP()应用程序类的实现文件中包含了类似如下的代码:BEGIN_MESSAGE_MAP(CTApp,CWinApp)/AFX_MSG_MAP(CTttApp)ON_COMMAND(ID_APP_ABOUT,OnAppAbout)/AFX_MSG_MAPEND_MESSAGE_MAP()头文件里是消息映射和消息处理函数的声明,实现文件里是消息映射的实现和消息处理函数的实现。它表示让应用程序对象处理命令消息ID_APP_ABOUT,消息处理函数是OnAppAbout。,MFC应用程序MESSAGE_MAP消息映射形式,BEGIN_MESSAGE_MAP(theclass,baseclass)/AFX_MSG_MAP(theclass)ON_./MFC预定义的消息映射宏ON_MESSAGE(message,memberFxn)/用户自定义的消息映射宏./AFX_MSG_MAPEND_MESSAGE_MAP(),注意:特殊注解“/AFX_MSG_MAP”是ClassWizard类向导用于维护消息映射宏的标记,用户不要删除注解轻易修改注解内的代码。,例利用ClassWizard为框架类添加消息WM_CLOSE、WM_DESTROY及菜单项“Edit|Copy”的消息处理函数,分析ClassWizard完成了哪些工作。,启动ClassWizard,添加要求的三个消息处理函数,ClassWizard将在类的实现文件中添加三个消息映射宏和消息处理函数。消息映射宏如下:BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)/AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()/由MFCAppWizard程序向导自动生成的消息映射ON_WM_CLOSE()/由ClassWizard类向导添加ON_WM_DESTROY()ON_COMMAND(ID_EDIT_COPY,OnEditCopy)/AFX_MSG_MAPEND_MESSAGE_MAP(),ClassWizard在类的定义中声明了消息处理函数,classCMainFrame:CFrameWndpublic:CMainFrame();protected:/AFX_MSG(CMainFrame)/声明消息处理函数原形afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct);/由程序向导自动生成afx_msgvoidOnClose();/由ClassWizard类向导添加afx_msgvoidOnDestroy();afx_msgvoidOnEditCopy();/AFX_MSGDECLARE_MESSAGE_MAP()/声明使用消息映射宏;,消息的发送,发送消息到一个窗口可以采用传送(Send)或寄送(Post)方式,这两种方式之间的主要区别是消息被接收对象收到后是否立即被处理。Windows提供了三个API函数用于消息的发送。函数SendMessage()用于向一个或多个窗口传送消息,该函数将调用目标窗口的窗口函数,直到目标窗口处理完收到的消息,该函数才返回。函数PostMessage()用于向一个或多个窗口寄送消息,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回。函数SendDlgItemMessage()函数用于向对话框中指定的控件发送消息,直到目标控件处理完收到的消息,该函数才返回。,MFC将这三个函数封装为CWnd窗口类的成员函数,封装了目标窗口句柄,它们将向调用它的窗口对象发送或寄送消息,如pMyView-SendMessage()的调用形式表示向pMyView所指对象发送消息。与用户输入相关的消息(如鼠标消息和键盘消息)通常是以寄送(Post)的方式发送,以便这些用户输入可以由运行较缓慢的系统进行缓冲处理。而其它消息通常是以传送(Send)的方式发送。,手工处理消息映射,创建自己的消息映射的具体过程:定义自己的消息ID:MFC允许用户自定义消息,常量WM_USER(为0 x0400)与第一个自定义消息值相对应,用户必须为自己的消息定义相对于WM_USER的偏移值。利用#define语句定义自己的消息,例如:#defineWM_USER0X0400#defineWM_USER1WM_USER+0#defineWM_USER2WM_USER+1,是对应的消息处理函定义消息映射:在BEGIN_MESSAGE_MAP()之后,END_MESSAGE_MAP()之前加入消息映射语句:ON_MESSAGE(message,memberFxn)其中,message是消息名标识,memberFxn数。在cpp文件中定义消息处理函数,对消息进行响应:自定义消息处理函数的声明:必须在函数返回类型前面加上afx_msg标识,如:afx_msgLRESULTmemberFxn(WPARAMwParam,LPARAMlParam);其中,参数wParam、lParam用于传递消息的两个附加信息。在需要发送消息的地方发送消息:可用CWnd:SendMessage()函数或CWnd:PostMessage()函数发送消息。,例编写一个自定义消息应用程序,程序启动后设置一个定时器,在WM_TIMER的消息处理函数中发送一个用户自定义消息,在对应的自定义消息处理函数中以动画的形式旋转显示一行文本。,基本思路:用WM_TIMER消息处理函数发送消息;启动定时器销毁定时器用自定义消息完成动画旋转显示功能。自定义消息ID定义消息映射定义消息处理函数,具体过程:1首先利用MFCAppWizardexe向导创建一个名为Rotate的应用程序。利用ClassWizard类向导为CRotateView类生成消息WM_CREATE的消息处理函数,通过设置定时器在指定的时间间隔向窗口发送WM_TIMER消息。SetTimer(1,200,NULL);/启动定时器2在文件RotateView.cpp开始位置定义一个用户自定义消息:#defineWM_MYMESSAGEWM_USER+1利用ClassWizard为CRotateView类生成消息WM_TIME的消息处理函数:SendMessage(WM_MYMESSAGE);,3在类CRotateView的定义中声明自定义消息处理函数:afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);在文件RotateView.cpp消息映射BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加自定义消息映射宏:ON_MESSAGE(WM_MYMESSAGE,OnMyMyessage)4在类CRotateView的定义中声明一个private属性、int型的成员变量m_dEscapement,它表示文本显示角度,并在类CRotateView的构造函数中初始化:m_dEscapement=0;5利用ClassWizard生成消息WM_DESTROY的消息处理函数,在销毁已创建的定时器:KillTimer(1);,6在文件RotateView.cpp中手工添加自定义消息处理函数实现代码,完成以动画形式旋转显示一行文本的功能。LRESULTCE6_6View:OnMyMessage(WPARAMwParam,LPARAMlParam)CClientDCdc(this);m_dEacapement=(m_dEacapement+100)%3600;CFontfontRotate;fontRotate.CreateFont(30,0,m_dEacapement,0,0,0,0,0,0,0,0,0,0,0);CFont*pOldFont=dc.SelectObject(,如果不考虑自定义消息,可以采用其他方式:WM_TIMER消息处理函数:调用文本显示函数旋转变量的计算定义一个函数用来显示文本定义一个变量用于文本的位置计算,进入下一节,第三章文档视图结构:MFC的三种窗体类型,在MFC中,文档是真正的数据载体,视图是文档的显示界面,对应于同一个文档,可能存在多个视图界面,需要另外一种东西将界面管理起来,即框架。SDI单文档窗口:一次只处理一个文档,譬如记事本,绘图板;MDI多文档窗口:可同时处理多个文档,也意味着需要更多的额外编程工作。并不只是要跟踪所有打开的文档,还要提供Window菜单来管理特殊的程序特性;Dialog对话框窗口:通常只需要显示少量的数据和获取少量的用户输入,除了节省资源外,对话框版本的应用程序的加载速度也更快些;,文档和视图的四个核心类,1.Cdocument(或COleDocument):该类负责存储和管理程序的数据,并为自定义的文档类提供基础的功能。一个文档代表一个数据单元,用户可以通过文件菜单上的“打开”命令打开文档,或通过文件菜单上的“保存”命令保存文档。,2.Cview类或其派生类:该类为自定义的视图类提供了基础的功能。一个视图附加到一个文档并扮演一个文档和用户的中间人角色:视图显示文档的外观到屏幕上,并把用户的输入翻译成对文档的操作。此外,视图类还负责打印和打印预览的显示。CView最常用的函数是GetDocument,这个函数用于返回与此视图关联的文档。同时CView具有窗口类的功能,可以方便的定义消息处理函数,MFC定义了一个非常好的、在“文档-视图-框架”之间的消息传递机制。,3.CFrameWnd类:该类支持一个文档的一个或多个视图的框架,框架窗口类定义了一个视图的容器。一个SDI程序只使用一个框架窗口CFrameWnd类作为程序的顶层窗口提供视图的框架。一个MDI程序使用两种不同类型的框架窗口CMDIFrameWnd作为顶层窗口,CMDIChildWnd作为浮动窗口,为程序文档提供框架。,4.CDocTemplate(CSingleDocTemplate或CMultiDocTemplate):文档模板类支持某种类型的文档并管理这种类型的文档、视图和框架窗口对象。,文档模板,为了管理创建文档、视图和框架窗口的复杂过程,MFC框架使用两种文档模板类:CSingleDocTemplate类为SDI(单文档)程序提供支持CMultiDocTemplate类为MDI(多文档)程序提供支持。一个CSingleDocTemplate类可以一次创建和存储一个类型的文档。文档对象由程序对象创建并维护,在程序的InitInstance方法中完成的一个关键任务是创建一个或多个适当类型的文档模板,程序对象为模板列表中的每个文档模板存储一个指针,提供一个接口用来添加文档模板。如果需要支持两个或更多的文档类型,就应该为每种文档类型添加一个AddDocTemplate的调用。,多文档和多视图,文档-视图程序不仅局限在一个文档和基于文档数据的视图,通过使用MFC的Splitter窗口类,一个单文档接口(SDI)程序可以针对同一个文档实现两个或多个视图划分框架窗口客户区。文档-视图结构可以扩展到多文档接口(MDI)程序,以支持一个文档的多视图、多个打开的文档,甚至多个文档类型。,MDI程序和SDI程序的主要不同,1.MDI程序从CMDIFrameWnd类继承顶层框架窗口,而不是CFrameWnd类。2.MDI程序使用基于CMDIChildWnd类的子类来表示子框架窗口。3.MDI程序使用CMultiDocTemplate而不是CSingleDocTemplate来创建文档模板。4.在CMultiDocTemplate类中引用的框架窗口是子框架窗口类而不是顶层框架窗口。5.MDI程序有至少两个菜单资源,当没有文档打开时显示一个菜单,当有至少一个文档打开时显示另一个菜单。,单文档框架的初始化,BOOLCSinglePadApp:InitInstance()/使程序添加对OLE控件的包容支持AfxEnableControlContainer();#ifdef_AFXDLL/当使用MFC动态库时,使程序控件具有3D外观Enable3dControls();#else/当使用MFC静态库时,使程序控件具有3D外观Enable3dControlsStatic();#endif/程序用来存储配置信息的注册表值SetRegistryKey(_T(LocalAppWizard-GeneratedApplications);/加载标准的INI文件选项(包括MRU)LoadStdProfileSettings();/注册文档模板CSingleDocTemplate*pDocTemplate;,pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,/资源ID,文档的名称RUNTIME_CLASS(CSinglePadDoc),/文档RUNTIME_CLASS(CMainFrame),/主要的SDI框架窗口RUNTIME_CLASS(CSinglePadView);/视图/把注册的文档模板添加到程序中AddDocTemplate(pDocTemplate);/解析命令行完成如标准Shell命令、DDE、文件打开操作CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);/处理命令行中的命令if(!ProcessShellCommand(cmdInfo)returnFALSE;/显示和更新窗口m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();returnTRUE;,多文档框架的初始化,BOOLCMultiPadApp:InitInstance()AfxEnableControlContainer();/使程序添加对OLE控件的包容支持#ifdef_AFXDLLEnable3dControls();/使程序控件具有3D外观,当使用MFC动态库时。#elseEnable3dControlsStatic();/使程序控件具有3D外观,#endif/程序用来存储配置信息的注册表值SetRegistryKey(_T(LocalAppWizard-GeneratedApplications);LoadStdProfileSettings();/加载标准的INI文件选项(包括MRU)/注册文档模板CMultiDocTemplate*pDocTemplate;pDocTemplate=newCMultiDocTemplate(IDR_MULTIPTYPE,/MDI窗口的资源RUNTIME_CLASS(CMultiPadDoc),/MDI文档RUNTIME_CLASS(CChildFrame),/MDI子框架RUNTIME_CLASS(CMultiPadView);/MDI视图,/把注册的文档模板添加到程序中AddDocTemplate(pDocTemplate);/创建MDI主窗口CMainFrame*pMainFrame=newCMainFrame;/加载主窗口和主资源if(!pMainFrame-LoadFrame(IDR_MAINFRAME)returnFALSE;m_pMainWnd=pMainFrame;/解析命令行完成如标准Shell命令、DDE、文件打开操作CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);/处理命令行中的命令if(!ProcessShellCommand(cmdInfo)returnFALSE;/显示和更新窗口m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();returnTRUE;,例子:生成一个多文档记事本,视图选择为CEditView为基类,不用写一行代码就实现了一个记事本,可以保存,打开文档文件,例子:实现多文档的MDI程序,更改对应的类名为上图所示,为了创建一个新的文档模板,需要建立三个类,即CBallFrame(子框架窗口类)、CBallDoc(文档类)、CBallView(视图类)。,添加IDR_MULTBTYPE菜单资源中NewHello,NewBall两个菜单项,在CMDIApp类中添加新增的两个菜单项的响应函数,在MultiBall.cpp文件中添加三个子类的头文件,插入一个新的菜单资源IDR_BALLTYPE,BOOLCMDIApp:InitInstance()/加Hello模板到模板列表CMultiDocTemplate*pDocTemplate;pDocTemplate=newCMultiDocTemplate(IDR_MULTIBTYPE,RUNTIME_CLASS(CHelloDoc),RUNTIME_CLASS(CHelloFrame),/customMDIchildframeRUNTIME_CLASS(CHelloView);AddDocTemplate(pDocTemplate);/加球模板到模板列表CMultiDocTemplate*pBallTemplate=newCMultiDocTemplate(IDR_BALLTYPE,RUNTIME_CLASS(CBallDoc),RUNTIME_CLASS(CBallFrame),/customMDIchildframeRUNTIME_CLASS(CBallView);AddDocTemplate(pBallTemplate);/createmainMDIFramewindowCMainFrame*pMainFrame=newCMainFrame;if(!pMainFrame-LoadFrame(IDR_MAINFRAME)returnFALSE;m_pMainWnd=pMainFrame;/Themainwindowhasbeeninitialized,soshowandupdateit.pMainFrame-ShowWindow(m_nCmdShow);pMainFrame-UpdateWindow();returnTRUE;,添加新建文档的响应函数:OnNewHello,OnNewBall/下面两个菜单命令处理函数根据模板列表创建一个相应的新的视图文档voidCMDIApp:OnNewHello()/搜索模板列表里包含Hello串的文档模式POSITIONcurTemplatePos=GetFirstDocTemplatePosition();while(curTemplatePos!=NULL)CDocTemplate*curTemplate=GetNextDocTemplate(curTemplatePos);CStringstr;curTemplate-GetDocString(str,CDocTemplate:docName);if(str=_T(Hello)curTemplate-OpenDocumentFile(NULL);return;AfxMessageBox(NoHelloTemplate);,voidCMDIApp:OnNewBall()/搜索模板列表里包含Ball串的文档模式POSITIONcurTemplatePos=GetFirstDocTemplatePosition();while(curTemplatePos!=NULL)CDocTemplate*curTemplate=GetNextDocTemplate(curTemplatePos);CStringstr;curTemplate-GetDocString(str,CDocTemplate:docName);if(str=_T(Ball)curTemplate-OpenDocumentFile(NULL);return;AfxMessageBox(NoBallTemplate);,修改字符串资源中IDR_MULTIBTYPE的属性值,插入新的字符串资源IDR_BALLTYPE,并设置属性值,将CHelloView更改继承自CEditView类:替换CHelloView类源文件与头文件中所有的CView为CEditView;更改CHelloDoc类中Serialize序列化函数的实现为:(CEditView*)m_viewList.GetHead()-SerializeRaw(ar);这样就可以实现将CHelloView由普通的视图类调整为可以编辑保存的编辑视图对象;在CBallView的OnDraw()函数中添加代码如下:CRectrect;GetClientRect(rect);pDC-SetTextAlign(TA_BASELINE|TA_CENTER);/设置文本排列居中pDC-SetTextColor(RGB(255,0,0);/设置文本颜色pDC-SetBkMode(TRANSPARENT);/设置背景模式为透明pDC-TextOut(rect.Width()/2,rect.Height()/2,BallView,9);,例子二单文档多视图(分割视图),1.首先创建一个MFC单文档应用程序。2.添加4个MFC类TopLView、BottomLView、TopRView、BottomRView,基类为CView。3.添加一个MFC类CControlForm,基类为CFormView,对话框ID默认。4.创建一个切分类,如MySplitter,基类为CSplitterWnd(默认基类选项中无此类,可以先选择CFrameWnd类,生成后再修改为CSplitterWnd类)。5.在框架类Cmainframe的头文件中,添加2个MySplitter的变量(因为下面要进行两次切分操作m_wndSplitter,m_wndSplitter2)。6.重写框架类CMainframe的OnCreateClient函数,如下:/第一次静态切分CreateStatic,一行两列if(!m_wndSplitter.CreateStatic(this,1,2)returnFALSE;,/第二次静态切分(将第一次切分后的第二列再分为2*2)及所有的子视图创建(CreateView函数)。if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CControlForm),CSize(100,100),pContext)|!m_wndSplitter2.CreateStatic(/注释掉原有的响应函数注意:记得在Mainfrm.h中添加以上五个视图类的头文件:#includeControlForm.h#includeTopLView.h#includeTopRView.h#includeBottomLView.h#includeBottomRView.h#include“MySplitter.h”将CMySplitter的构造函数与析构函数改为public属性,第四章:简单绘图绘制线条,要求:单击鼠标左键并按住拖动后,释放鼠标左键,完成线条的绘图。1.新建单文档类型程序,名为Draw,添加鼠标左键按下及释放的消息响应函数;2.为CDrawView类添加Cpoint类型成员变量m_ptOrigin;,使用SDK全局函数绘制线条:,GetDc可以在任意位置绘图,前提是得到任意绘图区域的句柄,必须记住释放资源,利用MFC的CDC类绘图,默认获得的是当前上下文环境下的设备句柄,此处获得的是CDrawView对象的指针句柄,利用MFC的CClientDC类绘图,CClientDC类的构造函数会调用GetDC,析构函数会调用ReleaseDC,因此不需要显式的释放资源;,当将this更改为GetParent()函数时,则可以在窗口的整个区域绘图包括菜单栏、工具栏,非客户区域;因为CDrawView是由CMainFrame对象生成的,因此此处获得的即为整个程序的框架窗口设备句柄;,利用MFC的CWindowDC类绘图,获得了桌面窗口的句柄,故可以实现在整个桌面绘图;,第五章:菜单操作,GetMenu获得菜单项,GetSubMenu获得菜单项的子菜单,checkMenuItem设置/删除菜单项的复选标志,设置默认菜单项,将会以粗体方式显示,加载图标菜单项,获得默认的菜单项所能加载的位图的尺寸,并已消息框方式显示出来,此处为13*13,在位图资源编辑器中编辑位图,使之大小为13*13,也可以采用其他工具调整位图大小;,移除和加载菜单项,Cmenu为局部对象,可能导致异常,要么将menu对象更改为CMainFrame的成员变量,要么增加一条语句:menu.Detach();,创建快捷菜单(右键菜单)1.在资源选项的Menu文件夹下右键单击,选择InsertMenu命名为IDR_POPUP_MENU在里面填一些菜单项;2.选中视图类,在属性中选择消息:WM_CONTEXTMENU,添加函数函数;voidCMyDrawView:OnContextMenu(CWnd*pWnd,CPointpoint)/TODO:在此处添加消息处理程序代码CMenum_menu;m_menu.LoadMenuW(IDR_POPUP_MENU);CMenu*popupmenu=m_menu.GetSubMenu(0);popupmenu-TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,pWnd,0);,第六章对话框,对话框的作用:主要功能是用于接收用户的输入数据;还可用来显示提示信息(如程序启动时显示版权和运行进度信息)。在MFC中,对话框的功能被封装在CDialog类中,而CDialog类是CWnd类的派生类。作为窗口,对话框和其它窗口一样具有窗口的一切功能。对话框的典型应用:通过菜单命令或工具栏按钮打开一个对话框;对话框也可以作为一个程序的主界面。,对话框:是Windows应用程序中一种常用的资源,其主要功能是输出信息和接收用户的输入数据。控件:是嵌入在对话框中或其它父窗口中的一个特殊的小窗口,它用于完成不同的输入、输出功能。,基于对话框的应用程序,可以直接利用MFCAppWizard向导创建一个基于对话框的应用程序,这种程序运行后首先出现一个对话框。在向导的第一步选择DialogBased项。因为对话框应用程序一般不包含文档,故不支持数据库和复合文档。按照对话框应用程序向导提示的步骤进行操作就得到一个对话框应用程序项目,出现对话框编辑器和控件工具栏浮动窗口,它们采用的是一种所见即所得的可视化工作方式。利用向导创建应用程序的框架后,程序员可根据程序具体功能要求添加代码。当一个有模式对话框打开时,用户只能与该对话框进行交互,而其他用户界面对象收不到输入信息。平时所遇到的大部分对话框都是有模式对话框。无模式对话框则不然,该对话框并不阻止用户的输入。,对话框的初始化,OnInitDialog():该函数是由消息WM_INITDIALOG来激活的,但此消息比较特别,它不用添加到消息映射表中。该函数用来进行对话框的初始化,为使用对话框进行准备工作。该函数的原型为:virtualvoidOnInitDialog();而且CDialog类中提供了它的默认实现,即在CDialog的派生类中将根据需要决定是否重写该函数。,对话框的结束,在CDialog类中存在两个关键函数OnOK()和OnCancel(),这两个函数用于响应单击OK按钮(控件ID为IDOK)和Cancel按钮(控件ID为IDCANCEL)的消息,这些消息也不用添加到消息映射表里。两个函数都用于关闭对话框并返回对话框拥有者的窗口,但返回结果不同。OnOK()函数返回IDOK,并把对话框输入的数据结果提供给对话框的拥有者,而OnCancel()函数返回IDCANCEL,但并不把对话框输入的数据结果提供给对话框的拥有者。,有关对话框的常用处理函数CDialog:CDialog()通过调用派生类构造函数,根据对话框资源模板定义一个对话框。CDialog:DoModal()激活模态对话框,显示对话框窗口。CDialog:Create()根据对话框资源模板创建非模态对话框窗口。如果对话框不是Visible属性,还需通过调用CWnd:ShowWindow()函数显示非模态对话框窗口。,CDialog:OnOk()单击OK按钮时调用该函数,接收对话框输入数据,关闭对话框。CDialog:OnCancel()单击Cancel按钮或按Esc键时调用该函数,不接收对话框输入数据,关闭对话框。CDialog:OnInitDialog()WM_INITDIALOG消息处理函数,在调用DoModal或Create函数时系统发送WM_INITDIALOG消息,在显示对话框前调用该函数进行初始化。CDialog:EndDialog()用于关闭模态对话框窗口。,CWnd:ShowWindow()显示或隐藏对话框窗口CWnd:DestroyWindow()关闭并销毁非模态对话框CWnd:UpdateData()通过调用DoDataExchange()设置或获取对话框控件的数据CWnd:DoDataExchange()被UpdateData()调用以实现对话框数据交换,不能直接调用。,CWnd:GetWindowText()获取对话框窗口的标题CWnd:SetWindowText()修改对话框窗口的标题CWnd:GetDlgItemText()获取对话框中控件的文本内容CWnd:SetDlgItemText()设置对话框中控件的文本内容CWnd:GetDlgItem()获取控件或子窗口的指针CWnd:MoveWindow()用于移动对话框窗口CWnd:EnableWindow()使窗口处于禁用或可用状态,对话框数据交换DDX和验证DDV,在对话框中实现用户数据输入和输出的一般方法是通过ClassWizard类向导将对话框控件与成员变量相关联,利用对话框数据交换DDX(DialogDataExchange)和验证DDV(DialogDataValidation)机制实现数据的输入和输出。DDX是将成员变量与对话框控件相连接,完成数据在成员变量与控件之间的交换。DDV用于数据的校验,它能自动校验输入的数据是否符合设计要求。对话框数据交换与验证都是通过DoDataExchange()完成。,当利用ClassWizard类向导添加成员变量时,用户如果在窗口的左下角输入数据的范围,ClassWizard将自动加入函数DDV的调用代码。例如,当添加一个UINT型的成员变量m_nInput时指定它的最小值和最大值分别为0和100,则ClassWizard类向导将在成员函数DoDataExchange()中添加以下DDV函数的调用语句:DDV_MinMaxUInt(pDX,m_nInput,0,100);程序运行后,如果用户的输入数据超出0100的范围,DDV将显示一个提示信息对话框,提示用户有效的输入范围。,UpdateData()的用法,当调用UpdateData(TRUE)时,MFC通过调用DDX函数将数据从控件传递到关联的成员变量;当调用UpdateData(FALSE)时,MFC通过调用DDX函数将数据从成员变量传递到关联的的控件。利用UpdateData()函数实现了在刷新后重新获取成员变量。,对话框中的成员变量,UpdateData(TRUE),UpdateData(FALSE),初始化成员变量,更新后重新获取成员变量,注意当程序调用CDialog:DoModal()创建并显示对话框时,将自动调用CDialog:OnInitDialog()完成初始化的工作。在函数OnInitDialog()中,程序会自动调用UpdateData(FALSE),将数据从成员变量传递到关联的控件,从而显示在控件中。单击OK按钮将调用CDialog:OnOk()函数,在OnOK()中程序会自动调用UpdateData(TRUE),将数据从控件传递到关联的成员变量。DDX就如同一条双向通道,而方向控制开关就是UpdateData()函数中的BOOL类型参数是TRUE还是FALSE。,提示信息对话框,提示信息对话框也称消息对话框,用来显示有关的提示信息。提示信息对话框是一种最简单的对话框,不需要用户自己创建它就可以直接使用,VisualC+提供了相应的函数实现这样的功能。,MFC全局函数:intAfxMessageBox(LPCTSTRlpText,UINTnType=MB_OK,UINTnlDHelp=0);API函数:intMessageBox(HWNDhWnd,LPCTSTRlpText,LPCTSTRlpCaption,UINTnType);CWnd类的成员函数:intCWnd:MessageBox(LPCTSTRlpText,LPCTSTRlpCaption=N
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 注册会计师考试2025年资产评估中的法律问题分析试题及答案
- 证券从业资格证的考试资料试题及答案
- 证券从业资格的细致复习试题及答案
- 项目管理考试在线学习方式试题及答案
- 理解商品市场与金融市场的关系试题及答案
- 如何有效防止实验室交叉污染试题及答案
- 微生物实验中使用的实验动物类型试题及答案
- 如何制定2024年行政管理师考试的复习计划试题及答案
- 微生物检验技师实操能力考察试题及答案
- 深入探讨行业变化的证券从业资格证试题及答案
- 医学伦理学人卫试题(附参考答案)
- 2024诗词大会100题题库(含答案)
- 超市专用棚架搭建方案
- 安全隐患排查和治理制度
- 【初中物理】凸透镜成像规律+-2024-2025学年人教版物理八年级上册
- 2024年应急预案知识考试题库及答案(共60题)
- 二年级下册数学口算综合练习题 (每页100题)
- 安全生产法律法规知识培训课件
- 湖北公务员面试模拟64
- 信息安全意识培训课件
- 人教版数学八年级上册:14-整式的乘法与因式分解-专题练习(附答案)
评论
0/150
提交评论