收藏 分享(赏)

vc++文档和视图.ppt

上传人:无敌 文档编号:1111015 上传时间:2018-06-12 格式:PPT 页数:43 大小:473.02KB
下载 相关 举报
vc++文档和视图.ppt_第1页
第1页 / 共43页
vc++文档和视图.ppt_第2页
第2页 / 共43页
vc++文档和视图.ppt_第3页
第3页 / 共43页
vc++文档和视图.ppt_第4页
第4页 / 共43页
vc++文档和视图.ppt_第5页
第5页 / 共43页
点击查看更多>>
资源描述

1、文档/视图结构的应用程序框架,2,本章内容,文档、视图、框架的关系简介文档/视图结构的应用程序框架SDI/MDI程序的文档/视图结构应用实例本章重点: 文档/视图结构框架的理解和应用,3,文档/视图结构框架的提出,简单应用程序框架中最主要的问题是CFrameWnd类要完成的任务太多、太杂。文档/视图结构的主要思想就是明确划分CFrameWnd的工作,将这些工作按照分工交给不同的类去处理。文档/视图结构中的CFrameWnd类的主要作用是提供应用程序的框架,不再针对具体问题做处理。文档/视图结构引入了三个新的类:CDocument类:包含应用程序的数据及其处理方法CView类:分担了CFrame

2、Wnd的显示操作并显示文档的数据CDocTemplate类:是文档/视图结构的维护类,负责建立并维护框架窗口、文档和视图 因此,文档/视图结构中应用程序的主要框架部分至少包括5个类的对象。,4,一、文档、视图和框架的关系,文档和视图是相互交互的;视图通过GetDocument函数获得指向关联文档的指针,从文档读取数据后进行显示,并将与用户交互后的结果送回文档处理。框架由文档模板类创建,能够为视图类和应用程序提供显示的窗口。文档、视图和框架三者相互关联、相互协调,彼此都包含了指向对方的指针。,5,文档/视图结构的优点和使用,特征:数据操作与数据显示分离,数据操作和数据显示分别按标准方法封装于两个

3、不同的对象。使得程序的更加清晰,更易于维护。MFC类对公共的文档/视图活动提供了大量的函数,由类库框架来管理,方便用户使用。打印预览功能,可以方便实现“所见即所得”的打印效果。 总之,文档/视图结构能够很好的解决数据处理与数据显示的协调问题,但也不是适用于所有的场合,例如:移植早期的Windows应用程序。所以,要根据具体情况选择合适的应用程序结构。,6,二、文档/视图结构,在文档/视图结构中,7,文档/视图结构的工作机制,视图通过GetDocument成员函数获得指向相关联的文档对象的指针,通过该指针调用文档类的成员函数来从文档中读取数据,视图把数据显示于计算机屏幕上,用户通过与视图的交互来

4、查看数据并对数据进行修改,视图通过相关联的文档类的成员函数将经过修改的数据传递给文档对象,文档对象获得修改过的数据之后,对其进行必要的修改,最后保存到永久介质(如磁盘文件)中,8,三、文档和视图,16.3.1 文档类,9,10,16.3.2 CDocument类的派生类构造方法,1. 构造CDocument类的派生类的基本步骤:,一般来说,从CDocument类派生自己的文档类所需的典型步骤为为每一个文档类型从CDocument类(当然也可以是其它CDocument类的派生类)派生一个相应的文档类。为文档类添加成员变量。这些成员变量用来保存文档的数据,其它对象(如与文档相关联的视图)直接或间接

5、的访问这些成员变量来读取或更新文档的数据。重载Serialize成员函数,实现文档数据的串行化。,11,16.3.3 文档类的数据成员,常用成员函数,1当用户选择“文件”菜单中的“新建”命令时,将调用的成员函数OnNewDocument, BOOL CMySdiDoc:OnNewDocument() if (!CDocument:OnNewDocument() return FALSE;return TRUE; ,2 在不删除文档对象的情况下清除文档中的数据的函数DeleteContents,void CMyDoc:DeleteContents(),12,5 只要用户关闭一个文档,就会调用On

6、CloseDocument函数,默认操作是调用DeleteContents,void CMySdiDoc:OnCloseDocument() CDocument:OnCloseDocument();,6 要实现文档数据的串行化,需要在文档中重载成员函数Serialize:void CMySdiDoc:Serialize(CArchive& ar)if (ar.IsStoring()/ TODO: add storing code here /保存文档内容else/ TODO: add loading code here /读取文档内容 ,13,16.3.4 视图类,14,16.3.5 CVie

7、w类的派生类介绍,15,16.3.6 文档与视图结构的交互,1CView:GetDocument 一个视图对象有且只有一个与文档相关联的对象。GetDocument函数使得应用程序从一个视图得到它所对应的文档;GetDocument提供了用来访问文档类的成员函数的指针。,2 CDocument:UpdateAllViews当文档数据发生改变时,通知所有的视图更新所显示的数据。,4 Cview:OnInitialUpdate用户选择File菜单的New或者Open时,调用该函数完成视图类的初始化工作。,常用成员函数,3 CView:OnUpdate由应用程序框架调用来作为对应用程序调用Updat

8、eAllView函数的响应。,16,16.3.7 文档模板类 CDocTemplate,CDocTemplate类的基本函数说明,17,16.3.8 文档模板CDocTemplate类的函数使用说明,在VC中,文档类、与文档类相关联的视图类以及为视图类提供显示的框架窗口都是由文档模板创建的。每一种文档类型都有一种文档模板与之相对应,文档模板负责创建和管理该文档类型的所有文档,CDocTemplate(UINT nIDResource, / 和文档类型一同使用的各种资源的资源标识符 CRuntimeClass* pDocClass,/ 指向派生文档类的CRuntimeClass对象的指针 CRu

9、ntimeClass* pFrameClass, / 指向派生框架类的CRuntimeClass对象的指针 CRuntimeClass* pViewClass); / 指向CView派生视类的CRuntimeClass对象的指针,文档、框架窗口和视图的创建过程之间的先后顺序为: 创建文档 创建框架窗口 创建视图,文档、视图和框架三者之间是相互关联、相互协调的,彼此都包含了指向对方的指针。它们之间的联系是通过文档模板的构造函数来实现的。文档模板的构造函数的原型如下:,18,在应用程序的InitInstance()函数中,通过使用文档模板的构造函数创建文档模板的对象如下:BOOL CMymdiAp

10、p:InitInstance() CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMySdiDoc), /SDI派生文档类的CRuntimeClass对象的指针 RUNTIME_CLASS(CMainFrame), /SDI派生子框架类的CRuntimeClass对象的指针 RUNTIME_CLASS(CMySdiView);/SDI派生视图类的CRuntimeClass对象的指针 /然后,使用CwinApp:AddDocTemplate(

11、)方法将新模板添加到应用程序的文档模板列表中 AddDocTemplate(pDocTemplate); ,19,四、文档/视图应用程序,一、单文档界面与多文档界面,20,由于每一个文档可以有多个视图,但每个视图只能对应于一个确定的文档,多文档程序需要解决的问题仅仅是多个文档的数据管理方法的问题,多文档程序,最初的文档模板只支持主窗口,但每次打开一个新文档时都调用CDocument的函数OnNewDocument,建立一个由CMDIChildWnd派生的新的MDI子窗口,这些窗口中保存着各种已打开的文档,所有的细节都由MFC库处理,视图是文档的不同表现形式比如,一个*.html语言的文件,在浏

12、览器里和在记事本中打开的表现形式是不同的但它们操作的是同一个文件这就是一个文档对应两视图,21,二、编写单文档应用程序,例1:创建一个应用程序,其运行界面如下图所示。在应用程序的主窗口中客户区用RGB(128,128,128)色绘制一椭圆,并显示一文本“My first DOC/VIEW program!”,开始出现在窗口的左上角。 在客户区任意位置单击鼠标左键,则文本从鼠标点击处开始重新显示,通过这个这种方式可以改变主窗口中的显示文本的位置。,22,应用程序的编程部分,1. 应用程序框架设计,(1)在MFC AppWizard-Step 1 - 选择Single Document - 其余接

13、受默认选择,23,2. 为C*Doc类添加成员变量,手动地将成员变量添加到Doc类和View类中。如下面的步骤所示: 在Workspace窗口中的ClassView选项卡中双击C*Doc类,VC+将在代码编辑窗口中打开该文档类的定义。在C*Doc的定义中,找到下面的程序代码段:/ Attributespublic:在此之后手工地输入int m_MouseX;int m_MouseY;注:在类C*Doc的定义中包括多个public块。事实上,可以把这些定义都放到同一个public块中,在定义中包括多个public块只是为了区别开不同用途的公有成员。,24,3. 为C*View类添加成员变量,用同

14、样的方法在C*View类中添加成员变量如下: int m_ViewMouseX; int m_ViewMouseY;,4. 为C*View类添加消息映射,在C*View类中添加WM_LBUTTONDOWN的消息映射,方法如下: 用ClassWizard,为C*View类添加WM_LBUTTONDOWN的消息处理函数,并加入以下代码:,25,void C*View:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultInvalidate();

15、/使视图无效,应用程序自动调用OnDraw函数m_ViewMouseX=point.x;m_ViewMouseY=point.y; /将当前鼠标的值赋给变量C*Doc *pDoc=GetDocument(); /获得当前的文档指针pDoc-m_MouseX=m_ViewMouseX;pDoc-m_MouseY=m_ViewMouseY; /将鼠标值赋给文档变量pDoc-SetModifiedFlag(true); /设置修改标志为TRUECView:OnLButtonDown(nFlags, point);,添加的OnLButtonDown函数代码:,注意此处的C*Doc指相应的Doc类,视具

16、体的工程名称而定,26,void C*View:OnDraw(CDC* pDC)C*Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herepDC-SaveDC(); /保存原来的设备表CRect rc;GetClientRect( /绘制椭圆,5为OnDraw函数添加代码:,27,CFont fnt; /定义字体对象fnt.CreateFont(50,0,0,0,FW_BOLD,true,false,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP

17、_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,Arial);CSize size;CString sText=My first DOC/VIEW program!;pDC-SelectObject( /恢复原来的设备描述表,28,6. 现在运行程序,查看结果会发现:输出文本在程序开始运行时并不直接出现在客户区。,void C*Doc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;/ TODO: add reinitialization code here/ (S

18、DI documents will reuse this document)m_MouseX=0;m_MouseY=0;return TRUE;,如果要实现程序开始运行时就出现文本,需要为C*Doc类的OnNewDocument函数添加鼠标位置初始化代码。,29,例2:编写单文档应用程序,创建一个应用程序,其工程名称为“ MySdi”。在应用程序的主窗口中显示一文本“ 您好, 单文档界面的例程!”,并始终出现在窗口的中央。 “ 编辑” 菜单上有一个菜单项“ 改变显示文本”,单击该项可以弹出一个对话框,通过这个对话框可以改变主窗口中的显示文本。,30,输入应用程序的代码,1. 创建工程,31,3

19、. 为CMysdiDoc类添加成员变量,手动地将成员变量添加到类CMysdiDoc的定义中。如下面的步骤所示:在Workspace窗口中的FileView选项卡中展开Mysdi files|Header Files,双击MysdiDoc.h,VC+将在代码编辑窗口中打开文件MysdiDoc.h,这个文件包括了Mysdi应用程序中的文档类CMysdiDoc的定义。在CMysdiDoc的定义中,找到下面的程序代码段/ Attributespublic:在此之后手工地输入以下内容CString m_str;,32,4文档变量初始化,为了测试该程序,在CMysdiDoc的OnNewDocument成员

20、变量中为公有成员m_str赋以初值 “ 您好, 单文档界面的例程!”。方法是在OnNewDocument的函数实现代码中添加斜体部分的代码内容BOOL CMymdiDoc2:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;m_str=您好, 单文档界面的例程!;return TRUE;,33,5视图的输出,下面我们将为Mysdi程序的视图类CMysdiView类的OnDraw成员函数添加一些代码,用于将文档类中的m_str成员变量的内容显示到视图的框架窗口中。这里我们用下面的代码来替换类CMysdiView的OnDraw成员函

21、数void CMysdiView:OnDraw(CDC* pDC)CMysdiDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereCRect rectClient;GetClientRect(rectClient);/ 获取当前客户区的指针CSize sizeClient=rectClient.Size();/ 获取当前客户区的大小CString str=pDoc-m_str;/ 从文件中读取数据CSize sizeTextExtent=pDC-GetTextExtent(

22、str); / 用新选定的字体绘制字符串pDC-TextOut(sizeClient.cx-sizeTextExtent.cx)/2,(sizeClient.cy-sizeTextExtent.cy)/2,str);,34,6文档串行化,先在 “ 编辑” 菜单中添加一条改变文档内容的菜单,用户可以将对文档显示文本所做的修改保存到一个磁盘文件中,具体的实现方法如下:,(1)单击Workspace窗口 - ResourceView选项卡 - 展开Mysdi resources|Menu - 双击IDR_MAINFRAME - 为 “编辑” 菜单添加一个菜单项 “改变显示文本” - 设置ID为ID_

23、EDIT_CHANGETEXT,(2) 为示例程序添加如图16-7所示的对话框。然后使用ClassWizard为对话框生成CDialog类的派生类CInputDlg,并为其中的Edit Box控件(其ID为IDC_EDIT1)添加相关联的成员变量m_input,其类型为CString。,(3)在类CMysdiDoc中为菜单项 “编辑|改变显示文本” (ID为ID_EDIT_CHANGETEXT)添加处理函数OnEditChangeTextvoid CMysdiDoc:OnEditChangetext() CInputDlg inputDlg;/建立一个CinputDlg类的对象inputDlg

24、 if( inputDlg.DoModal()=IDOK )/使inputDlg成为一个模式对话框 m_str = inputDlg.m_input; /获取输入的字符串UpdateAllViews(NULL); /更新视图 ,35,7对话框和Serialize函数,为使CInputDlg类在CMysdiDoc类中成为可识别的,必须在mysdiDoc.cpp文件中加入CInputDlg类的说明头文件InputDlg.h #include InputDlg.h/加入头文件,为了把这些修改保存到磁盘文件中,并在需要时可以打开所保存的磁盘文件读取文档,我们重载CExampleDoc类的Seriali

25、ze函数来完成串行化。重载后的Serialize函数的代码如下:void CMysdiDoc:Serialize(CArchive /读取文档内容 ,36,三、 编写多文档应用程序,1应用程序的主窗口布局和功能,创建一个多文档的应用程序,程序运行后,可以打开若干个文档,如图所示.,37,2.应用程序的设计部分,(1) 创建工程利用AppWizard创建MDI类型工程。,38,39,void CMyMdiView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or c

26、all defaultInvalidate(); /使视图无效,应用程序自动调用OnDraw函数m_ViewMouseX=point.x;m_ViewMouseY=point.y; /将当前鼠标的值赋给变量CMyMdiDoc *pDoc=GetDocument(); /获得当前的文档指针pDoc-m_MouseX=m_ViewMouseX;pDoc-m_MouseY=m_ViewMouseY; /将鼠标值赋给文档变量pDoc-SetModifiedFlag(true); /设置修改标志为TRUECView:OnLButtonDown(nFlags, point);,添加的OnLButtonDo

27、wn函数代码:,40,void CMyMdiDoc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;/ TODO: add reinitialization code here/ (SDI documents will reuse this document)m_MouseX=0;m_MouseY=0;return TRUE;,(5)为CMyMdiDoc类的OnNewDocument函数添加鼠标位置初始化代码。,41,void CMyMdiView:OnDraw(CDC* pDC)CMyMdiDoc* pDoc = GetDo

28、cument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herepDC-SaveDC(); /保存原来的设备表CRect rc;GetClientRect( /绘制椭圆,(6)为OnDraw函数添加代码:,42,CFont fnt; /定义字体对象fnt.CreateFont(50,0,0,0,FW_BOLD,true,false,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,Ar

29、ial);CSize size;CString sText=My first DOC/VIEW program!;pDC-SelectObject( /恢复原来的设备描述表,43,小结,文档/视图结构的主要思路就是明确划分CFrameWnd的工作,并将这些工作按照分工分别交给不同的类去处理。文档视图结构引入了三个类:CView,CDocument和CDocTemplate类。文档/视图结构至少涉及5个类的对象:应用程序的主体是CWinApp派生类的对象。框架窗口是CFrameWnd的派生对象。“文档”指应用程序的数据结构是CDocument的派生对象“视图”是CView类的派生对象,分担了显示的工作。文档/视图的管家,CDocTemplate派生类的对象。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报