MFC單文檔視圖結(jié)構(gòu)源碼剖析_第1頁(yè)
MFC單文檔視圖結(jié)構(gòu)源碼剖析_第2頁(yè)
MFC單文檔視圖結(jié)構(gòu)源碼剖析_第3頁(yè)
MFC單文檔視圖結(jié)構(gòu)源碼剖析_第4頁(yè)
MFC單文檔視圖結(jié)構(gòu)源碼剖析_第5頁(yè)
已閱讀5頁(yè),還剩16頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

MFC單文檔視圖構(gòu)造源碼分析第一章找回WinMain函數(shù)第一在VC的安裝路徑中找到WINMAIN.CPP文件,AfxWinMain函數(shù)就是VC編譯器的進(jìn)口,去掉一些不重要的東西后獲取以下得程序。intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){intnReturnCode=-1;CWinApp*pApp=AfxGetApp( );///獲取應(yīng)用程序類的指針與文檔視圖沒關(guān)。AfxWinInit(hInstance,hPrevInstance,lpCmdLine,nCmdShow);///與文檔視圖沒關(guān)。pApp->InitApplication( );初始化應(yīng)用程序詳見下文。pApp->InitInstance( );///最重要下邊祥述nReturnCode=pApp->Run( );///信息循環(huán)直到應(yīng)用程序被關(guān)閉。與文檔視圖沒關(guān)。AfxWinTerm( );與文檔視圖沒關(guān)。returnnReturnCode;///整個(gè)應(yīng)用結(jié)束。}下邊分節(jié)表達(dá)。第二章InitApplication( )函數(shù)在文件Appcore.cpp文件中InitApplication以下:BOOLCWinApp::InitApplication( ){if(CDocManager::pStaticDocManager!=NULL)///這段和我們關(guān)系不大,臨時(shí)不理它{if(m_pDocManager==NULL)m_pDocManager=CDocManager::pStaticDocManager;CDocManager::pStaticDocManager=NULL;}if(m_pDocManager!=NULL)m_pDocManager->AddDocTemplate(NULL);elseCDocManager::bStaticInit=FALSE;/*

我們的程序?qū)?huì)執(zhí)行到這句

,表示文檔類用動(dòng)向方式創(chuàng)立

,也就是說用

RUNTIME_CLASS

來創(chuàng)立的

(詳見下文

)。*/returnTRUE;}說明:CDocManager類是一個(gè)不公開的類,他主要用來管理多文檔模板對(duì)象的,關(guān)于單文檔只有一個(gè)文檔模板這個(gè)類不是很重要,但還是用它管理文檔模板的;本文只在相關(guān)之處作說明。bStaticInit是它的一個(gè)靜態(tài)成員。第三章InitInstance( )函數(shù)它一般被重載,在First工程中,InitInstance中和文檔視圖類相關(guān)的程序有下邊的一些:CSingleDocTemplate*pDocTemplate;定義指針pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CFirstDoc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CFirstView));這條語(yǔ)句的作用見第一段AddDocTemplate(pDocTemplate);CCommandLineInfocmdInfo;定義一個(gè)對(duì)象ParseCommandLine(cmdInfo);///分析命令行并發(fā)送參數(shù),與文檔視圖沒關(guān)if(!ProcessShellCommand(cmdInfo))這是最重要的詳見的三段returnFALSE;m_pMainWnd->ShowWindow(SW_SHOW);顯示窗口m_pMainWnd->UpdateWindow( );第一節(jié):newCSingleDocTemplatenewCSingleDocTemplate其實(shí)就是創(chuàng)立一個(gè)CSingleDocTemplate對(duì)象并調(diào)用他的構(gòu)造函數(shù),要講清楚這句話,第一一定理解RUNTIME_CLASS構(gòu)造,RUNTIME_CLASS構(gòu)造定義以下:#defineRUNTIME_CLASS(class_name)((CRuntimeClass*)(&class_name::class##class_name))于是這句話睜開后以下(關(guān)于吻合##的詳細(xì)意義拜見MSDN):pDocTemplatenewCSingleDocTemplate(IDR_MAINFRAME,(CRuntimeClass*)(&CFirstDoc::classCFirstDoc),(CRuntimeClass*)(&CMainFrame::classCMainFrame),(CRuntimeClass*)(&CFirstView::classCFirstView));這時(shí)我們會(huì)發(fā)現(xiàn)CfirstDoc,CmainFrame,CfirstView各會(huì)多冒出一個(gè)靜態(tài)成員出來,它終歸在哪里呢?查察這三個(gè)類的定義我們會(huì)發(fā)現(xiàn)每個(gè)類定義都有一個(gè)宏DECLARE_DYNCREATE,在實(shí)現(xiàn)文件中有別的一個(gè)宏IMPLEMENT_DYNCREATE。下邊把這些宏的睜開狀況列出以下:(1)文檔類DECLARE_DYNCREATE(CFirstDoc)睜開后為:public:staticconstCRuntimeClassclassCFirstDoc;這就是上邊所說的那個(gè)靜態(tài)成員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);}這些宏第一在你的定義文件中定義一個(gè)以class+類名為名字的靜態(tài)變量。而后定義一個(gè)返回這個(gè)靜態(tài)變量的函數(shù)GetRuntimeClass并在實(shí)現(xiàn)文件中實(shí)現(xiàn)之。最后定義并實(shí)現(xiàn)一個(gè)創(chuàng)立對(duì)象的函數(shù)CreateObject。好了,我們此刻就來看看CSingleDocTemplate對(duì)象的構(gòu)造函數(shù)做了些什么:下邊是他的實(shí)現(xiàn)CSingleDocTemplate::CSingleDocTemplate(UINTnIDResource,CRuntimeClass*pDocClass,CRuntimeClass*pFrameClass,CRuntimeClass*pViewClass)CDocTemplate(nIDResource,pDocClass,pFrameClass,pViewClass){m_pOnlyDoc=NULL;}它主若是初始化他的父類CDocTemplate,CDocTemplate做了些什么?以下:{把資源

ID

及文檔、框架、視圖的三個(gè)

CRuntimeClass

構(gòu)造的靜態(tài)成員的地址

(也就是傳進(jìn)來的四個(gè)參數(shù)

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

為指定的文檔模板對(duì)象裝載資源}至此這個(gè)

new

語(yǔ)句總算講完了。第二節(jié):

AddDocTemplate(pDocTemplate);下邊是他的實(shí)現(xiàn)函數(shù)voidCWinApp::AddDocTemplate(CDocTemplate*pTemplate){if(m_pDocManager==NULL)m_pDocManager=newCDocManager;/*創(chuàng)立一個(gè)文檔管理類,關(guān)于單文檔常常只有一個(gè)文檔模板用CDocManager類其實(shí)不是很重要,我們可以忽視這句*/m_pDocManager->AddDocTemplate(pTemplate);/*把文檔模板指針保存在CDocManager實(shí)例中由CDocManager去管理他,我們只需知道有這個(gè)事就行了*/}第三節(jié):ProcessShellCommand(cmdInfo)這個(gè)函數(shù)發(fā)送的一個(gè)命令就是FileNew其余的臨時(shí)不論他,其實(shí)全部的文檔類,框架類,視圖類都是在這個(gè)函數(shù)中創(chuàng)立的,在第一段中已經(jīng)講到應(yīng)用程序類將上三個(gè)類的CRuntimeClass一個(gè)靜態(tài)成員地址保存起來了,關(guān)于CRuntimeClass構(gòu)造的詳細(xì)功能參照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( );///不過調(diào)用CDocManager::OnFileNew}文檔管理類的OnFileNew去掉一些沒用的東西后實(shí)現(xiàn)以下:voidCDocManager::OnFileNew( ){CDocTemplate*pTemplate=(CDocTemplate*)m_templateList.GetHead( );/*獲取第一個(gè)文檔模板,關(guān)于單文檔只有一個(gè)文檔模板*/if(m_templateList.GetCount( )>1)///對(duì)單文檔這段沒用{CNewTypeDlgdlg(&m_templateList);intnID=dlg.DoModal( );if(nID==IDOK)pTemplate=dlg.m_pSelectedTemplate;elsereturn;///none-canceloperation}pTemplate->OpenDocumentFile(NULL);/*實(shí)際上是調(diào)用CSingleDocTemplate::OpenDocumentFile函數(shù)下邊祥述這里,由于在CDocTemplate類中這個(gè)函數(shù)是一個(gè)純虛函數(shù)*/}下邊簡(jiǎn)述pTemplate->OpenDocumentFile(NULL);這個(gè)函數(shù),這是最重要的一個(gè)函數(shù),他執(zhí)行了以下6個(gè)步驟:pDocument=CreateNewDocument( );///創(chuàng)立一個(gè)新文檔{CDocument*pDocument=(CDocument*)m_pDocClass->CreateObject( );/*這是才真切的創(chuàng)立文檔對(duì)象,這里創(chuàng)立的文檔對(duì)象就是上邊RUNTIME_CLASS(CFirstDoc),中的對(duì)象這是MFC開發(fā)人員想出來的一種運(yùn)轉(zhuǎn)時(shí)創(chuàng)立對(duì)象的方法,應(yīng)當(dāng)說比較不錯(cuò)的,不知道C++Builder的是如何構(gòu)造的。*/AddDocument(pDocument);///把創(chuàng)立的對(duì)象指針記錄下來,此后還要用的。}pFrame=CreateNewFrame(pDocument,NULL);/*依據(jù)新文檔指針創(chuàng)立新文檔框架,這個(gè)比較重要下一段描述*/SetDefaultTitle(pDocument);設(shè)置缺省標(biāo)題,不重要的pDocument->OnNewDocument( )除去老文檔內(nèi)容{DeleteContents( );刪除本來的內(nèi)容而不論能否存盤SetModifiedFlag(FALSE);除去以前修悔悟的標(biāo)志}pThread->m_pMainWnd=pFrame;框架窗口作為的指針作為主窗口的指針I(yè)nitialUpdateFrame(pFrame,pDocument,bMakeVisible);/*使框架中的視圖窗口接遇到OnInitialUpdat的調(diào)用,并作原始更新。*/至此第一段的OnFileNew函數(shù)總算講完。下邊講CreateNewFrame函數(shù)CreateNewFrame是CDocTemplate的成員函數(shù)以下3個(gè)步驟:CCreateContextcontext;創(chuàng)立CcreateContext對(duì)象.也就是我們重載LoadFrame函數(shù)的那個(gè)CcreateContext的本源*/context.m_pCurrentFrame=pOther;///保存當(dāng)前框架,一般為NULLcontext.m_pCurrentDoc=pDoc;保存文檔對(duì)象指針context.m_pNewViewClass=m_pViewClass;保存視圖對(duì)象指針context.m_pNewDocTemplate=this;保存文檔模板的指針。CFrameWnd*pFrame=(CFrameWnd*)m_pFrameClass->CreateObject( );真切創(chuàng)立框架的對(duì)象pFrame->LoadFrame(m_nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,NULL,&context)加載資源,這是最重要的,下邊表達(dá){GetIconWndClass(dwDefaultStyle,nIDResource)///加載資源并注冊(cè)窗口{AfxFindResourceHandle::LoadIcon加載光標(biāo)資源CREATESTRUCTcs;///創(chuàng)立一個(gè)CREATESTRUCT構(gòu)造實(shí)例PreCreateWindow(cs);/*調(diào)用窗口預(yù)創(chuàng)立函數(shù),這個(gè)函數(shù)我們可以重載的依據(jù)cs調(diào)用AfxRegisterWndClass注冊(cè)框架窗口*/}Create( )創(chuàng)立框架窗口,后邊祥述,此處臨時(shí)不講。m_hMenuDefault=::GetMenu(m_hWnd);獲取并保存菜單句柄LoadAccelTable(MAKEINTRESOURCE(nIDResource));裝載加快鍵表}下邊講Create函數(shù),以下4個(gè)步驟:hMenu=::LoadMenu(hInst,lpszMenuName);///加載菜單CREATESTRUCTcs;///創(chuàng)立一個(gè)CREATESTRUCT構(gòu)造實(shí)例cs.lpCreateParams=lpParam;///(此時(shí)的lpParam就是建的context對(duì)象指針)PreCreateWindow(cs);調(diào)用窗口預(yù)創(chuàng)立函數(shù),這個(gè)函數(shù)我們可以重載的,又調(diào)用一次調(diào)用API函數(shù)::CreateWindowEx真切創(chuàng)立框架窗口,創(chuàng)立過程中會(huì)發(fā)出WM_CREATE和WM_NCCREATE等信息。下邊講接收WM_CREATE信息的信息辦理函數(shù)CMainFrame::OnCreate,其余信息不重要CMainFrame::OnCreate最重要的是調(diào)用CFrameWnd::OnCreateHelper函數(shù)以

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論