CDocument类的使用

来源:互联网 发布:刺客信条4低配优化 编辑:程序博客网 时间:2024/04/30 23:57

首先我们来写一个例子:在视图类中显示文档类的数据

1.建一个win32简单应用程序

2. 删除入口函数,只留下#include "stdafx.h"

3.将stdafx.h中的头文件 <windows.h> 更改为 <afxwin.h>。

4.Project-->Settings菜单项中设置使用MFC库

5.编写代码

// MFCDoc.cpp : Defines the entry point for the application.//#include "stdafx.h"#include <afxext.h>#include "resource.h"class CMyDoc : public CDocument{public:CString m_strData;CMyDoc(){m_strData = "Hello World!";}DECLARE_MESSAGE_MAP()protected:void OnTest();};BEGIN_MESSAGE_MAP(CMyDoc,CDocument)ON_COMMAND(ID_TEST,OnTest)END_MESSAGE_MAP()void CMyDoc::OnTest(){AfxMessageBox("CMyDoc::OnTest");}//定义动态创建的视图类class cDocView: public CEditView//继承自CEditView无需实现OnDraw函数{DECLARE_DYNCREATE(cDocView)  public:virtual void OnInitialUpdate( );};IMPLEMENT_DYNCREATE(cDocView,CEditView)void cDocView::OnInitialUpdate(){//1 获取与视图关联的文档CMyDoc *pDoc = (CMyDoc*)GetDocument();//2 将文档数据显示到视图SetWindowText(pDoc->m_strData);}class CMainFrame:public CFrameWnd{};class CDocApp:public CWinApp{public:virtual BOOL InitInstance();};CDocApp theApp;BOOL CDocApp::InitInstance(){CMainFrame *pFrame = new CMainFrame;CCreateContext cxt;//指定创建视图时所需的视图类cxt.m_pNewViewClass = RUNTIME_CLASS(cDocView);//创建与视图对象关联的文档对象cxt.m_pCurrentDoc = new CMyDoc;pFrame->LoadFrame(IDR_MENU1,WS_OVERLAPPEDWINDOW,NULL,&cxt);pFrame->InitialUpdateFrame(NULL,TRUE);//此函数会自动调用OnInitialUpdate函数m_pMainWnd = pFrame;pFrame->ShowWindow(SW_SHOW);pFrame->UpdateWindow();return TRUE;}
注意:这里需要自己添加菜单资源,File->new ->Resourse Script ,插入Menu



分析:

2.1 相关函数

     2.1.1 CView::OnInitialUpdate()-初始化视图对象

     被框架窗口的函数调用,在第一次附加文档之后,视图窗口初始化显示之前。

     2.1.2 CView::GetDocument()

     获取与视图关联的文档 

     2.1.3 CFrameWnd::InitialUpdateFrame()-初始化更新框架在框架窗口创建后调用该函数,引起该框架内所有的视图窗口的OnInitialUpdate()函数的调用。

   2.2 实现步骤:

     2.2.1 App::InitInstance()函数中:

        1 创建框架对象 new CMainFrame

        2 定义结构体变量 CCreateContext cxt;保存视图类的运行时类信息的地址,创建文档,保存文档对象地址。

        3 调用LoadFrame函数,创建框架窗口,并把变量cxt作为该函数的参数。

        4 作为应用程序主窗口,显示和更新

     2.2.2 在文档中添加成员变量m_strData,并初始化

     2.2.3 重写CView::OnInitialUpdate()函数,在函数中,把文档中的数据显示到视图。

     2.2.4 LoadFrame函数之后,调用了InitialUpdateFrame()函数。


思考:

1. 视图对象是在什么时候被动态创建?

   答:视图对象的创建放到了框架的消息处理中创建的

   分析:在整个线性流程找不到CreateView的时候我们需要考虑消息机制,即LoadFrame调用Create函数时,产生了 create消息,同时让OnCreate函数处理,我们从ctrl+f 搜下 OnCreated看到到OnCreateClient函数,最终我们发现:调试跟进这些函数断点OnCreate->OnCreateHelper->OnCreateClient->CreateView()


2. 文档与视图的关系什么?关系什么时候建立?

   答:视图类与文档类相互保存对方的地址。一个文档可以对应多个视图,但是一个视图只能对应一个文档。

在CView::OnCreate()函数中:(viewcore.cpp)         调用m_pCurrentDoc->AddView(this);    97行         AddView()函数的执行流程:        void CDocument::AddView(CView* pView)        {   ...          //将视图的地址保存到文档对象的链表中   m_viewList.AddTail(pView);                //将文档地址保存到视图对象的变量中     pView->m_pDocument = this;          ...  }

3.CDocument-继承自CCmdTarget类,意味着文档类也可以处理命令消息,那么处理消息的顺序是? 

  答: ActiveView->Document->Frame->App

    在AfxMessageBox("CMyDoc::OnTest");这行加断点,调用堆栈得到下图,调试跟进可得到上边结论 

    

0 0
原创粉丝点击