任何程序都有一個入口函數(shù),我們在學(xué)習(xí)C語言的時候入口函數(shù)是main函數(shù),學(xué)習(xí)Win32也是有main函數(shù)的,Win32的入口函數(shù)是_tWinMain(),因為MFC對Win32API進(jìn)行了封裝,所以在MFC的代碼中我們是找不到_tWinMain()入口函數(shù)的,這增加了我們學(xué)習(xí)MFC的難度,很多同學(xué)都不知道程序是從哪里開始運(yùn)行的,為了解決這個問題,我通過設(shè)置斷點的方式,一步一步跟蹤代碼的執(zhí)行,分析出了MFC整體的運(yùn)行流程。
首先我使用VisualStudio2010提供的搜索功能搜索_tWinMain(),注意這里搜索的路徑不能是當(dāng)前工程路徑,當(dāng)前工程路徑里的文件是找不到的,必須是在安裝目錄里的VC庫里去搜索,如圖11示: 不管MFC怎么進(jìn)行封裝,它的原理還是和Win32一樣的,所以在庫里里面搜索一定可以找到我們需要的_tWinMain函數(shù),圖13示 可以看到,搜索結(jié)果中第一個就是我們要找的函數(shù)。進(jìn)入這個函數(shù)之后,設(shè)置一個斷點,然后調(diào)試整個程序,可以看到程序果然運(yùn)行到斷點處,圖14示 從_tWinMain函數(shù)內(nèi)部我們發(fā)現(xiàn),里面只有一句代碼:returnAfxWinMain(hInstance,hPrevInstance, lpCmdLine, nCmdShow);也就是說MFC使用AfxWinMain替代了_tWinMain函數(shù),原來的_tWinMain函數(shù)實際上是沒有任何用處的,我們繼續(xù)跟蹤,圖15示 在AfxWinMain內(nèi)部我們終于看見我們熟悉的InitInstance()函數(shù)了,其中里面的類都是通過繼承和多態(tài)的特性進(jìn)行工作的,CWinApp繼承CWinThread類,我們新建的類CDemoADOApp繼承CWinApp,任何應(yīng)用程序只有一個CWinApp類,在CWinThread的成員函數(shù)中有InitInstance、Run、ExitInstance三個主要的函數(shù),且這三個函數(shù)都是虛函數(shù),我們的類CDemoADOApp通過繼承CWinApp類,重寫InitInstance和ExitInstance函數(shù),根據(jù)面向?qū)ο蟮亩鄳B(tài)性,當(dāng)執(zhí)行pThread->InitInstance()這一句代碼時執(zhí)行的函數(shù)不再是CWinThread或CWinApp里的InitInstance,而是CDemoADOApp類的InitInstance,我們通過調(diào)試工具進(jìn)入InitInstance內(nèi)部,圖16示 可以發(fā)現(xiàn),程序果然跳轉(zhuǎn)到CDemoADOApp類的InitInstance()里面,在InitInstance()里面我們可以對我們的應(yīng)用程序做初始化工作,當(dāng)需要的配置都做好之后,退出InitInstance函數(shù),再次回到AfxWinMain函數(shù),接下來程序就會執(zhí)行Run函數(shù),等待消息響應(yīng)。圖17示 Win32采用的是消息循環(huán)的機(jī)制,通過捕捉應(yīng)用程序上所有消息,識別之后送到相應(yīng)的消息處理函數(shù)去處理操作,MFC也是基于這個機(jī)制,不過MFC使用的是消息映射與反射,就是將消息與處理函數(shù)通過制定宏建立聯(lián)系,歸根到底也是和Win32原理一樣。 調(diào)試跟蹤到這里,程序的整體脈絡(luò)也大體清晰了,簡單來講AfxWinMain函數(shù)內(nèi)部就執(zhí)行三個函數(shù)InitInstance、Run、ExitInstance,InitInstance初始化,Run循環(huán)等待消息并執(zhí)行相應(yīng)處理程序,ExitInstance在程序結(jié)束之后做收尾工作,如釋放資源等。 我認(rèn)為學(xué)習(xí)VC++最重要的是弄清楚MFC的運(yùn)行機(jī)制,弄清楚MFC的運(yùn)行機(jī)制之前先要明白Win32又是怎么工作的,只要明白了Win32的工作流程,理解MFC就會變得簡單很多了,至于其它的開發(fā),都是基于這個運(yùn)行機(jī)制,所以調(diào)試分析我沒有對其他窗口的實現(xiàn)進(jìn)行分析,而是著重分析了應(yīng)用程序的執(zhí)行流程。
|