版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第三講MFC框架程序剖析2/5/2023MFC框架程序剖析內(nèi)容安排什么是MFC框架程序?
MFC的程序框架剖析(運(yùn)行脈絡(luò))
MFC框架程序仿真2/5/20232MFC框架程序剖析什么是MFC框架程序?MFC框架程序是利用MFCAppWizard生成的Windows應(yīng)用程序。MFCAppWizard是一個輔助我們生成源代碼的向?qū)Чぞ?,它可以幫助我們自動生成基于MFC框架的源代碼。該向?qū)У拿恳粋€步驟中,我們都可以根據(jù)需要來選擇各種特性,從而實現(xiàn)定制應(yīng)用程序。實踐:利用MFCAppWizard創(chuàng)建一個基于MFC的“單文檔界面(SDI)”應(yīng)用程序。2/5/20233MFC框架程序剖析MFC單文檔界面程序初探頭文件——類定義、類成員函數(shù)聲明stdafx.h、test.h、MainFrm.h、testDoc.h、testView.h、Resource.h源文件——類函數(shù)實現(xiàn)stdafx.cpp、test.cpp、MainFrm.cpp、testDoc.cpp、testView.cpp、test.rc資源文件——圖標(biāo)、菜單項、鼠標(biāo)形狀等資源test.ico、test.rc2、testDoc.ico、toolbar.bmp2/5/20234MFC框架程序剖析MFC單文檔界面程序初探(續(xù))
stdafx.h、stdafx.cppstdafx.h中包含了使用MFC的常備頭文件,包括:afxwin.h——每一個WindowsMFC程序都必須載入它,它以及它載入的文件申明了所有的MFC類。afxext.h——凡使用工具欄、狀態(tài)欄的程序必須載入這個文件。afxdisp.h——凡使用通用對話框的MFC的程序需載入該文件。afxdtctl.h——支持IE4的常用控件。afxcmn.h——凡使用Windows9x新增的通用型控件的MFC程序需載入此文件。2/5/20235MFC框架程序剖析MFC單文檔界面程序初探(續(xù))
test.h、test.cpp管理和維護(hù)主應(yīng)用程序類CTestApp(由CWinApp繼承而來),每一個MFC程序有且僅有一個主應(yīng)用程序類對象theApp,它代表一個程序本體。
MainFrm.h、MainFrm.cpp管理和維護(hù)主框架類CMainFrame(由CWnd繼承而來),主框架是應(yīng)用程序的主體窗口,其他的窗口(如視類窗口、工具條、狀態(tài)條)都依附于主框架窗口(覆蓋在它上面)。2/5/20236MFC框架程序剖析MFC單文檔界面程序初探(續(xù))
testView.h、testView.cpp管理和維護(hù)視圖類CTestView(由CWnd繼承而來),負(fù)責(zé)顯示的部分。
testDoc.h、testDoc.cpp文檔類CTestDoc(由CDocumet繼承而來),負(fù)責(zé)顯示數(shù)據(jù)的后臺管理和維護(hù)。2/5/20237MFC框架程序剖析內(nèi)容安排什么是MFC框架程序?
MFC框架程序剖析(運(yùn)行脈絡(luò))
MFC框架程序仿真2/5/20238MFC框架程序剖析WindowsAPI程序回顧程序入口WinMain設(shè)計注冊窗口類RegisterClass創(chuàng)建窗口CreateWindow顯示/更新窗口ShowWindow消息循環(huán)GetMessage窗口過程WindowProc2/5/20239MFC框架程序剖析問題的提出與WindowsAPI程序相比,MFC程序無執(zhí)行路徑、無條理、不知如何處理消息,有點(diǎn)“見林不見樹”的味道:
問題一:看不到WinMain,因此不知道程序從哪里開始執(zhí)行。
問題二:看不到RegisterClass和CreateWindow,那么窗口是如何做出來的呢?
問題三:看不到消息循環(huán)(GetMessage/DispathMessage),那么程序如何推動?
問題四:看不到窗口過程WindowProcedure,那么窗口消息響應(yīng)如何執(zhí)行?本節(jié)的目的就是要鏟除這些疑惑,把上述看不到的東西給挖出來。2/5/202310MFC框架程序剖析①M(fèi)FC中的全局對象theApp初始化CTestAPP對象,應(yīng)用程序內(nèi)存獲得配置調(diào)用基類CWinApp構(gòu)造函數(shù)(在MFC源碼目錄的文件中AppCore.cpp),用于程序運(yùn)行時的一些初始化工作。注意:由于theApp是個全局對象,所以CWinApp構(gòu)造函數(shù)會在入口函數(shù)WinMain之前運(yùn)行。2/5/202311MFC框架程序剖析②MFC中的WinMain函數(shù)文件AppModul.cpp中能找到WinMain入口函數(shù):extern"C"intWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance, LPTSTRlpCmdLine,intnCmdShow){ //callshared/exportedWinMain returnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);}至此,問題一得以解決!(找到WinMain)2/5/202312MFC框架程序剖析AfxWinMain函數(shù)AfxWinMain的定義在WinMain.cpp中intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance, LPTSTRlpCmdLine,intnCmdShow){….. CWinThread*pThread=AfxGetThread(); CWinApp*pApp=AfxGetApp(); //Appglobalinitializations(rare) if(pApp!=NULL&&!pApp->InitApplication()) gotoInitFailure; //Performspecificinitializations if(!pThread->InitInstance())//CWinApp的虛函數(shù),實際執(zhí)行的是CTestApp中的InitInstance()函數(shù)。窗口對象就在這個函數(shù)內(nèi)部產(chǎn)生。 {…… } nReturnCode=pThread->Run();//消息循環(huán)……}2/5/202313MFC框架程序剖析③CTestApp::InitInstance()函數(shù)BOOLCTestApp::InitInstance()//Test.cpp中{…… if(!ProcessShellCommand(cmdInfo))//new一個CMainFrame對象 returnFALSE; m_pMainWnd->ShowWindow(SW_SHOW);//顯示主框架窗口 m_pMainWnd->UpdateWindow();//更新主框架窗口 returnTRUE;}注:ProcessShellCommand(cmdInfo)會new一個主框類對象,從而調(diào)用主框類函數(shù)CFrameWnd::LoadFrame()2/5/202314MFC框架程序剖析④CFrameWnd::LoadFrame函數(shù)CFrameWnd::LoadFrame的定義在WinFrm.cpp中BOOLCFrameWnd::LoadFrame(UINTnIDResource,DWORDdwDefaultStyle, CWnd*pParentWnd,CCreateContext*pContext){……VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));……if(!Create(lpszClass,lpszTitle,dwDefaultStyle,rectDefault, pParentWnd,MAKEINTRESOURCE(nIDResource),0L,pContext)){returnFALSE;//willselfdestructonfailurenormally}……}2/5/202315MFC框架程序剖析LoadFrame函數(shù)(續(xù))CFrameWnd::LoadFrame中的AfxDeferRegisterClass函數(shù)會調(diào)用API函數(shù)::RegisterClass()來注冊主框架窗口。
至此,問題二的窗口類注冊問題得以解決!(找到RegisterClass)CFrameWnd::LoadFrame中的Create函數(shù)會調(diào)用基類的窗口創(chuàng)建函數(shù)CWnd::CreateEx()。
2/5/202316MFC框架程序剖析⑤CWnd::CreateExCWnd::CreateEx
的定義在WinCore.cpp中在CreateEx函數(shù)內(nèi)部:首先會調(diào)用PreCreateWindow(cs)函數(shù),給設(shè)計人員一個更改窗口風(fēng)格的機(jī)會。然后調(diào)用API函數(shù)::CreateWindowEx創(chuàng)建窗口至此,問題二的窗口類創(chuàng)建問題得以解決?。ㄕ业紺reateWindowEx)2/5/202317MFC框架程序剖析⑥CWinThread::RunCWinThread::Run()的定義在ThrdCore.cpp中intCWinThread::Run(){ ……
do { //pumpmessage,butquitonWM_QUIT if(!PumpMessage()) returnExitInstance();
}…….. ASSERT(FALSE);//notreachable}2/5/202318MFC框架程序剖析PumpMessage()PumpMessage()的定義在ThrdCore.cpp中BOOLCWinThread::PumpMessage(){…… if(m_msgCur.message!=WM_KICKIDLE&&!PreTranslateMessage(&m_msgCur)) {
::TranslateMessage(&m_msgCur); ::DispatchMessage(&m_msgCur); } returnTRUE;}至此,問題三的消息循環(huán)問題得以解決2/5/202319MFC框架程序剖析消息映射消息是Windows程序的血液,Windows程序靠消息的流動而維護(hù)生命。在WindowsAPI程序當(dāng)中,消息的處理方法是在窗口函數(shù)中借助一個大大的switch/case比較操作,判別消息,再執(zhí)行對應(yīng)的處理代碼。在MFC中,為了讓大大的switch/case比較操作簡化,也讓程序代碼模塊化,MFC采用了一種“MessageMapping”(消息映射表)的做法,把消息和其處理程序關(guān)聯(lián)起來。2/5/202320MFC框架程序剖析MessageMapping的基本原理首先定義一個MSGMAP_ENTRY結(jié)構(gòu)structMSGMAP_ENTRY{UNITnMessage;LONG(*pfn)(HWND,UNIT,WPARAM,LPARAM);};注意:pfn是一個函數(shù)指針,而該指針?biāo)傅暮瘮?shù)處理nMessage消息。這正是面向?qū)ο笥^念中把“數(shù)據(jù)”和“處理數(shù)據(jù)的方法”封裝起來的一種具體實現(xiàn)。2/5/202321MFC框架程序剖析MessageMapping的基本原理(續(xù))接下來,組織一個MSGMAP_RNTRY結(jié)構(gòu)的數(shù)組_messageEntries[],把程序終欲處理的若干消息以及消息處理函數(shù)的關(guān)聯(lián)性建立起來:structMSGMAP_ENTRY
_messageEntries[]={WM_CREATE,OnCreate,WM_PAINT,OnPaint,WM_SIZE,OnSize,WM_COMMAND,OnCommandWM_CLOSE,OnColse……};消息消息處理函數(shù)2/5/202322MFC框架程序剖析MessageMapping的基本原理(續(xù))于是窗口函數(shù)可以這么寫:LRESULTCALLBACKMyWndProc(HWNDhwnd,UINTuMsg,WPARAMwParam,LPARAMlParam){for(inti=0;i<sizeof(_messageEntries);i++) { if(message==_messageEntries[i].nMessage)return((*_messageEntries[i].pfn)(hwnd,nMsg,wParam,lParam)}}這么一來,窗口過程函數(shù)WndProc永遠(yuǎn)不必改變,每當(dāng)有新的要處理的消息,只要在_messageEntries[]數(shù)組中加上新的數(shù)組元素,并針對新消息寫新的處理函數(shù)就OK了。2/5/202323MFC框架程序剖析MFC框架程序中是如何實現(xiàn)消息映射操作的呢?舉例:在MFC框架程序中為視類增加一個鼠標(biāo)左鍵按下消息。在源文件中會增加三處代碼:(1)消息響應(yīng)函數(shù)原型(作為類成員函數(shù),在類h頭文件中聲明)(2)消息映射宏(CPP源文件)(3)消息響應(yīng)函數(shù)定義(在類CPP源文件實現(xiàn)該消息響應(yīng)函數(shù))在MFC框架程序中,消息映射通過消息映射宏來實現(xiàn)消息映射的操作。2/5/202324MFC框架程序剖析消息映射宏BEGIN_MESSAGE_MAP(CTestView,CView)
//{{AFX_MSG_MAP(CTestView)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP //Standardprintingcommands……END_MESSAGE_MAP()其中BEGIN_MESSAGE_MAP和END_MESSAGE_MAP這兩個宏之間定義了CTestView類的消息映射表,即前面所講的_messageEntries[]數(shù)組;而ON_WM_LBUTTONDOWN()這個宏的作用是在_messageEntries[]數(shù)組中添加一個消息映射元素,把WM_LBUTTONDOWN消息與OnLButtonDown函數(shù)關(guān)聯(lián)起來。通過這種機(jī)制,一旦有消息產(chǎn)生,程序就會調(diào)用相應(yīng)的消息響應(yīng)函數(shù)來進(jìn)行處理。2/5/202325MFC框架程序剖析內(nèi)容安排什么是MFC框架程序?
MFC框架程序剖析(運(yùn)行脈絡(luò))
MFC框架程序仿真2/5/202326MFC框架程序剖析MFC框架程序仿真為什么要仿真?MFC太過龐大,我們必須撇開枝節(jié),把重點(diǎn)凸現(xiàn)出來,才容易領(lǐng)略到MFC框架程序的設(shè)計方式
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 柜臺出租經(jīng)營合同
- 權(quán)許可合同電影發(fā)行協(xié)議
- 航運(yùn)業(yè)勞務(wù)派遣合同及注意事項
- 智能交通系統(tǒng)建設(shè)合作框架協(xié)議
- 基于大數(shù)據(jù)的智能倉儲管理方案
- 企業(yè)內(nèi)部知識管理和知識共享平臺建設(shè)
- 人力資源行業(yè)招聘流程優(yōu)化及人才管理方案
- 智能建筑服務(wù)合同
- 地下工程旋挖樁施工合同模板
- 建筑工地土方作業(yè)協(xié)議書
- 在小學(xué)語文教學(xué)中彰顯人文情懷 人文情懷
- 急性呼吸衰竭的診斷和處理
- GB/T 337.1-2014工業(yè)硝酸濃硝酸
- 小學(xué)語文課程標(biāo)準(zhǔn)(2023年版)
- GB/T 13738.2-2017紅茶第2部分:工夫紅茶
- 涉稅風(fēng)險防范課件
- 《小英雄雨來》閱讀測試題附答案
- 應(yīng)用PDCA降低抗生素的使用率及使用強(qiáng)度課件
- DB31T 1238-2020 分布式光伏發(fā)電系統(tǒng)運(yùn)行維護(hù)管理規(guī)范
- 分包計劃范文
- 個人住房質(zhì)押擔(dān)保借款合同書范本(3篇)
評論
0/150
提交評論