C++MFC编程笔记day05 文档类-单文档和多文档应用程序

简介:  文档类    1 相关类    CDocument类-父类是CCmdTarget类,所以,文档类也可以处理菜单等               命令消息。

 文档类

   1 相关类
   CDocument类-父类是CCmdTarget类,所以,文档类也可以处理菜单等
              命令消息。作用保存和管理数据。
   注意事项:如何解决断言错误
   2 在视图中显示文档中的数据
    2.1 CView::OnInitialUpdate
        作用初始化视图,在附加文档之后,显示之前,由框架调用。
    2.2 CView::GetDocument
        获取与视图相关的文档
    2.3 CFrameWnd::InitialUpdateFrame
        作用,初始化更新框架,可以引起CView::OnInitialUpdate
        函数的调用。
   3 创建过程
     3.1 在CFrameWnd::OnCreate()函数中,通过层层调用,调用
         CreateView()函数,在函数中,动态创建视图对象,并创建
         视图窗口。
     3.2 在CView::OnCreate()函数中,调用AddView()函数,在函数中,
         文档与视图相互保存对方地址。
     3.3 注意问题:
         一个文档可以对应多个视图(一个文档的数据可以被多个视图
         显示),一个视图只能对应一个文档。
如果有断言错误,要看出错行号,并查看Call Stack是否有默认的字符串表数据需要编写。
示例:
#include "stdafx.h"
#include "resource.h"
//文档类
class CMyDoc:public CDocument
{
public:
	CMyDoc()
	{
		m_strText="Data From Doc!";
	}


	CString m_strText;
};
class CDocView:public CEditView
{
	DECLARE_DYNCREATE(CDocView);
public:
		virtual void OnInitialUpdate();
};
IMPLEMENT_DYNCREATE(CDocView,CEditView)
void CDocView::OnInitialUpdate()
{
	CMyDoc* doc= (CMyDoc*)this->GetDocument();//获取视图对应的文档
	SetWindowText(doc->m_strText);
	this->UpdateData(TRUE);
}
//窗口框架类
class CDocFrame:public CFrameWnd
{
};
//应用程序类
class CDocApp:public CWinApp
{
public:
	virtual BOOL InitInstance();
};
CDocApp theApp;
BOOL CDocApp::InitInstance()
{
	CDocFrame *pFrame=new CDocFrame;
	//动态创建视图
	CCreateContext cxt;
	cxt.m_pCurrentDoc=new CMyDoc;
	cxt.m_pNewViewClass=RUNTIME_CLASS(CDocView);
	pFrame->LoadFrame(IDR_MAINFRAME,
		WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,NULL,&cxt);
	pFrame->InitialUpdateFrame(NULL,TRUE);//这里才会调用视图的OnInitialUpdate
	m_pMainWnd=pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}




 单文档视图应用程序

   1 概念
     只能管理一个文档
   2 相关类
     CWinApp-应用程序类
     CFrameWnd-框架类
     CView-视图类
     CDocument-文档类
     CDocTemplate-文档模板类
     CSingleDocTemplate-单文档模板类,父类是CDocTemplate。使用
     文档模板类创建但文档应用程序时,框架、视图和文档都是采用动态
     创建的方式创建对象的。
     CSingleDocTemplate(
       UINT nIDResource,//资源ID
       CRuntimeClass* pDocClass,//文档类的运行时类信息
       CRuntimeClass* pFrameClass,//框架的运行时类信息
       CRuntimeClass* pViewClass //视图的运行时类信息
     );
    3 创建过程
    3.1 AddDoctemplate()-添加文档模板
        {
          if (m_pDocManager == NULL)
             //新建文档管理类的对象
    m_pDocManager = new CDocManager;
 m_pDocManager->AddDocTemplate(pTemplate);
          {
             //将文档模板对象地址保存到链表中
             m_templateList.AddTail(pTemplate);
          }
        }
    3.2 OnFileNew()-新建文档
        {
          m_pDocManager->OnFileNew();
          {
            pTemplate->OpenDocumentFile(NULL);
            {
              //动态创建文档对象
              pDocument = CreateNewDocument();
              //动态创建框架对象和创建窗口
              pFrame = CreateNewFrame(pDocument, NULL);
              {
                 //1 动态创建框架对象
                 (CFrameWnd*)m_pFrameClass->CreateObject();
                 //2 创建框架窗口
                 pFrame->LoadFrame(...);
                 //3 接着文档类中描述的创建过程,在框架的
                 WM_CREATE消息处理函数中,创建视图对象和窗口;
                 在视图的WM_CREATE消息处理函数中,文档与视图
                 相互保存对方地址。
              }


            }
          }
        }


   4 各个类(或者说各个对象)之间的关系
    CWinApp
      |->m_pDocManager (CDocManager)
           |->m_templateList  (CSingleDocTemplate)
                |->m_pOnlyDoc (CDocument)
                |->CRuntimeClass* m_pDocClass;  (CDocument)
       |->CRuntimeClass* m_pFrameClass; (CFramWnd)
                |->CRuntimeClass* m_pViewClass;  (CView)
      |->m_pMainWnd (CFrameWnd)
           |->m_pActiveView(CView)
                |->m_pDocument (CDocument)
                      |->m_viewList (CView)
     各个类(各个对象)之间的关系通过保存对方地址产生的
   5 处理命令消息的默认先后顺序
     View->Document->Frame->App


//示例:有些东西没加,选择使用MFC动态库才能运行正常
#include "stdafx.h"
#include "resource.h"
//文档类
class  CMyDoc:public CDocument
{
DECLARE_DYNCREATE(CMyDoc)
};
IMPLEMENT_DYNCREATE(CMyDoc,CDocument)


//视图类
class CMyView:public CEditView
{
DECLARE_DYNCREATE(CMyView)
};
IMPLEMENT_DYNCREATE(CMyView,CEditView)




//应用程序类
class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CMyApp theApp;
//框架窗口类
class CMyFrame:public CFrameWnd
{
DECLARE_DYNCREATE(CMyFrame)
};
IMPLEMENT_DYNCREATE(CMyFrame,CFrameWnd)


BOOL CMyApp::InitInstance()
{
//创建单文档模版对象
CSingleDocTemplate *pTemplate=new CSingleDocTemplate(IDR_MAINFRAME,
RUNTIME_CLASS(CMyDoc),RUNTIME_CLASS(CMyFrame),RUNTIME_CLASS(CMyView));
//将文档模版对象添加到应用程序
AddDocTemplate(pTemplate);
//新建文档
OnFileNew();
//显示更新窗口
m_pMainWnd->ShowWindow(SW_MAXIMIZE);
m_pMainWnd->UpdateWindow();
return TRUE;
}




多文档视图应用程序

   1 概念
    可以管理多个文档
   2 相关类
    CWinApp-应用程序类
    CMDIFrameWnd-多文档主框架类
    CMDIChildWnd-多文档子框架类
    CView-视图类
    CDocument-文档类
    CMultiDocTemplate-多文档模板类
    多文档菜单有两个、图标也有两个,分别是主框架的和子框架的。
    主框架窗口对象只有一个,而子框架窗口可以有多个。每一次新建
    会创建子框架、视图和文档对象,使用文档模板创建的。
    注意:要求主框架窗口的菜单,菜单项至少是两项!
  3 创建
    添加新建菜单的消息处理
    3.1 "新建"与"新建视图"的区别
      "新建",创建子框架、视图和文档共3个对象
      "新建视图",只想创建子框架和视图,文档使用原有的活动视图的

       文档。最终的目的,一个文档对应多个视图。

多个视图数据同步
   1 捕获视图内容发生变化的消息,在消息处理函数中,将当前视图的数据
     保存到文档,通知其它视图文档数据发生改变了。
     1.1 消息映射,ON_CONTROL_REFLECT
     1.2 通知视图数据更新,CDocument::UpdateAllViews

   2 其它视图收到通知后,在函数中,将文档的新的数据显示到本视图上
     2.1 CView::OnUpdate()函数,视图更新函数,被CDocument::

         UpdateAllViews()函数调用。


代码示例:
// MFCmdi.cpp : Defines the entry point for the application.
//加两个菜单资源,两个ICO资源,主窗口和子窗口的分别是IDR_MAINFRAME,IDR_CHILDFRAME
#include <afxwin.h>
#include <afxext.h>
#include "stdafx.h"
#include "resource.h"

//文档类
class CMyDoc:public CDocument
{
	DECLARE_DYNCREATE(CMyDoc)
};
IMPLEMENT_DYNCREATE(CMyDoc,CDocument)


//视图类
class CMyView:public CEditView
{
	DECLARE_DYNCREATE(CMyView)
};
IMPLEMENT_DYNCREATE(CMyView,CEditView)


//子框架窗口类-动态创建
class CChildFrame:public CMDIChildWnd
{
	DECLARE_DYNCREATE(CChildFrame)
};
IMPLEMENT_DYNCREATE(CChildFrame,CMDIChildWnd)
//主框架窗口类
class CMainFrame:public CMDIFrameWnd
{
DECLARE_MESSAGE_MAP()
public:
protected:
	void OnNewView();
};
//新建视图,不新建文档,让一个活动文档对应多个视图
void CMainFrame::OnNewView()
{
	//获取活动子窗口
	CChildFrame* pFrame=(CChildFrame*)GetActiveFrame();
	//获取活动视图
	CMyView*pView=(CMyView*)pFrame->GetActiveView();
	//获取活动文档
	CMyDoc* pDoc=(CMyDoc*)pView->GetDocument();
	//获取文档模版
	CDocTemplate*pTemplate=pDoc->GetDocTemplate();
	//由模版,基于活动文档 创建新的子窗口
	CChildFrame*pNewFrame= (CChildFrame*)pTemplate->CreateNewFrame(pDoc,NULL);
	pTemplate->InitialUpdateFrame(pNewFrame,NULL);
}
BEGIN_MESSAGE_MAP(CMainFrame,CMDIFrameWnd)
ON_COMMAND(ID_NEW_VIEW,OnNewView)
END_MESSAGE_MAP()
//应用程序类
class CMyApp:public CWinApp
{
	DECLARE_MESSAGE_MAP()


public:
	virtual BOOL InitInstance();
protected:
	void OnNew();


};
BEGIN_MESSAGE_MAP(CMyApp,CWinApp)
ON_COMMAND(ID_NEW,OnNew)


END_MESSAGE_MAP()
//新建
void CMyApp::OnNew()
{
	this->OnFileNew();
}


BOOL CMyApp::InitInstance()
{
	CMainFrame *pFrame=new CMainFrame;
	pFrame->LoadFrame(IDR_MAINFRAME);
	m_pMainWnd=pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	CMultiDocTemplate *pTemplate=new CMultiDocTemplate(
		IDR_CHILDFRAME,RUNTIME_CLASS(CMyDoc),
		RUNTIME_CLASS(CChildFrame),RUNTIME_CLASS(CMyView));
	//将文档模版对象添加到应用程序
	AddDocTemplate(pTemplate);
	//新建文档
	OnFileNew();
	return TRUE;
}
CMyApp theApp;





相关文章
|
6天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
29 5
|
12天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
40 4
|
14天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
38 4
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
22 1
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
28 4
|
1月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
25 4
|
1月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
1月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
1月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
54 1
|
1月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
20 1