MFC单文档视图穷追猛打

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MFC单文档视图穷追猛打

目录

第一章找回WinMain函数 2

第二章InitApplication()函数 2

第三章InitInstance ()函数 3

第一节:new CSingleDocTemplate 3

第二节:AddDocTemplate(pDocTemplate); 5

第三节:ProcessShellCommand(cmdInfo) 5

第一段AfxGetApp()->OnCmdMsg(…) 6

第二段OnFileNew(); 6

第四节:m_pMainWnd->ShowWindow(SW_SHOW); ///显示窗口 8

第五节:m_pMainWnd-> UpdateWindow (); ///重画窗口 8

第四章pApp->Run函数 8

第五章总结 8

本文将针对一个单文档来描述MFC的文档/视图结构,他直接打开MFC的源代码进行分析,在分析过程中去掉了无关的部分。所以第一步就是要创建一个称为First得工程,文档类型是单文档,下文将围绕这个工程来讲的。

第一章找回WinMain函数

首先在VC的安装路径中找到WINMAIN.CPP文件,AfxWinMain函数就是VC编译器的入口,去掉一些不重要的东西后得到如下得程序。

int AFXAPI AfxWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,L PTSTR lpCmdLine, int nCmdShow)

{

int nReturnCode = -1;

CWinApp* pApp = AfxGetApp(); ///获取应用程序类的指针与文档视图无关。AfxWinInit(hInstance, hPrevInstance,lpCmdLine,nCmdShow); ///与文档视图无关。

pApp->InitApplication(); ///初始化应用程序详见下文。

pApp->InitInstance(); ///最重要下面祥述

nReturnCode = pApp->Run();///消息循环直到应用程序被关闭。与文档视图无关。

AfxWinTerm(); ///与文档视图无关。

return nReturnCode;///整个应用结束。

}

下面分节讲述。

第二章InitApplication()函数

在文件Appcore.cpp文件中InitApplication如下:

BOOL CWinApp::InitApplication()

{

if (CDocManager::pStaticDocManager != NULL) ///这段和我们关系不大,暂时不理它

{

if (m_pDocManager == NULL)

m_pDocManager = CDocManager::pStaticDocManager;

CDocManager::pStaticDocManager = NULL;

}

if (m_pDocManager != NULL)

m_pDocManager->AddDocTemplate(NULL);

else

CDocManager::bStaticInit = FALSE; /*我们的程序将会执行到这句,表示文档类用动态方式创建,也就是说用RUNTIME_CLASS来创建的(详见下文)。*/ return TRUE;

}

说明:CDocManager类是一个不公开的类,他主要用来管理多文档模板对象的,对于单文档只有一个文档模板这个类不是很重要,但还是用它管理文档模板的;本文只在相关之处作说明。bStaticInit是它的一个静态成员。

第三章InitInstance ()函数

它一般被重载,在First工程中,InitInstance中和文档视图类有关的程序有下面的一些:

CSingleDocTemplate* pDocTemplate; ///定义指针

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CFirstDoc),

RUNTIME_CLASS(CMainFrame),

RUNTIME_CLASS(CFirstView)); ///这条语句的作用见第一段

AddDocTemplate(pDocTemplate);

CCommandLineInfo cmdInfo; ///定义一个对象

ParseCommandLine(cmdInfo); ///解析命令行并发送参数,与文档视图无关

if (!ProcessShellCommand(cmdInfo)) ///这是最重要的详见的三段

return FALSE;

m_pMainWnd->ShowWindow(SW_SHOW); ///显示窗口

m_pMainWnd->UpdateWindow();

第一节:new CSingleDocTemplate

new CSingleDocTemplate其实就是创建一个CSingleDocTemplate对象并调用他的构造函数,要讲清楚这句话,首先必须明白RUNTIME_CLASS结构,RUNTIME_C LASS结构定义如下:

#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::clas s##class_name))

于是这句话展开后如下(关于符合##的具体意义参见MSDN):

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

(CRuntimeClass*)(&CFirstDoc::classCFirstDoc),

(CRuntimeClass*)(&CMainFrame::classCMainFrame),

(CRuntimeClass*)(&CFirstView::classCFirstView));

这时我们会发现CfirstDoc,CmainFrame,CfirstView各会多冒出一个静态成员出来,它究竟在哪里呢?查看这三个类的定义我们会发现每个类定义都有一个宏DECLARE_DYNCREATE,在实现文件中有另外一个宏IMPLEMENT_DYNCREATE。下面把这些宏的展开情况列出如下:

(1)文档类

DECLARE_DYNCREATE(CFirstDoc) 展开后为:

public:

static const CRuntimeClass classCFirstDoc; ///这就是上面所说的那个静态成员

virtual CRuntimeClass* GetRuntimeClass() const;

static CObject* PASCAL CreateObject();

IMPLEMENT_DYNCREATE(CFirstDoc, CDocument) 展开后为:

CObject* PASCAL CFirstDoc::CreateObject()

{ return new CFirstDoc; }

const CRuntimeClass CFirstDoc::classCFirstDoc= {

"CFirstDoc", sizeof(class CFirstDoc), 0xFFFF, CFirstDoc::CreateObje ct, (CRu

ntimeClass*)(&CDocument::classCDocument), NULL };

CRuntimeClass* CFirstDoc::GetRuntimeClass() const

{ return (CRuntimeClass*)(&CFirstDoc::classCFirstDoc); }

(2)视图类

DECLARE_DYNCREATE(CFirstView) 展开后为:

public:

static const CRuntimeClass classCFirstView;

virtual CRuntimeClass* GetRuntimeClass() const;

static CObject* PASCAL CreateObject();

相关文档
最新文档