




已閱讀5頁,還剩2頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
MFC源程序設(shè)計-計算機(jī)安全 MFC源程序設(shè)計MFC程序設(shè)計之來龍去脈(),到后來就沒有再管了,其實(shí)那只是冰山一角.具體MFC是怎么運(yùn)行的,還是沒有交待清楚。說明:1、本文作者在VS2003中跟蹤代碼,此代碼為VS2003中拷貝,使用MFC7。 2、不同框架的MFC程序由所不同,本文以單文檔為例。 3、本文讀者需要有一定的SDK的基礎(chǔ),不需要太多,至少知道它的基本框架和來龍去脈即可! 4、文章只想起到說明作用,所以代碼會有一些刪除。學(xué)MFC,竟然還不知道MFC的MAIN函數(shù)在什么地方?怎么運(yùn)行的?實(shí)在不高明??催^候捷(JJHOU)老師的深入淺出MFC的,對它一定很熟悉。呵呵,本文是獻(xiàn)給沒有看過那本書,但是又很希望學(xué)習(xí)MFC程序設(shè)計的朋友的。(沒有看過那本書的朋友還不趕快去買?)其實(shí)本文,主要是對深入淺出MFC第六章的一個總結(jié)和補(bǔ)充罷了?。ū疚挠性摃煌牡胤?,也有一些筆者自己的見解?。┭詺w正傳。假如你用AppWizard一步一步NEXT下來,然后在CLASSVIEW中去找尋WINMAIN函數(shù),那么你只有失望。MFC最大的特點(diǎn)是什么?封裝!MFC的確封裝的太好了,以至于很多想學(xué)習(xí)MFC的人都望而卻步。閑話少說,還是繼續(xù)我們今天的話題,MAIN函數(shù)!實(shí)話告訴你吧,即使你搜索所有的MFC生成的文件,都無法發(fā)現(xiàn)WINMAIN的字眼,那么它就近在什么地方呢?我相信你已經(jīng)想到,MAIN函數(shù)應(yīng)該在主要的應(yīng)用程序文件中。難道是“您定義的程序名.cpp”這個文件?不錯就是它。再Crtl+F一下,看有沒有我們要找的WINMAIN函數(shù)?看來你又要失望了,但是你注意有這樣一句:/ The one and only CMyApp object CMyApp theApp; /本人建立的工程名為My。是不是很特別,再注意一下那句注釋“The one and only CMyApp object”,每個應(yīng)用程序有且只用一個CMyApp對象。我想你應(yīng)該想到了,WinMain函數(shù)每個程序也只能有一個,那么這個全局對象跟WinMain函數(shù)肯定有莫大的關(guān)系?沒錯,相信你的直覺。特別注意:深曉C+細(xì)節(jié)的人一定知道,全局對象優(yōu)先于MAIN函數(shù)執(zhí)行的道理。如果你不知道也沒關(guān)系,那么我在這里告訴你:“全局對象優(yōu)先于MIAN函數(shù)執(zhí)行,且構(gòu)建于棧中,切記,切記!”現(xiàn)在,我們該深入WinMain運(yùn)行機(jī)制了,確切的說,應(yīng)該是MFC的機(jī)制!首先,看看MFC的庫文件把,它能給我們帶來許多驚喜。(vc6的相應(yīng)的目錄是Microsoft Visual StudioVC98MFCSRC;VC7相應(yīng)的目錄是Microsoft Visual Studio .NET 2003Vc7atlmfcsrcmfc)現(xiàn)在我們就從這個全局下手,開始今天的旅途。CMyApp theApp; 此時,系統(tǒng)會執(zhí)行CMyApp的父類(CWinApp)構(gòu)造函數(shù),再執(zhí)行CMyApp的構(gòu)造函數(shù)。(先有老爹,再有兒子?。?,此時就會調(diào)用CWinApp的構(gòu)造函數(shù)。CWinApp的構(gòu)造函數(shù)(在VC提供的MFC代碼中以“文中的一個字或詞組”的方式查詢關(guān)鍵字,此時打開APPCORE.CPP,以下使用相同搜索方式,不再復(fù)述。)找到以下內(nèi)容:CWinApp:CWinApp(LPCTSTR lpszAppName) if (lpszAppName != NULL) m_pszAppName = _tcsdup(lpszAppName); else m_pszAppName = NULL; / initialize CWinThread state AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); AFX_MODULE_THREAD_STATE* pThreadState = pModuleState-m_thread; ASSERT(AfxGetThread() = NULL); pThreadState-m_pCurrentWinThread = this; ASSERT(AfxGetThread() = this); m_hThread = :GetCurrentThread(); m_nThreadID = :GetCurrentThreadId(); / initialize CWinApp state ASSERT(afxCurrentWinApp = NULL); / only one CWinApp object please pModuleState-m_pCurrentWinApp = this; ASSERT(AfxGetApp() = this);. .OK,就到這里就可以了,仔細(xì)看上面代碼,它已經(jīng)完成了應(yīng)用程序線程額的啟動,它給予了我們程序的生命。現(xiàn)在請注意: pThreadState-m_pCurrentWinThread = this;pModuleState-m_pCurrentWinApp = this; 這兩行代碼其實(shí)都是做的一件事兒。 這段代碼的意思是,獲得了CMyApp的全局對象的this指針。(此時你肯定要疑問,為什么是CMyApp的指針?this目前是在CWinApp中??? 對此我的答案是,可是你是由CMyApp的對象引發(fā)的CWinApp的構(gòu)造啊!)這個指針可非一般的人物,稍后我們的很多工作都要靠它完成。 CWinApp之中的成員變量將因?yàn)閠heApp這個全局對象的誕生而獲得配置和初始值。 構(gòu)造完父類,現(xiàn)在構(gòu)造子類??墒俏覀兛吹?,AppWizard給我們的子類里它什么也沒做?是的,這一切都聽從你的安排! CMyApp:CMyApp() / TODO: add construction code here,/ Place all significant initialization in InitInstance 接下來就是今天的主角兒了,搜索關(guān)鍵字“WinMain”,出現(xiàn)很多文件。別急,因?yàn)楝F(xiàn)在我們應(yīng)該先看看WinMain的聲明。打開appmodul.cpp: _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)/ call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);這里_tWinMain是為了支持UNICODE而命名的一個宏,真正起作用的是AfxWinMain,注意看看它的參數(shù),是不是和SDK的WinMain函數(shù)一樣?現(xiàn)在再搜索下AfxWinMain,其實(shí)在winmain.cpp中:int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)ASSERT(hPrevInstance = NULL);int nReturnCode = -1;CWinThread* pThread = AfxGetThread();CWinApp* pApp = AfxGetApp();/ AFX internal initializationif (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow) goto InitFailure;/ App global initializations (rare)if (pApp != NULL & !pApp-InitApplication() goto InitFailure;/ Perform specific initializationsif (!pThread-InitInstance() if (pThread-m_pMainWnd != NULL) TRACE(traceAppMsg, 0, Warning: Destroying non-NULL m_pMainWndn); pThread-m_pMainWnd-DestroyWindow(); nReturnCode = pThread-ExitInstance(); goto InitFailure;nReturnCode = pThread-Run();. .此段代碼注意五個細(xì)節(jié):CWinApp* pApp = AfxGetApp(); 意為獲得對象指針,其實(shí)就是剛才那個THIS。不記得了?指向CMyApp的那個!還值得注意的是,Afx意是全局的,隨時你都可以調(diào)用它。(AFX就是MFC開發(fā)小組的開發(fā)代號,意為Application Framework 傳說X只是為了好看,沒實(shí)在意思?!)if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)AfxWinInit完成了線程的初始化和窗框類的注冊。具體參看appinit.cpp中的定義。if (pApp != NULL & !pApp-InitApplication()其實(shí)pApp和pThread是同一個指針,都是指向CMyApp的指針,這里因?yàn)镃MyApp中沒有定義InitApplication,實(shí)際上就調(diào)用的CWinApp:InitApplication(),完成了MFC的內(nèi)容管理。if (!pThread-InitInstance()因?yàn)镃MyApp中改寫了它,所以調(diào)用CMyApp中的,其實(shí)它也是初始化工作。此時也完成了默認(rèn)窗口類的定義。假如你熟悉SDK編程的話,一定不會忘記窗口類的設(shè)計、注冊、創(chuàng)建、現(xiàn)實(shí)及更新的步驟,此時MFC以為你設(shè)計好了默認(rèn)的窗口類?,F(xiàn)在你不禁要疑問,InitApplication()和InitInstance()有何不同?答案是,假如你執(zhí)行一個程序,于是兩個函數(shù)都會被調(diào)用;當(dāng)你在不關(guān)閉前一個程序的前提下,再執(zhí)行一個程序,那么就只執(zhí)行后一個函數(shù)。nReturnCode = pThread-Run();這個一步驟在深入淺出MFC中被成為程序的活水源頭,在我看來它就是你開車踩油門的步驟。待會我們會具體闡述!在設(shè)計窗口類以后,就應(yīng)該是注冊,MFC自動調(diào)用(跳轉(zhuǎn)到)AfxEndDeferRegisterClass(WINCORE.CPP中),為你注冊了五個窗口類,分別是:AfxWnd,AfxCreateBar,AfxMDIFrame,AfxFrameOrView,AfxOleControl以上窗口類MFC將自動轉(zhuǎn)化成獨(dú)立無二的類名,供其調(diào)用。在窗口的注冊以后,就應(yīng)該是窗口的創(chuàng)建工作,此時會調(diào)用CFrameWnd:Create(),該代碼位于WINFRM.Cpp中BOOL CFrameWnd:Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName,DWORD dwStyle,const RECT& rect,CWnd* pParentWnd,LPCTSTR lpszMenuName,DWORD dwExStyle,CCreateContext* pContext)HMENU hMenu = NULL;if (lpszMenuName != NULL) / load in a menu that will get destroyed when window gets destroyed HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU); if (hMenu = :LoadMenu(hInst, lpszMenuName) = NULL) TRACE(traceAppMsg, 0, Warning: failed to load menu for CFrameWnd.n); PostNcDestroy(); / perhaps delete the C+ object return FALSE; m_strTitle = lpszWindowName; / save title for laterif (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd-GetSafeHwnd(), hMenu, (LPVOID)pContext) TRACE(traceAppMsg, 0, Warning: failed to create CFrameWnd.n); if (hMenu != NULL) DestroyMenu(hMenu); return FALSE;return TRUE;其中完成了窗口的創(chuàng)建工作,里面還涉及擴(kuò)展風(fēng)格的調(diào)用CreateEx,具體細(xì)節(jié)請參看MSDN。此時你不禁要問,我們的事兒都讓MFC做完了?工業(yè)化生產(chǎn)出來的窗口都是千篇一律啊,我要有我自己的風(fēng)格!別急,MFC給用戶提供了一個修改窗口設(shè)計的機(jī)會那就是:PreCreateWindow(CREATESTRUCT& cs) 你在MSDN中查詢一下CREATESTRUCT這個結(jié)構(gòu)體,你會發(fā)現(xiàn)它和我們的CreateWindow幾乎是一模一樣,這個就是MFC留給你修改窗口的一個機(jī)會。在PreCreateWindow時,會跳到CWnd:PreCreateWindow,里面有一個宏:AfxDeferRegisterClass,它的作用是:如果該窗口類沒有被注冊,那么就注冊它;如果注冊了,就什么也不管!窗口類的設(shè)計、注冊、創(chuàng)建都已經(jīng)完成,現(xiàn)在只剩下更新和顯示了。這些工作都交由 CMyApp:InitInstance()完成: m_pMainWnd-ShowWindow(SW_SHOW); m_pMainWnd-UpdateWindow();現(xiàn)在if (!pThread-InitInstance()的工作已經(jīng)完成,按照MAIN函數(shù)的內(nèi)容,接下來該:nReturnCode = pThread-Run()了此時應(yīng)該調(diào)用CMyApp的Run()函數(shù),但是在CMyApp類中,根本沒有聲明或定義這樣一個函數(shù),根據(jù)多態(tài)性的原則,指針遷升,指向CWinApp:Run(),其代碼位于APPCORE.CPP中:int CWinApp:Run() if (m_pMainWnd = NULL & AfxOleGetUserCtrl() / Not launched /Embedding or /Automation, but has no main window! TRACE(traceAppMsg, 0, Warning: m_pMainWnd is NULL in CWinApp:Run - quitting application.n); AfxPostQuitMessage(0); return CWinThread:Run();最后你會發(fā)現(xiàn),它又調(diào)用了一個CWinThread:Run(),此時你就看不到CWinThread:Run()的代碼了(至少筆者沒有找到,因?yàn)槲④浿惶峁┝瞬糠諱FC代碼。)但是你可以在MSDN中找到CWinThread:Run()的描述:Run 控制線程的函數(shù)。包含消息泵。一般不重寫。 再具體點(diǎn)就是:Run acquires and dispatches Windows messages
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 影像科CT技師上崗證真題與答案
- 游客行為分析優(yōu)化旅游服務(wù)
- 企業(yè)培訓(xùn)課件價值觀
- 企業(yè)培訓(xùn)技巧課件
- 英語全能閱讀強(qiáng)化練(十五)
- 優(yōu)化外資利用結(jié)構(gòu)改進(jìn)措施
- 企業(yè)培訓(xùn)車輛無償借用及管理合同
- 美容養(yǎng)生連鎖店按摩技師團(tuán)隊(duì)承包合同
- 高效采購合同談判策略與標(biāo)的物協(xié)議
- 彩票站與彩票代銷商代理合作協(xié)議
- 2025年北京市中考數(shù)學(xué)真題試卷及答案
- 北京昌平霍營街道社區(qū)“兩委”干部儲備人才招募筆試真題2024
- 1IEC62660-1中文電動道路車輛用二次鋰離子蓄電池鋰離子電池性能試驗(yàn)
- HPE 3PAR8400、HPE 3000B SAN Switch安裝及維護(hù)手冊
- 消防跑點(diǎn)培訓(xùn)材料
- 集料堿活性試驗(yàn)檢測記錄表(砂漿長度法)
- 汽輪機(jī)廠工業(yè)驅(qū)動技術(shù)介紹
- (完整版)漢密爾頓焦慮量表(HAMA)
- 梁平法識圖PPT通用通用課件
- 新概念英語第一冊單詞匯總打印版已排版
- 湘版高中音樂鑒賞《中國近現(xiàn)代通俗音樂》教學(xué)設(shè)計、實(shí)錄與反思
評論
0/150
提交評論