单文档视图应用程序

1. 单文档视图应用程序和多文档的区别:

前者在某一时刻只能管理一个文档,而后者可以管理多个


2. 文档模板类

作用:用统一的方式创建框架、视图、文档对象。

CDocTemplate: 抽象基类,提供了所有文档模板的功能。

CSingleDocTemplate:单文档模板类

     CSingleDocTemplate( 
      	UINT nIDResource,//资源ID
     	 CRuntimeClass* pDocClass,//文档类的运行时类信息 
     	 CRuntimeClass* pFrameClass,//框架类的运行时类信息
      	CRuntimeClass* pViewClass//视图类的运行时类信息 
     );

 注意:定义文档、框架和视图类时需要动态创建的支持


3. 建一个win32简单应用程序, 删除入口函数,将stdafx.h中的头文件 <windows.h> 更改为 <afxwin.h>,Project-->Settings菜单项中设置使用MFC动态库,需要自己添加菜单资源,File->new ->Resourse Script ,插入Menu

// Sdi.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include <afxext.h>
class CSdiDoc:public CDocument
{
	DECLARE_DYNCREATE(CSdiDoc)
};
IMPLEMENT_DYNCREATE(CSdiDoc,CDocument)

class CSdiView:public CEditView
{
	DECLARE_DYNCREATE(CSdiView)
};
IMPLEMENT_DYNCREATE(CSdiView,CEditView)
class CMainFrame:public CFrameWnd
{
	DECLARE_DYNCREATE(CMainFrame)
};
IMPLEMENT_DYNCREATE(CMainFrame,CFrameWnd)
class CSdiApp:public CWinApp
{
public:
	virtual BOOL InitInstance();
};
CSdiApp theApp;
BOOL CSdiApp::InitInstance()
{
	//创建单文档模板
	CSingleDocTemplate *pTemplate=
		new CSingleDocTemplate(
		IDR_MENU1,
		RUNTIME_CLASS(CSdiDoc),
		RUNTIME_CLASS(CMainFrame),
		RUNTIME_CLASS(CSdiView));
    //把文档模板添加到应用程序
	AddDocTemplate(pTemplate);
    //新建文档,(创建文档、框架和视图对象)
	OnFileNew();
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();
	return TRUE;
}


分析:

AddDocTemplate函数的实现:我们设断点进入函数中得到

void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)
{
	if (m_pDocManager == NULL)
		m_pDocManager = new CDocManager;
	m_pDocManager->AddDocTemplate(pTemplate);
}
<pre name="code" class="cpp">void CDocManager::AddDocTemplate(CDocTemplate* pTemplate)
       {
          ...
          //在文档模板链表中添加新建的文档模板
          m_templateList.AddTail(pTemplate);   534行 
       }

 我们可以看出: 

1. 应用程序没有直接管理模板,而是交给文档管理类管理模板

2. 在文档管理类使用链表保存文档模板,可以管理多个模板 

 OnFileNew()函数的实现:我们设断点进入函数中得到

void CWinApp::OnFileNew()
      {
		if (m_pDocManager != NULL)
	    	m_pDocManager->OnFileNew();
      } 

      void CDocManager::OnFileNew()
     {
        ...
        //获取保存的文档模板
	CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
        //调用文档模板的OpenDocumentFile()函数
        pTemplate->OpenDocumentFile(NULL);      827行
     }

     CDocument* CSingleDocTemplate::OpenDocumentFile(...)
     {
        //创建新的文档对象
        pDocument = CreateNewDocument();         112行
        //创建新的框架对象和框架窗口
        pFrame = CreateNewFrame(pDocument, NULL); 132行
     }

     CFrameWnd* CDocTemplate::CreateNewFrame(...)
     {
        //创建新的框架对象
        CFrameWnd* pFrame =                      264行 
           (CFrameWnd*)m_pFrameClass->CreateObject();
        //创建新的框架窗口
        if (!pFrame->LoadFrame(m_nIDResource,...); 277行
     }
调用LoadFrame时,产生WM_CREATE消息,在消息处理函数OnCreate()中,调用CreateView()函数,创建视图对象和视图窗口。
创建视图窗口时,产生WM_CREATE消息,在消息处理函数OnCreate()中,调用AddView()函数,文档与视图相互保存对方的地址。




 

画出类之间的调用关系图

CWinApp
        |->m_pDocManager(CDocManager*)
             |->m_templateList (CSingleDocTemplate*) 
                  |->m_pOnlyDoc (CDocument*)
 
        |->m_pMainWnd(CFrameWnd*)
             |->m_pActiveView(CView*)
                  |->m_pDocument (CDocument*)
                       |->m_viewList (CView*)


结论:MFC各个类之间的关系实质上通过包含对方地址产生的






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值