MFC单文档视图结构源码剖析_第1页
MFC单文档视图结构源码剖析_第2页
MFC单文档视图结构源码剖析_第3页
MFC单文档视图结构源码剖析_第4页
MFC单文档视图结构源码剖析_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MFC单文档视图构造源码分析第一章找回WinMain函数第一在VC的安装路径中找到WINMAIN.CPP文件,AfxWinMain函数就是VC编译器的进口,去掉一些不重要的东西后获取以下得程序。intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){intnReturnCode=-1;CWinApp*pApp=AfxGetApp( );///获取应用程序类的指针与文档视图没关。AfxWinInit(hInstance,hPrevInstance,lpCmdLine,nCmdShow);///与文档视图没关。pApp->InitApplication( );初始化应用程序详见下文。pApp->InitInstance( );///最重要下边祥述nReturnCode=pApp->Run( );///信息循环直到应用程序被关闭。与文档视图没关。AfxWinTerm( );与文档视图没关。returnnReturnCode;///整个应用结束。}下边分节表达。第二章InitApplication( )函数在文件Appcore.cpp文件中InitApplication以下:BOOLCWinApp::InitApplication( ){if(CDocManager::pStaticDocManager!=NULL)///这段和我们关系不大,临时不理它{if(m_pDocManager==NULL)m_pDocManager=CDocManager::pStaticDocManager;CDocManager::pStaticDocManager=NULL;}if(m_pDocManager!=NULL)m_pDocManager->AddDocTemplate(NULL);elseCDocManager::bStaticInit=FALSE;/*

我们的程序将会执行到这句

,表示文档类用动向方式创立

,也就是说用

RUNTIME_CLASS

来创立的

(详见下文

)。*/returnTRUE;}说明:CDocManager类是一个不公开的类,他主要用来管理多文档模板对象的,关于单文档只有一个文档模板这个类不是很重要,但还是用它管理文档模板的;本文只在相关之处作说明。bStaticInit是它的一个静态成员。第三章InitInstance( )函数它一般被重载,在First工程中,InitInstance中和文档视图类相关的程序有下边的一些:CSingleDocTemplate*pDocTemplate;定义指针pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CFirstDoc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CFirstView));这条语句的作用见第一段AddDocTemplate(pDocTemplate);CCommandLineInfocmdInfo;定义一个对象ParseCommandLine(cmdInfo);///分析命令行并发送参数,与文档视图没关if(!ProcessShellCommand(cmdInfo))这是最重要的详见的三段returnFALSE;m_pMainWnd->ShowWindow(SW_SHOW);显示窗口m_pMainWnd->UpdateWindow( );第一节:newCSingleDocTemplatenewCSingleDocTemplate其实就是创立一个CSingleDocTemplate对象并调用他的构造函数,要讲清楚这句话,第一一定理解RUNTIME_CLASS构造,RUNTIME_CLASS构造定义以下:#defineRUNTIME_CLASS(class_name)((CRuntimeClass*)(&class_name::class##class_name))于是这句话睁开后以下(关于吻合##的详细意义拜见MSDN):pDocTemplatenewCSingleDocTemplate(IDR_MAINFRAME,(CRuntimeClass*)(&CFirstDoc::classCFirstDoc),(CRuntimeClass*)(&CMainFrame::classCMainFrame),(CRuntimeClass*)(&CFirstView::classCFirstView));这时我们会发现CfirstDoc,CmainFrame,CfirstView各会多冒出一个静态成员出来,它终归在哪里呢?查察这三个类的定义我们会发现每个类定义都有一个宏DECLARE_DYNCREATE,在实现文件中有别的一个宏IMPLEMENT_DYNCREATE。下边把这些宏的睁开状况列出以下:(1)文档类DECLARE_DYNCREATE(CFirstDoc)睁开后为:public:staticconstCRuntimeClassclassCFirstDoc;这就是上边所说的那个静态成员virtualCRuntimeClass*GetRuntimeClass( )const;staticCObject*PASCALCreateObject( );IMPLEMENT_DYNCREATE(CFirstDoc,CDocument)睁开后为:CObject*PASCALCFirstDoc::CreateObject( ){returnnewCFirstDoc;}constCRuntimeClassCFirstDoc::classCFirstDoc={"CFirstDoc",sizeof(classCFirstDoc),0xFFFF,CFirstDoc::CreateObject,(CRuntimeClass*)(&CDocument::classCDocument),NULL};CRuntimeClass*CFirstDoc::GetRuntimeClass( )const{return(CRuntimeClass*)(&CFirstDoc::classCFirstDoc);}(2)视图类DECLARE_DYNCREATE(CFirstView)睁开后为:public:staticconstCRuntimeClassclassCFirstView;virtualCRuntimeClass*GetRuntimeClass( )const;staticCObject*PASCALCreateObject( );IMPLEMENT_DYNCREATE(CFirstView,CView)睁开后为:CObject*PASCALCFirstView::CreateObject( ){returnnewCFirstView;}constCRuntimeClassCFirstView::classCFirstView={"CFirstView",sizeof(classCFirstView),0xFFFF,CFirstView::CreateObject,(CRuntimeClass*)(&CView::classCView),NULL};CRuntimeClass*CFirstView::GetRuntimeClass( )const{return(CRuntimeClass*)(&CFirstView::classCFirstView);}(3)主框架类DECLARE_DYNCREATE(CMainFrame)睁开后为:public:staticconstCRuntimeClassclassCMainFrame;virtualCRuntimeClass*GetRuntimeClass( )const;staticCObject*PASCALCreateObject( );IMPLEMENT_DYNCREATE(CMainFrame,CFrameWnd)睁开后为:CObject*PASCALCMainFrame::CreateObject( ){returnnewCMainFrame;}constCRuntimeClassCMainFrame::classCMainFrame={"CMainFrame",sizeof(classCMainFrame),0xFFFF,CMainFrame::CreateObject,(CRuntimeClass*)(&CFrameWnd::classCFrameWnd),NULL};CRuntimeClass*CMainFrame::GetRuntimeClass( )const{return(CRuntimeClass*)(&CMainFrame::classCMainFrame);}这些宏第一在你的定义文件中定义一个以class+类名为名字的静态变量。而后定义一个返回这个静态变量的函数GetRuntimeClass并在实现文件中实现之。最后定义并实现一个创立对象的函数CreateObject。好了,我们此刻就来看看CSingleDocTemplate对象的构造函数做了些什么:下边是他的实现CSingleDocTemplate::CSingleDocTemplate(UINTnIDResource,CRuntimeClass*pDocClass,CRuntimeClass*pFrameClass,CRuntimeClass*pViewClass)CDocTemplate(nIDResource,pDocClass,pFrameClass,pViewClass){m_pOnlyDoc=NULL;}它主若是初始化他的父类CDocTemplate,CDocTemplate做了些什么?以下:{把资源

ID

及文档、框架、视图的三个

CRuntimeClass

构造的静态成员的地址

(也就是传进来的四个参数

)保存了起来。LoadTemplate( );///

为指定的文档模板对象装载资源}至此这个

new

语句总算讲完了。第二节:

AddDocTemplate(pDocTemplate);下边是他的实现函数voidCWinApp::AddDocTemplate(CDocTemplate*pTemplate){if(m_pDocManager==NULL)m_pDocManager=newCDocManager;/*创立一个文档管理类,关于单文档常常只有一个文档模板用CDocManager类其实不是很重要,我们可以忽视这句*/m_pDocManager->AddDocTemplate(pTemplate);/*把文档模板指针保存在CDocManager实例中由CDocManager去管理他,我们只需知道有这个事就行了*/}第三节:ProcessShellCommand(cmdInfo)这个函数发送的一个命令就是FileNew其余的临时不论他,其实全部的文档类,框架类,视图类都是在这个函数中创立的,在第一段中已经讲到应用程序类将上三个类的CRuntimeClass一个静态成员地址保存起来了,关于CRuntimeClass构造的详细功能参照MSDN。ProcessShellCommand描述以下:BOOLCWinApp::ProcessShellCommand(CCommandLineInfo&rCmdInfo){BOOLbResult=TRUE;switch(rCmdInfo.m_nShellCommand){caseCCommandLineInfo::FileNew:if(!AfxGetApp( )->OnCmdMsg(ID_FILE_NEW,0,NULL,NULL))OnFileNew( );if(m_pMainWnd==NULL)bResult=FALSE;break;caseCCommandLineInfo::FileOpen:if(!OpenDocumentFile(rCmdInfo.m_strFileName))bResult=FALSE;break;.///}returnbResult;}AfxGetApp( )->OnCmdMsg( )AfxGetApp( )->OnCmdMsgID_FILE_NEWOnFileNewOnFileNew( );OnFileNew,voidCWinApp::OnFileNew( ){if(m_pDocManager!=NULL)m_pDocManager->OnFileNew( );///不过调用CDocManager::OnFileNew}文档管理类的OnFileNew去掉一些没用的东西后实现以下:voidCDocManager::OnFileNew( ){CDocTemplate*pTemplate=(CDocTemplate*)m_templateList.GetHead( );/*获取第一个文档模板,关于单文档只有一个文档模板*/if(m_templateList.GetCount( )>1)///对单文档这段没用{CNewTypeDlgdlg(&m_templateList);intnID=dlg.DoModal( );if(nID==IDOK)pTemplate=dlg.m_pSelectedTemplate;elsereturn;///none-canceloperation}pTemplate->OpenDocumentFile(NULL);/*实际上是调用CSingleDocTemplate::OpenDocumentFile函数下边祥述这里,由于在CDocTemplate类中这个函数是一个纯虚函数*/}下边简述pTemplate->OpenDocumentFile(NULL);这个函数,这是最重要的一个函数,他执行了以下6个步骤:pDocument=CreateNewDocument( );///创立一个新文档{CDocument*pDocument=(CDocument*)m_pDocClass->CreateObject( );/*这是才真切的创立文档对象,这里创立的文档对象就是上边RUNTIME_CLASS(CFirstDoc),中的对象这是MFC开发人员想出来的一种运转时创立对象的方法,应当说比较不错的,不知道C++Builder的是如何构造的。*/AddDocument(pDocument);///把创立的对象指针记录下来,此后还要用的。}pFrame=CreateNewFrame(pDocument,NULL);/*依据新文档指针创立新文档框架,这个比较重要下一段描述*/SetDefaultTitle(pDocument);设置缺省标题,不重要的pDocument->OnNewDocument( )除去老文档内容{DeleteContents( );删除本来的内容而不论能否存盘SetModifiedFlag(FALSE);除去以前修悔悟的标志}pThread->m_pMainWnd=pFrame;框架窗口作为的指针作为主窗口的指针InitialUpdateFrame(pFrame,pDocument,bMakeVisible);/*使框架中的视图窗口接遇到OnInitialUpdat的调用,并作原始更新。*/至此第一段的OnFileNew函数总算讲完。下边讲CreateNewFrame函数CreateNewFrame是CDocTemplate的成员函数以下3个步骤:CCreateContextcontext;创立CcreateContext对象.也就是我们重载LoadFrame函数的那个CcreateContext的本源*/context.m_pCurrentFrame=pOther;///保存当前框架,一般为NULLcontext.m_pCurrentDoc=pDoc;保存文档对象指针context.m_pNewViewClass=m_pViewClass;保存视图对象指针context.m_pNewDocTemplate=this;保存文档模板的指针。CFrameWnd*pFrame=(CFrameWnd*)m_pFrameClass->CreateObject( );真切创立框架的对象pFrame->LoadFrame(m_nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,NULL,&context)加载资源,这是最重要的,下边表达{GetIconWndClass(dwDefaultStyle,nIDResource)///加载资源并注册窗口{AfxFindResourceHandle::LoadIcon加载光标资源CREATESTRUCTcs;///创立一个CREATESTRUCT构造实例PreCreateWindow(cs);/*调用窗口预创立函数,这个函数我们可以重载的依据cs调用AfxRegisterWndClass注册框架窗口*/}Create( )创立框架窗口,后边祥述,此处临时不讲。m_hMenuDefault=::GetMenu(m_hWnd);获取并保存菜单句柄LoadAccelTable(MAKEINTRESOURCE(nIDResource));装载加快键表}下边讲Create函数,以下4个步骤:hMenu=::LoadMenu(hInst,lpszMenuName);///加载菜单CREATESTRUCTcs;///创立一个CREATESTRUCT构造实例cs.lpCreateParams=lpParam;///(此时的lpParam就是建的context对象指针)PreCreateWindow(cs);调用窗口预创立函数,这个函数我们可以重载的,又调用一次调用API函数::CreateWindowEx真切创立框架窗口,创立过程中会发出WM_CREATE和WM_NCCREATE等信息。下边讲接收WM_CREATE信息的信息办理函数CMainFrame::OnCreate,其余信息不重要CMainFrame::OnCreate最重要的是调用CFrameWnd::OnCreateHelper函数以

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论