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

文档类

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;
上一篇:MFC文档视图结构学习笔记


下一篇:Win7与Ubuntu双系统时卸载Ubuntu的方法