单程序结构课件.ppt
1,基于MFC进行应用开发,使用VC+的应用程序向导MFC AppWizard可以开发:单文档Single document 多文档Multiple document对话框Dialog based三种类型的应用程序。,本讲开始学习单文档应用程序的开发技术,2,单文档应用案例1的程序运行界面,3,本讲主要内容,利用向导建立一个单文档应用程序框架 向导生成的核心类及其功能 文档/视图 文字的显示 菜单,4,单文档案例1文本显示案例,利用MFC建立一个单文档应用程序,用于在客户区显示文本。程序的主要功能包括:使用菜单命令按照指定文本内容和坐标位置在客户区显示文本保存文本内容等。,5,利用向导建立一个单文档应用程序框架,【例9-1】利用MFC AppWizardexe向导生成一个SDI单文档应用程序MyTextOut。,6,【编程步骤】 (1)在Visual C+ IDE中执行File|New命令,打开New对话框。在项目类型列表框中选择MFC AppWizardexe项,在Project name框中输入项目名称,本例为MyTextOut。选择好合适的路径。(2)在MFC AppWizard-Step 1对话框中选择Single document项,向导将会创建一个单文档应用程序框架,在本例中,以下的各个步骤使用向导提供的默认选项即可。,利用向导建立一个单文档应用程序框架,7,利用向导建立一个单文档应用程序框架,编译、连接、运行MFC AppWizardexe向导创建的应用程序MyTextOut。运行结果如图所示。,框架(菜单栏、工具栏、状态栏),客户区,单文档程序要包含文档,并且一次只能打开一个文档,其框架是指菜单栏、工具栏、状态栏等界面元素,客户区则用于展示用户文档。,8,向导生成的核心类及其功能,MFC应用程序框架实质上是一个标准的Windows应用程序,它具有标准的窗口、菜单栏和工具栏。MFC AppWizardexe向导为一般的SDI应用程序生成了五个核心类,它们分别是:应用程序类CMyTextOutApp框架窗口类CMainFrame文档类CMyTextOutDoc视图类CMyTextOutView文档模板类CSingleDocTemplate,9,向导生成的核心类及其功能,一般应用程序框架中所有类的名字由MFC AppWizardexe向导根据一定的规则自动命名。应用程序框架中类(框架窗口类例外)的命名规则一般遵照如下要求:Class Name = C + ProjectName + ClassType,10,向导生成的核心类及其功能,1应用程序类CMyTextOutAppCMyTextOutApp类是MFC的CWinApp类的派生类。它的主要功能有:应用程序的初始化;程序的启动;程序运行结束时的清理工作。应用程序对象theApp是一个唯一的全局变量,它的主要功能是通过调用WinMain()主函数启动程序的运行。MFC应用程序框架也有一个作为程序入口点的WinMain()主函数,但在源程序中看不见该函数,它在MFC中已定义好并同应用程序相链接。,11,向导生成的核心类及其功能,2框架窗口类CMainFrameCMainFrame类是MFC的CFrameWnd类的派生类。它主要负责创建标题栏、菜单栏、工具栏和状态栏。不同的SDI应用程序,其框架窗口类名和文件名是统一的。CMainFrame类中声明了框架窗口中的工具栏m_wndToolBar、状态栏m_wndStatusBar两个成员变量和四个成员函数。,12,向导生成的核心类及其功能,3文档类CMyTextOutDoc类CMyTextOutDoc是MFC的CDocument类的派生类,它用于管理和维护数据,包括应用程序数据的保存和装载,实现文档的序列化功能。4视图类CMyTextOutView类CMyTextOutView是MFC的CView类的派生类,它主要负责客户区文档数据的显示,以及如何进行人机交互。,13,向导生成的核心类及其功能,5文档模板类CSingleDocTemplate文档、视图、框架类和所涉及的资源形成了一种固定的联系,这种固定的联系就称为文档模板。文档模板类CSingleDocTemplate是MFC的CDocTemplate类的派生类CSingleDocTemplate文档模板类在应用程序中有着非常重要的作用,是它将原本独立的文档、视图和框架窗口对象联系在一起。,14,文档/视图,为了统一和简化数据处理,基于MFC的应用程序通常采用文档/视图结构。在MFC文档/视图结构中,有关数据处理的工作可以分为数据的处理和数据的显示两个部分。文档负责数据的处理、数据的维护以及数据的存储,视图则负责数据的显示和数据的编辑,客户区消息的响应和处理等工作,即充当了文档与用户之间的交互界面。,15,文档/视图,文档(document)是MFC应用程序中所处理数据的集合,包括文本、图形、图像和表格等类型。视图(view)是文档在应用程序窗口中的一个映像。视图就如一个观景器,用户通过视图看到文档,通过视图修改文档。一个视图是一个没有边框的窗口,它位于主框架窗口中的客户区。视图是文档对外显示的窗口,但它并不能完全独立,它必须依存在一个框架窗口内。,16,文档/视图,当打开某种类型的文件时,应用程序必须确定哪一种文档模板用于解释这种文件。在初始化程序时,必须首先注册文档模板,以便程序利用这个模板来完成主框架窗口、视图、文档对象的创建和资源的装入。 BOOL CMyTextOutApp:InitInstance() CSingleDocTemplate* pDocTemplate; /声明文档模板指针pDocTemplate = new CSingleDocTemplate( /创建文档模板对象IDR_MAINFRAME, /文档模板使用的资源IDRUNTIME_CLASS(CMyTextOutDoc), /创建文档对象RUNTIME_CLASS(CMainFrame), / 创建主SDI框架窗口对象RUNTIME_CLASS(CMyTextOutView); /创建视图对象AddDocTemplate(pDocTemplate); /将文档模板加入链表 ,17,表9-1 MFC应用程序对象之间的相互访问方法,18,文字的显示,【例9-2】以例9-1的单文档应用程序MyTextOut为基础,添加代码实现文本输出。程序运行后在视图窗口显示文本串“这是我的第一个单文档应用程序!”。,19,文字的显示,【编程步骤】(1)本例需要在视图类的成员函数OnDraw()中添加显示文本的代码来实现屏幕输出。在例9-1生成的框架代码基础上,打开Workspace窗口单击ClassView标签,找到CMyTextOutView类,点击其左边的“+”展开该类,双击其成员函数OnDraw(),在编辑窗口出现该成员函数代码,在指定位置手工添加如下粗体所示代码。,20,文字的显示,void CMyTextOutView:OnDraw(CDC* pDC) CMyTextOutDoc* pDoc = GetDocument(); /获得文档类对象的指针 ASSERT_VALID(pDoc); /检查该指针是否为空 / TODO: add draw code for native data here /在视图内的设备坐标(150,100)位置输出文本 pDC-TextOut(150,100,“这是我的第一个单文档应用程序!);,TextOut()是CDC类的成员函数。其功能是在指定的位置输出文本串。函数原型如下:CDC: TextOut( int x, int y, const CString& str )其中参数x,y指定文本输出位置坐标。 参数str指定输出内容。,MFC应用程序通常在视图类CView的成员函数OnDraw()中实现屏幕输出,因为在重画窗口时会自动调用函数OnDraw(),这样才能保证显示的内容在每次重画窗口时都能显示出来。,GetDocument()是视图类的成员函数,调用它可以返回与视图相关联的文档对象的指针,利用这个指针可以访问文档类及其派生类的公有成员。通常的用法如下:CMyTextOutDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);,ASSERT_VALID()是MFC库中的断言 。ASSERT_VALID()的用法是:ASSERT_VALID(一个从CObject类派生的对象指针)功能:用于对C+对象或指针进行有效性判断,如果出错,会弹出带断言信息(程序,模块, assertion行)的对话框。对话框有3个按钮:“Break”,“Repeat”(“Debug”), 和“Continue”(“Ignore”)。“Break”结束程序,“Continue”忽略断言,最有用的是“Repeat”按钮。按下它会在断言的地方打开源代码编辑器. 在这里可以测试所有的变量值并找出问题所在。,21,文字的显示,编译、连接、运行程序。运行结果如图。,22,设备环境DC,Windows应用程序通过为指定设备(屏幕,打印机等)创建一个设备环境(Device Context, DC),在DC表示的逻辑意义的“画布”上进行图形的绘制。DC是一种包含设备信息的数据结构,它包含了物理设备所需的各种状态信息。,23,DC实际上是一个关于如何绘制图形的方法的集合。它可以确立在应用窗口中绘制图形的方式,即确定绘图模式和映射模式。当应用程序需要在某个图形设备上绘图时,首先要获取绘图窗口区域的一个设备环境DC,之后才能选取合适的绘图工具进行绘图工作。为了便于绘图,Windows系统在初始化时为程序提供了一套默认的绘图属性和对象集合,所以程序在取得了合适的DC之后,就可以使用这些默认的绘图属性和对象进行绘图。例如,Windows缺省的DC包括了一支黑色的画笔,所绘制的线条都是黑色的。,设备环境DC,24,图形设备接口GDI,为了方便图形绘制,Windows把与绘图相关的操作都制作成函数,这些函数的集合称为图形设备接口(graphical device interface,GDI)。GDI提供了各种绘图函数,例如GDI中有绘制矩形的函数Rectangle()、绘制文本的函数DrawText()等。GDI还提供了一套绘图工具,如Pen(画笔)、Brush(画刷)、Font(字体)等。由于在Windows屏幕上看到的所有内容都是图形,所以在应用窗口中每次进行显示和编辑操作时,都必须调用特定的GDI函数。,25,CDC类,为了支持GDI绘图,MFC提供了两种重要的类:设备环境类(CDC类),用于设置绘图属性和绘制图形;绘图对象类,封装了各种GDI绘图对象,包括画笔、刷子、字体、位图、调色板和区域。MFC中,设备环境DC是由VC+的CDC类对象来表示的,可以调用CDC的很多成员函数来完成各种各样的绘图操作。,26,CPaintDC类,CPaintDC是所有CDC类中最常用的一个类,它代表了应用程序窗口的客户区,它只能使用于CView类的成员函数OnDraw中。MFC AppWizard应用程序向导创建的OnDraw()函数自动支持所获取的DC。OnDraw函数的声明为: OnDraw(CDC *pDC);这个函数的参数pDC就是指向CPaintDC类对象的指针,在OnDraw函数中可以使用CDC类的成员函数对这个对象进行绘图操作。,27,WM_PAINT消息,系统每次创建应用程序窗口或窗口需要刷新时都会产生WM_PAINT消息,系统接收到这个消息就会自动调用OnDraw函数,应用程序也可以使用相关函数来激活OnDraw函数,因此,程序中所有对窗口客户区进行绘图的代码都应该写在这个函数中。,28,GDI坐标系和映射模式,在Windows屏幕上绘图离不开坐标系。上面程序中使用的坐标系是MM_TEXT映射模式,MM_TEXT为GDI默认的映射模式。该模式下的原点为客户区左上角,向下、向右为正向。Windows映射模式就是在Windows方式下的屏幕坐标方式。一个实际的物理屏幕是由像素组成的。例如1024768分辨率就是指物理屏幕的实际宽度为1024个像素,高度为768个像素。,29,表 Windows的8种映射模式,30,菜单,【例9-3】改进例9-2的单文档应用程序MyTextOut,程序运行后使用菜单命令,调用对话框输入显示的文本内容和显示的坐标位置,按照输入的内容在视图区显示文本。,31,菜单建立菜单资源,【编程步骤】(1)建立菜单资源。在向导生成的程序框架中修改菜单资源,添加“文本|显示文本”菜单。在ResourceView中找到IDR_MAINFRAME资源,双击之,在显示出来的主菜单项最后的虚线空白框处双击,在弹出的properties对话框中填写Caption项为“文本(&T)”,可以看到主菜单最后一个菜单项即为“文本”,字符“&”用于在显示字母T时加下划线,表示该菜单命令的快捷键是“Alt+T”。并使用鼠标拖动该菜单项移至“帮助”菜单项左侧。注意,主菜单只有标题而没有相应的ID标识。,32,菜单建立菜单资源,33,菜单建立菜单资源,接着为主菜单添加菜单项。在“文本”菜单下面的虚线空白框处双击,在弹出的properties对话框中填写Caption项为“显示文本”,ID是该菜单项的标识,在此框中输入ID_TEXT_OUTPUT。在Prompt文本框中输入状态栏提示语“在视图区给定位置显示输入的文本内容”。,34,菜单建立菜单资源,35,菜单,(2)添加菜单命令处理函数。按下Ctrl+W键启动ClassWizard,在Class name下拉列表框中选择文档类CMyTextOutDoc,在Object IDs列表框中选择ID_TEXT_OUTPUT(“显示文本”菜单项的ID),在Messages列表框中选择COMMAND,单击Add Function按钮,为“显示文本”菜单项添加命令处理函数CMyTextOutDoc:OnTextOutput()。,36,菜单,(3)创建对话框资源。在ResourceView中找到Dialog资源,鼠标右击弹出快捷菜单,单击“Insert Dialog”,添加一个新对话框,修改其ID为 IDD_DLG_TEXT,Caption项为“请输入文本内容和显示位置”。参见图示。之后在对话框上放置相应的控件并布局。,37,菜单,(4)为对话框资源创建对应的对话框类。双击对话框资源,弹出为对话框增加类的对话框。设置对话框类名为CTextDialog,为该类自动生成两个文件TextDialog.h和TextDialog.cpp。,38,菜单,为三个编辑框控件添加成员变量m_strText、m_nText_X、m_nText_Y。如图所示。,39,菜单,(5)建立文本对话框与文档类的关联。下面在文档类CMyTextOutDoc中加入与上述控件变量对应的三个成员变量,即在MyTextOutDoc.h文件中加入:class CMyTextOutDoc : public CDocument protected: / create from serialization only CMyTextOutDoc(); DECLARE_DYNCREATE(CMyTextOutDoc) 手工添加的三个变量 int m_nText_X; int m_nText_Y; CString m_strText; ,40,菜单,(6)在CMyTextOutDoc.cpp文件中加入菜单命令响应函数OnTextOutput()的代码。void CMyTextOutDoc:OnTextOutput() / TODO: Add your command handler code here CTextDialog tdlg; /定义一个对话框对象 if(tdlg.DoModal()=IDOK) /显示对话框 /保存编辑框数据 将控件变量的数据保存到文档类成员变量中 m_nText_X=tdlg.m_nText_X; m_nText_Y=tdlg.m_nText_Y; m_strText=tdlg.m_strText; UpdateAllViews(NULL);接着需要在MyTextOutDoc.cpp文件中加入:#include TextDialog.h,将文本对话框的成员变量值赋给文档类的相应的成员变量m_strText, m_nTextX, m_nTextY,文档类已经获得了对话框控件上的数据,怎么将其显示在客户区呢?这时需要调用视图类CDrawView的方法OnDraw,该方法负责文档数据在客户区的显示。,更新与该文档有关的所有视图的方法是调用CDocument类的成员函数UpdateAllViews()。其原型为:void UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHint=NULL )UpdateAllViews通知该文档除了pSender之外的所有全部视图进行更新。其第一个参数pSender设为NULL,表示所有与当前文档相关的视图都要重绘。lHint是用于传送更新视图时,需要传送的额外信息参数;pHint是指向记录更新视图所需额外信息的控件。,