zoukankan      html  css  js  c++  java
  • mfc文档视图结构

    文档视图结构中操作流程

    一基本架构

    一个程序可以看作是建立在对文档进行处理的基础上的,而程序可处理的文档类型有可能有多种,同时每种文档又可能同时被打开多个视图,若在MDI程序中存在多个文档模板,这会在启动程序时显示一个新建对话框,其中每个条目显示一个文档模板字符串中第三个子串。每个文档又可分为数据部分和表现部分。

    基于这种认识,MFC文档视图框架结构将各功能模块总结为对象,用相互关联的这些对象类来建立应用程序.

    ①文档类型管理

    CWinApp代表程序,它可处理多种类型的文档,这样,就必须有一个存储管理文档类型的内部成员,这个成员就是

    CDocManager * m_pDocManager

    CDocManager负责管理文档类型

    CDocManager内部用

    CPtrList m_templateList;(指针链表)

    记录文档类型

    ②文档类型实现

    CDocTemplate(文档模板)代表具体的文档类型

    一个程序所能处理的文档类型,对对应各自的文档模板

    这些模板对象的指针被记录在m_templateList,并且由m_pDocManager管理

    ③文档模板的实现

    对于某一种文档,其内部数据结构,及外部表现形式,及针对它的操作命令都相对固定,因此文档模板有三个构成部分,文档的数据,用CDoucument管理;文档的表现形式,CView表示;文档在窗口系统中的容器,及菜单,工具条等命令形式则由CFrameWnd管理。必要时,同一文档可能需要多种表达,即一个CDocument可能关联几个CView,但模板声明时,只考虑一个文档对应一个视图,即作为默认时的活动视图,可是重载CFramwWnd::OnCreateClient设置其他的视图,例如静态分割窗口。

    这些信息被记录在其三个成员中

    CRuntimeClass* m_pDocClass; // class for creating new documents

    CRuntimeClass* m_pFrameClass; // class for creating new frames

    CRuntimeClass* m_pViewClass; // class for creating new views

    一各文档模板,对应一种文件类型,而这一类型的文件则可以有很多,这些对应的文件将记录在

    CPtrList m_docList;

    另外,文档模板也包含了该文档类型所对应的资源,如菜单,标题,图标等等信息

    二 文档类型的建立

    程序执行之初,(InitInstance 中)将建立文档类型链表

    依次建立多个文档类型(CCMultiDocTemplate),再一一添加(AddDocTemplate)到CWinApp的文档类型列表m_templateList中这样就建立了一个文件类型表,文件的新建,打开都将首先查找这个文件类型链表,找出文档的类型,得到文档模板,由文档模板得到文档应有的数据结构、文档的图形表述,及操作等等。

    三 文档的新建

    ①界面 命令ID_FILE_NEW发出

    CWinApp::OnFileNew()处理

    交由CDocManager * m_pDocManager(文档类型管理)处理

    ②CDocuManager查看文件类型列表,如过程序支持多种类型文档,给出一个类型选择机会。

    若文档类型列表中只有一种文档类型,直接选用这种类型。

    ③找到文档模板后,将调用文档模板的OpenDocumentFile(..)成员,传入的参数为NULL,表示新建

    i . OpenDocumentFile首先将首先建立文档的数据部分:

    CDocument* pDocument = CreateNewDocument();

    这将按照m_pDocClass所记录的CDocument类建立其实际数据对象。

    数据对象建立后,将其添加到CPtrList m_docList中,记录下这一文档模板对应打开的所有实际文件。 同时,CDocument也有一个列表CPtrList m_viewList; 用于记录文档对象所对应的(CView)视图,视图 容许有多个(同样的数据,可能有需要不同的表达形式)。

    ii. 为数据建立其表现形式的容器,即框架窗口

    CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);

    根据文档模板记录的框架类m_pFrameClass建立框架对象。

    iii. 建立框架对象的同时,CView(数据的表现形式,数据图像)的类型m_pViewClass将作为参数传给框架对象

    CCreateContext context;

    context.m_pNewViewClass = m_pViewClass;

    然后框架对象建立其实际的窗口 if (!pFrame->LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame stylesNULL, &context))

    LoadFrame 中将调用Create生成窗口,

    框架窗口建立客户区时,将调用CreateView(pContext, AFX_IDW_PANE_FIRST)建立模板所制定的CView对象

    并建立窗体pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0), this, nID, pContext))

    在CView建立时,其OnCreate()中将自己添加到对应文档的视图列表中:

    pContext->m_pCurrentDoc->AddView(this);

    ④文档对象(一般将文档(文件)的数据部分成为文档对象,与前面提到的文档意义有区别),文档对象的表现部分(视图对象) 及视图对象在Windows系统中的窗口容器(框架对象)自此都建立好了,接下来,是各对象的初始化。

    i. pDocument->OnNewDocument()

    在OnNewDocument()中有用户实现相应数据的新建或初始。

    完成后,将m_nUntitledCount增1,这个数用来对新文档进行计数,好用来给新文件起缺省名(例如:未命名3.txt);

    (如果OpenDocumentFile(.)有参数(打开文件时),在这儿将调用的是pDocument->OnOpenDocument() 用文件中的数据初始数据对象,)

    ii. InitialUpdateFrame初始化框架

    InitialUpdateFrame中将激活一个CView对象(若无,则为其他子窗口)

    并且向所有子窗口发送SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

    WM_INITIALUPDATE是MFC自定义的消息,用于在此时实现相关初始化,

    在CView::OnInitialUpdate中可写入需要添加的初始操作。

    激活框架窗口或相应视图。

    其后,更新框架窗口标题

    ⑤自此,新建文档过程结束。

    在msdn中有几个比较直观的图,这里copy过来

    文档的创建顺序

    框架窗口的创建顺序

    视图的创建顺序

    四 文档的打开

    ①响应打开命令 ID_FILE_OPEN

    CWinApp::OnFileOpen()

    调用m_pDocManager->OnFileOpen();

    ②DoPromptFileName提供打开文件对话框,得到文件名

    ③调用AfxGetApp()->OpenDocumentFile(newName);

    (这与新建文件有所不同)

    这是应用程序类的一个虚函数,可以添加特定处理于此

    一般情况下,将接着调用CWinApp::OpenDocumentFile(newName);

    ④回到CDocManager

    m_pDocManager->OpenDocumentFile(lpszFileName);

    查找文档模板列表,找出文档应该采用的文档模板。

    调用各模板的MatchDocType 判断是否合适,或是否已经打开过了。

    pTemplate->MatchDocType(szPath, pOpenDocument)

    若文件已经被某模板打开过,激活相应框架,试图。

    若没打开,单有相符合模板,使用该文档模板打开文件

    pBestTemplate->OpenDocumentFile(szPath);

    若不是程序处理的文件类型,报错返回。

    ⑤用找到的最合适文档模板打开文件。

    CMultiDocTemplate::OpenDocumentFile

    ⑥ ....

    以下各步骤与新建文件③以后各步相同,只是传入参数不同

    建立文档对象后,初始化时,将调用CDocumet::OpenDocumentFile 而不是CDocumet::OnNewDocument();

    昨天晚上正好遇到一个问题,就是点击“打开”菜单弹出的打开对话框的文件类型过滤本来是在IDR_MAINFRAME的第四、五段,但是貌似只能添加一个文本过滤类型,于是我在文档窗口中接受ID_FILE_OPEN消息,在消息响应函数中自己做一个CFileDialog来弹出打开对话框,在其中可以自由滴处理过滤类型,然后调用AfxGetApp()->OpenDocumentFile(dlg.GetPathName())、、、

    顺便说下,在MDI中命令消息处理流程是:CView->CDocument->CChildFrame->CMainFrame->CWinApp,其他的不是派生于CWnd的对象就不会响应窗口消息。

    转自http://blog.chinaunix.net/uid-24323834-id-2213979.html

  • 相关阅读:
    作业 20181030-3互评Alpha版本
    Alpha阶段事后诸葛亮会议记录
    Alpha发布用户使用报告
    20181023-2 贡献分配
    作业 20181016-1 Alpha阶段贡献分配规则
    Scrum立会报告+燃尽图(十月三十日总第二十一次)
    OC中时间函数的使用
    OC中的集合详解
    面向对象的概念详解(转)
    集中类
  • 原文地址:https://www.cnblogs.com/zfluo/p/5131929.html
Copyright © 2011-2022 走看看