分享

Document/View架构

 灞河之滨 2018-08-02
在文档里编程,首先要搞清楚文档/视图架构的运行流程,如下:

 

Document

  DocumentMFCCDocument里面被实例化. CDocument本身并无实际用途,它只提供一个空壳.当我们开发自己的程序时,应该从CDocument派生一个属于自己的Document类,并且在类中声明一些成员变量,用以承载(容纳)数据.然后再(至少)改写专门负责文件读写操作的Serialize函数.事实上,AppWizard为我们把空壳都准备好,

 由于CDocument派生自CObject,所以它就有CObject所支持的一切性质,包括RTTI,Dynamic Creation,Serialization.又由于它也派生CCmdTarget,所以它可以接受来自菜单或工具栏的WM_COMMAND消息。

 

View

 View负责描述(呈现)Document中的数据。

 ViewMFCCView中被实例化。CView只提供一个空壳,在开发过程中,应该从CView派生一个属于自己的View类,且在类中(至少)改写专门负责显示数据的OnDraw()函数(针对屏幕)或OnPaint()函数(针对打印机)。其实AppWizard为我们把空壳都准备好了。

 由于CView派生自CWnd,所以它可以接受一般的Windows消息(如WM_SIZE,WM_PAINT等等),又由于它也派生自CCmdTarget,因此它也可以接受菜单或工具栏的WM_COMMAND消息。

 传统C/SDK程序中,当窗口函数收到WM_APINT时,就调用BeginPaint,获得一个Device Context(DC),然后在这个DC上作画。这个DC代表屏幕装置。在MFC里面,一旦WM_PAINT发生,Framework会自动调用OnDraw函数。

 View事实上是个没有边框的窗口。真正出现时,其外围还有一个有边框的窗口,我们称之为Frame窗口。

 

Document Frame(View Frame)

 若我们的程序管理两种不同类型的数据,比如说一个是TEXT,一个是BITMAP,作为程序设计者要为使用者多考虑一些:使用者可能在操作TEXT数据时,换一套TEXT专用的使用界面,在使用者操作BITMAP数据时,也换一套BITMAP界面。这份工作是由Frame窗口负责。

 为什么UI的管理不由View直接负责,却要交给Frame窗口。将UI管理机能隔离出来,可以降低彼此之间的依存性,也可以是机能重复使用于各种场合,如SDI,MDI,OLE,In-Place editing(即地编辑)之中。如此一来,View的弹性也会大一些。

 

Document Template

 MFCDocument/View/Frame视为三位一体。每当使用者欲打开(或新增)一份文件,程序应该做出Document,View,Frame各一份。这个“三口组”成为一个运行单元,由所谓的Document Template掌管。MFC中有一个类CDocument负责此事。它又有两个派生类,分别CMultiDocTemplate 和CSingleDocTemplte.

 若我们的程序能够处理两种数据类型,必须制造两个Document Template出来,并使用AddDocTemplate函数将它们一一加入系统之中。这和程序是不是MDI并无关系。若程序支持多种数据类型,但却是个SDI,那只不过表示每次只能开启一份文件。

 CDocTemplate是个抽象类,定义一些用来处理Document/View/Frame三口组的基础函数。

 

 

CDocTemplate管理CDocument/CView/CFrameWnd

 Document Template管理“三口组“,CWinAPP又来管理Document Template.

 File/New         File/Open

                       

 CWinApp选择适当的Document Template

              CMyDoc

     构造Document对象

               CCwndFrame       CMyView

构造Frame窗口对象         构造View对象

            ↓               

产生Frame窗口 <———— 产生View窗口

      

读文件(若是File/Open)

       

将View窗口初始化

       

在View中显示资料

 注意:构造View对象和产生View窗口的关系。View窗口就是地地道道的Windows窗口,而为了对象管理,MFC把View窗口外包一个专门的C++类别,那就是CView。所以当然是先构造(Construct)一个View对象,再由其构造函数产生(Create)对应的View窗口。

 

解释CDocTemplate,CDocument,CView,CFrameWnd之间的关系:

# CWinApp拥有一个对象指针:CDocManager *m_pDocManager

# CDocManager拥有一个指针链表CPtrList m_templateList,用来维护一系列的Document Template.一个程序若支持两种文件类型,就应该有两份Document Templates,应用程序应该在CMyViewApp::InitInstance中以AddDocTemplate将这些Document Templates加入到由CDocManager所维护的链表中。

# CDocTemplate拥有三个成员变量,分别持有Document,View,Frame的CRuntimeClass指针,另有一个成员变量m_nIDResource,用来表示此Document显示时应该采用的UI对象。这四份数据应该在CMyWinApp::InitInstance函数构造CDocTemplate时指定,成为构造函数的参数。

# CDocument有一个成员变量CDocTemplate * m_pDocTemplate,回指Document Template;另有一个成员变量CPtrList m_viewList,表示它可以同时维护一系列的Views。

# CFrameWnd有一个成员变量CView * m_pViewActive,指向当前活动的View.

# CView有一个成员变量CDocumnet *m_pDocumnt,指向相关的Document.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多