`
isiqi
  • 浏览: 16482818 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

MFC-文档视图

阅读更多

MDI程序

MiniDraw只有一个About对话框,这回要把它变成一个MDI程序,借助于文档视图的威力,并不需要花很大的力气。

MDI4个类组成:

主框架类,由CMDIFrameWnd派生而来,表示程序的MDI父窗口。

子框架类,由CMDIChildWnd派生而来,表示程序的MDI子窗口。

视图类,由CView派生而来,表示一个文档视图,内嵌于子窗口。

文档类,由CDocument派生而来,表示一份“文档”,一份“文档”可以由多个视图表现。

现在创建这些类,全部通过新建头文件和源文件生成,下面它们的代码:

MainFrm.h

#ifndef LINZHENQUN_MAINFMR_H_

#define LINZHENQUN_MAINFMR_H_

class CMainFrm: public CMDIFrameWnd

{

DECLARE_DYNAMIC(CMainFrm)

public:

CMainFrm();

};

#endif //LINZHENQUN_MAINFMR_H_

MainFrm.cpp

#include<afxwin.h>

#include "MainFrm.h"

IMPLEMENT_DYNAMIC(CMainFrm, CMDIFrameWnd)

CMainFrm::CMainFrm()

{

}

DrawChildFrm.h

#ifndef LINZHENQUN_DRAWCHILDFRM_H_

#define LINZHENQUN_DRAWCHILDFRM_H_

class CDrawChildFrm: public CMDIChildWnd

{

DECLARE_DYNCREATE(CDrawChildFrm)

public:

CDrawChildFrm();

};

#endif //LINZHENQUN_DRAWCHILDFRM_H_

DrawChildFrm.cpp

#include <afxwin.h>

#include "DrawChildFrm.h"

IMPLEMENT_DYNCREATE(CDrawChildFrm, CMDIChildWnd)

CDrawChildFrm::CDrawChildFrm()

{

}

DrawView.h

#ifndef LINZHENQUN_DRAWVIEW_H_

#define LINZHENQUN_DRAWVIEW_H_

class CDrawView: public CView

{

DECLARE_DYNCREATE(CDrawView)

public:

CDrawView();

protected:

virtual void OnDraw(CDC* pDC);

};

#endif //LINZHENQUN_DRAWVIEW_H_

DrawView.cpp

#include <afxwin.h>

#include "DrawView.h"

IMPLEMENT_DYNCREATE(CDrawView, CView)

CDrawView::CDrawView()

{

}

void CDrawView::OnDraw( CDC* pDC )

{

}

DrawDoc.h

#ifndef LINZHENQUN_DRAWDOC_H_

#define LINZHENQUN_DRAWDOC_H_

class CDrawDoc: public CDocument

{

DECLARE_DYNCREATE(CDrawDoc)

public:

CDrawDoc();

};

#endif //LINZHENQUN_DRAWDOC_H_

DrawDoc.cpp

#include <afxwin.h>

#include "DrawDoc.h"

IMPLEMENT_DYNCREATE(CDrawDoc, CDocument)

CDrawDoc::CDrawDoc()

{

}

4个类全部只是空架,具体的事情已经由基类处理了,其中只有CDrawView覆盖OnDraw,因为它是一个抽象成员函数,所以不得不覆盖一下。

除了MainFrm类,其他三个类都声明了DYNCREATE宏,因而具备动态创建的能力。

接下来要在CDrawApp::InitInstance创建这些类实例,不过之前还得创建一些资源,比如菜单,资源字符串。

先为主窗口创建一个菜单,这是AFX强制要求的,否则有很多断言等着你,在Resource.rc里插入一个菜单,ID为:IDR_MAINFRAME,然后加几个菜单项,效果如下:

接着为程序和主窗口创建一个图标,这回用导入的方式,毕竟有那么多现成的图标,何必自己来动手呢,导入:

我们将导入的图标ID也命名为IDR_MAINFRAME,等会儿会说明原因。可执行文件的图标由ID值为1的图标决定,我们第一次导入的这个图标ID值即为1,打开resource.h看看就知道了,因此也成为了执行文件的图标。

接下来再为子窗口设置一个图标,用同样的方式,将ID命名为IDR_MFCMDITYPE

最后添加两个资源字符串,ID与上面相同,如下所示:

IDR_MAINFRAME用于指定主窗口的标题;IDR_MFCMDITYPE用于指定子窗口标题,打开对话框字符串等。

记住ID的命名只有两个IDR_MAINFRAMEIDR_MFCMDITYPE,分别对应于主窗口和子窗口。

加完资源,到CDrawApp::InitInstance写点代码,让主窗口显示出来:

BOOL CDrawApp::InitInstance()

{

//添加文档模板

CMultiDocTemplate *pTemplate = new CMultiDocTemplate(

IDR_MFCMDITYPE,

RUNTIME_CLASS(CDrawDoc),

RUNTIME_CLASS(CDrawChildFrm),

RUNTIME_CLASS(CDrawView)

);

AddDocTemplate(pTemplate);

//创建主窗口

CMainFrm* pMainFrm = new CMainFrm();

pMainFrm->LoadFrame(IDR_MAINFRAME);

m_pMainWnd = pMainFrm;

//默认新建一个文档子窗口

OnFileNew();

//显示主窗口

pMainFrm->ShowWindow(m_nCmdShow);

pMainFrm->UpdateWindow();

return TRUE;

}

第一件事情是创建一个文档模板,一个文档模板对应一种类型的“文档”,这些模板由一个管理器管理着,以后借助于RTTI来创建文档窗口。

第二件事情是创建主窗口,通过LoadFrame创建窗口,IDR_MAINFRAME在这里被用上了,LoadFrame不单会用这个ID来指定主窗口的菜单,还用这个ID来指定窗口图标和标题,这就是为什么在创建资源的时候要用一个相同的ID来命名几种资源。主窗口创建完后交由CWinApp的成员m_pMainWnd保管。

第三件事情是用OnFileNew创建一个子窗口,里面的代码仅仅调用m_pDocManager->OnFileNew(),而AFX会帮你把子窗口创建出来。

最后,显示并更新主窗口。

运行程序,效果如下:

我们纯手工打造了一个MDI程序,尽管上面已经说明了步骤,但仍然留给我们很多疑问,比如子窗口怎么创建出来的,文档与视图如何关联起来,这其中的奥妙就在文档视图的框架。

在分析文档视图的流程之前,可以从这里获得源代码。

文档模板

一个MDI程序有多个文档窗口,每一个文档窗口的内容可以不同,就像VS6一样,代码和资源分别为不同的文档窗口表示。

文档模板正是代表这样一种抽象,它由视图文档以及子框架类组件,RIIT在这里起了非常重要的作用,文档模板保存的是各个类的运行时结构,在必要的时候才利用运行时结构动态创建类实例。在我们的例子中,只有一种文档类型,所以只AddDocTemplate一次。

CWinApp有一个CDocManager类,专门用来管理文档模板,AddDocTemplate将一个文档模板加进CDocManager里面。

void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)

{

if (m_pDocManager == NULL)

m_pDocManager = new CDocManager;

m_pDocManager->AddDocTemplate(pTemplate);

}

模板管理器采用延迟创建的方法,这样做是很有道理的,因为有些程序并不使用文档视图框架,可能只是一个对话框,如果一开始就创建模板管理器,就造成不必要的浪费了。

新建过程

新建文档调用CWinApp::OnFileNew

void CWinApp::OnFileNew()

{

if (m_pDocManager != NULL)

m_pDocManager->OnFileNew();

}

m_pDocManager->OnFileNew取第一个模板类,如果存在多个模板类,则弹出一个对话框让用户选择。然后调用pTemplate->OpenDocumentFile(NULL)进行文档打开操作。

弹出对话框的行为个人觉得不是很好,并不是每一个程序都有这样的需求,或者说有些程序想要自己的选择方式。另外,这个选择对话框对于以后的本地化会成为一个问题。

真正的流程在CMultiDocTemplate::OpenDocumentFile,它创建了所有必须的类:

CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

BOOL bMakeVisible)

{

//创建文档类

CDocument* pDocument = CreateNewDocument();

//创建框架类

CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);

//文件名为空,表示是新建

if (lpszPathName == NULL)

{

// 设置一个默认的标题名

SetDefaultTitle(pDocument);

// 新建文档打开通过

pDocument->OnNewDocument();

// 文档计数,标题设置

m_nUntitledCount++;

}

else

{

//打开一个存在的文档

pDocument->OnOpenDocument(lpszPathName);

//文档的路径名

pDocument->SetPathName(lpszPathName);

}

//更新子框架

InitialUpdateFrame(pFrame, pDocument, bMakeVisible);

return pDocument;

}

它首先创建文档类和框架类,视图类会在框架类创建时连带被创建,等会儿看看视图类怎样与文档类关联起来。

接着分两种情况来处理,如果文件名为空,则进行新建操作,我们看到默认标题是这样表示出来的,Document后面跟随的12m_nUntitledCount决定。如果文件名不空,则进行打开操作,OnOpenDocument将有序列化行为,这是以后的主题了。

最后更新框架。

我们要重点看看视图类与文档如何关联:

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)

{

//指定创建视图所需要的信息,包括文档类

CCreateContext context;

border-right: medium none; padding-right: 0cm; border-top: medium none;

分享到:
评论

相关推荐

    MFC文档-视图-框架体系.rar_3S3_MFC_MFC 文档视图_MFC页面_页面MFC

    在这个名为"MFC文档-视图-框架体系.rar"的压缩包中,我们主要探讨的是MFC中的核心组件:文档(Document)、视图(View)和框架(Frame)体系。 1. **文档(Document)**:在MFC中,文档是数据的主要容器,它存储...

    MFC 单文档视图中进行多种视图的切换

    下面将详细解释如何在MFC的单文档视图中进行多种视图的切换。 首先,理解MFC中的视图(View)类:视图是与用户交互的窗口部件,它通常负责数据显示和用户输入处理。每个视图类都是CView类的派生类,每个类对应一种...

    MFC单文档视图

    MFC单文档视图(Single Document Interface, SDI)架构是一种常见的Windows应用程序设计模式,允许用户在一个文档窗口内处理单一的数据或内容。 在MFC中,SDI的主要组成部分包括:文档类(CDocument)、视图类...

    MFC 打开并显示文本文件的例子-文档视图模型

    在Microsoft Foundation Classes (MFC)库中,文档视图模型是一种设计模式,用于构建与用户界面交互的应用程序,特别是那些处理文件数据的应用。MFC框架是C++编程中用于简化Windows应用程序开发的一个强大的工具集。...

    MFC单文档多视图实例

    在这个"MFC单文档多视图实例"中,我们将深入探讨如何使用MFC来创建一个具有切分窗口、左侧列表视图以及右侧可变视图类型的应用程序。 首先,"单文档"(Single Document Interface, SDI)是指应用程序中只能打开一个...

    VC/MFC文档-视图-框架体系编程实例

    给出了关于VC/MFC文档-视图-框架体系的编程实例,详细介绍了VC/MFC文档编程,视图编程,窗口静态切分和动态切分,多文档和单文档程序设计,包含了(30个实例),资源的实例均从光盘中拷出来的,能够正常运行

    深入分析MFC文档视图结构

    "深入分析MFC文档视图结构" MFC文档视图结构是MFC的精髓,也是Observer模式的具体实现框架之一。它通过将数据和其表示分开,提供了很好的数据层次和表现层次的解耦。然而,在实际开发中,我们经常会遇到Document/...

    MFC单文档-双视图

    本主题主要聚焦于"MFC单文档-双视图"的概念,这涉及到使用MFC来创建一个支持单个文档但能显示多个不同视图的程序。 单文档接口(Single Document Interface, SDI)是一种常见的应用程序设计模式,它允许用户处理...

    mfc文档视图结构详解

    其中,文档/视图(Document/View)结构是MFC的核心设计模式,它为开发者提供了处理用户界面和数据模型之间交互的框架。这个结构将应用程序分为四个主要组件:文档模板、文档、视图和框架窗口,每部分都有其特定的...

    MFC文档视图结构详解.doc

    MFC 文档视图结构详解 MFC(Microsoft Foundation Classes)是一个强大的应用程序框架,它提供了一个通用的文档视图结构,帮助开发者快速构建基于文档的应用程序。在这个结构中,文档模板、文档、视图和框架窗口四...

    MFC单文档视图切割

    在本文中,我们将深入探讨"MFC单文档视图切割"这一主题,这是一项常见的软件开发技术,主要用于构建具有多个视图的用户界面。MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,用于简化Windows应用程序...

    MFC文档视图框架关系分析

    MFC文档视图架构提供了一种组织代码的方法,使得数据(文档)与用户界面(视图)分离,同时保持两者间的紧密协作。 **文档(Document)** 文档是应用程序中的数据容器,它存储用户的数据并处理数据的持久化。在MFC...

    深入理解MFC多文档/视图流程

    深入理解MFC(Microsoft Foundation Classes)的多文档/视图(Document/View)架构是开发Windows应用程序的关键之一。MFC提供了构建复杂用户界面的工具,包括单文档接口(SDI)和多文档接口(MDI)应用。本文将重点...

    MFC多文档多视图编程

    这是一个关于 MFC多文档多视图编程 的文档,有需要的朋友下载阅读。

    mfc单文档多视图

    MFC(Microsoft ...总的来说,"mfc单文档多视图"是一个学习MFC基础架构、文档视图模型以及如何在C++环境中实现用户界面的好例子。通过这个Demo,开发者可以深入理解MFC的工作原理,并将其应用到自己的项目中。

    MFC单文档多视图

    在Microsoft Foundation Classes (MFC)库中,"MFC单文档多视图"是一个重要的编程概念,主要用于构建用户界面。MFC是微软为Windows应用程序开发提供的一种C++类库,它封装了Windows API,使开发者可以更高效地编写...

    MFC单文档实现多视图

    4. **CFrameWnd**:框架窗口类,通常用于包含文档视图。在SDI中,它是主窗口类。 5. **CDocTemplate**:文档模板类,负责创建和管理文档、视图和框架窗口的关联。在多视图结构中,一个文档模板可以关联多个视图类。...

    MFC框架文档视图_源码.rar

    《深入解析MFC框架文档视图与源码》 MFC(Microsoft Foundation Classes)是微软提供的一种基于C++的类库,它为Windows应用程序开发提供了丰富的接口和工具。MFC框架文档视图(Document/View Architecture)是MFC...

    深入浅出MFC--侯捷 深入浅出MFC--侯捷 深入浅出MFC--侯捷

    3. **文档/视图架构(Document/View Architecture)**:MFC提倡的文档/视图架构将数据(Document)与显示数据的方式(View)分离,使得代码更易于维护和扩展。文档存储数据,视图负责数据的显示和交互,控制器...

    深入浅出MFC文档视图架构教程(天极网)

    深入浅出MFC文档视图架构教程是针对微软基础类库(Microsoft Foundation Classes,简称MFC)中的核心设计模式——文档视图架构进行详细解析的一个教程。MFC是微软为Windows应用程序开发提供的一套C++类库,它封装了...

Global site tag (gtag.js) - Google Analytics