【精品論文】MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全_6892.doc_第1頁(yè)
【精品論文】MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全_6892.doc_第2頁(yè)
【精品論文】MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全_6892.doc_第3頁(yè)
【精品論文】MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全_6892.doc_第4頁(yè)
【精品論文】MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全_6892.doc_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

MFC源程序設(shè)計(jì)-計(jì)算機(jī)安全 MFC源程序設(shè)計(jì)MFC程序設(shè)計(jì)之來(lái)龍去脈(),到后來(lái)就沒(méi)有再管了,其實(shí)那只是冰山一角.具體MFC是怎么運(yùn)行的,還是沒(méi)有交待清楚。說(shuō)明:1、本文作者在VS2003中跟蹤代碼,此代碼為VS2003中拷貝,使用MFC7。 2、不同框架的MFC程序由所不同,本文以單文檔為例。 3、本文讀者需要有一定的SDK的基礎(chǔ),不需要太多,至少知道它的基本框架和來(lái)龍去脈即可! 4、文章只想起到說(shuō)明作用,所以代碼會(huì)有一些刪除。學(xué)MFC,竟然還不知道MFC的MAIN函數(shù)在什么地方?怎么運(yùn)行的?實(shí)在不高明。看過(guò)候捷(JJHOU)老師的深入淺出MFC的,對(duì)它一定很熟悉。呵呵,本文是獻(xiàn)給沒(méi)有看過(guò)那本書,但是又很希望學(xué)習(xí)MFC程序設(shè)計(jì)的朋友的。(沒(méi)有看過(guò)那本書的朋友還不趕快去買?)其實(shí)本文,主要是對(duì)深入淺出MFC第六章的一個(gè)總結(jié)和補(bǔ)充罷了!(本文有該書不同的地方,也有一些筆者自己的見(jiàn)解!)言歸正傳。假如你用AppWizard一步一步NEXT下來(lái),然后在CLASSVIEW中去找尋WINMAIN函數(shù),那么你只有失望。MFC最大的特點(diǎn)是什么?封裝!MFC的確封裝的太好了,以至于很多想學(xué)習(xí)MFC的人都望而卻步。閑話少說(shuō),還是繼續(xù)我們今天的話題,MAIN函數(shù)!實(shí)話告訴你吧,即使你搜索所有的MFC生成的文件,都無(wú)法發(fā)現(xiàn)WINMAIN的字眼,那么它就近在什么地方呢?我相信你已經(jīng)想到,MAIN函數(shù)應(yīng)該在主要的應(yīng)用程序文件中。難道是“您定義的程序名.cpp”這個(gè)文件?不錯(cuò)就是它。再Crtl+F一下,看有沒(méi)有我們要找的WINMAIN函數(shù)?看來(lái)你又要失望了,但是你注意有這樣一句:/ The one and only CMyApp object CMyApp theApp; /本人建立的工程名為My。是不是很特別,再注意一下那句注釋“The one and only CMyApp object”,每個(gè)應(yīng)用程序有且只用一個(gè)CMyApp對(duì)象。我想你應(yīng)該想到了,WinMain函數(shù)每個(gè)程序也只能有一個(gè),那么這個(gè)全局對(duì)象跟WinMain函數(shù)肯定有莫大的關(guān)系?沒(méi)錯(cuò),相信你的直覺(jué)。特別注意:深曉C+細(xì)節(jié)的人一定知道,全局對(duì)象優(yōu)先于MAIN函數(shù)執(zhí)行的道理。如果你不知道也沒(méi)關(guān)系,那么我在這里告訴你:“全局對(duì)象優(yōu)先于MIAN函數(shù)執(zhí)行,且構(gòu)建于棧中,切記,切記!”現(xiàn)在,我們?cè)撋钊隬inMain運(yùn)行機(jī)制了,確切的說(shuō),應(yīng)該是MFC的機(jī)制!首先,看看MFC的庫(kù)文件把,它能給我們帶來(lái)許多驚喜。(vc6的相應(yīng)的目錄是Microsoft Visual StudioVC98MFCSRC;VC7相應(yīng)的目錄是Microsoft Visual Studio .NET 2003Vc7atlmfcsrcmfc)現(xiàn)在我們就從這個(gè)全局下手,開(kāi)始今天的旅途。CMyApp theApp; 此時(shí),系統(tǒng)會(huì)執(zhí)行CMyApp的父類(CWinApp)構(gòu)造函數(shù),再執(zhí)行CMyApp的構(gòu)造函數(shù)。(先有老爹,再有兒子?。藭r(shí)就會(huì)調(diào)用CWinApp的構(gòu)造函數(shù)。CWinApp的構(gòu)造函數(shù)(在VC提供的MFC代碼中以“文中的一個(gè)字或詞組”的方式查詢關(guān)鍵字,此時(shí)打開(kāi)APPCORE.CPP,以下使用相同搜索方式,不再?gòu)?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)用程序線程額的啟動(dòng),它給予了我們程序的生命?,F(xiàn)在請(qǐng)注意: pThreadState-m_pCurrentWinThread = this;pModuleState-m_pCurrentWinApp = this; 這兩行代碼其實(shí)都是做的一件事兒。 這段代碼的意思是,獲得了CMyApp的全局對(duì)象的this指針。(此時(shí)你肯定要疑問(wèn),為什么是CMyApp的指針?this目前是在CWinApp中?。?對(duì)此我的答案是,可是你是由CMyApp的對(duì)象引發(fā)的CWinApp的構(gòu)造啊!)這個(gè)指針可非一般的人物,稍后我們的很多工作都要靠它完成。 CWinApp之中的成員變量將因?yàn)閠heApp這個(gè)全局對(duì)象的誕生而獲得配置和初始值。 構(gòu)造完父類,現(xiàn)在構(gòu)造子類??墒俏覀兛吹剑珹ppWizard給我們的子類里它什么也沒(méi)做?是的,這一切都聽(tīng)從你的安排! CMyApp:CMyApp() / TODO: add construction code here,/ Place all significant initialization in InitInstance 接下來(lái)就是今天的主角兒了,搜索關(guān)鍵字“WinMain”,出現(xiàn)很多文件。別急,因?yàn)楝F(xiàn)在我們應(yīng)該先看看WinMain的聲明。打開(kāi)appmodul.cpp: _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)/ call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);這里_tWinMain是為了支持UNICODE而命名的一個(gè)宏,真正起作用的是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();. .此段代碼注意五個(gè)細(xì)節(jié):CWinApp* pApp = AfxGetApp(); 意為獲得對(duì)象指針,其實(shí)就是剛才那個(gè)THIS。不記得了?指向CMyApp的那個(gè)!還值得注意的是,Afx意是全局的,隨時(shí)你都可以調(diào)用它。(AFX就是MFC開(kāi)發(fā)小組的開(kāi)發(fā)代號(hào),意為Application Framework 傳說(shuō)X只是為了好看,沒(méi)實(shí)在意思?!)if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)AfxWinInit完成了線程的初始化和窗框類的注冊(cè)。具體參看appinit.cpp中的定義。if (pApp != NULL & !pApp-InitApplication()其實(shí)pApp和pThread是同一個(gè)指針,都是指向CMyApp的指針,這里因?yàn)镃MyApp中沒(méi)有定義InitApplication,實(shí)際上就調(diào)用的CWinApp:InitApplication(),完成了MFC的內(nèi)容管理。if (!pThread-InitInstance()因?yàn)镃MyApp中改寫了它,所以調(diào)用CMyApp中的,其實(shí)它也是初始化工作。此時(shí)也完成了默認(rèn)窗口類的定義。假如你熟悉SDK編程的話,一定不會(huì)忘記窗口類的設(shè)計(jì)、注冊(cè)、創(chuàng)建、現(xiàn)實(shí)及更新的步驟,此時(shí)MFC以為你設(shè)計(jì)好了默認(rèn)的窗口類。現(xiàn)在你不禁要疑問(wèn),InitApplication()和InitInstance()有何不同?答案是,假如你執(zhí)行一個(gè)程序,于是兩個(gè)函數(shù)都會(huì)被調(diào)用;當(dāng)你在不關(guān)閉前一個(gè)程序的前提下,再執(zhí)行一個(gè)程序,那么就只執(zhí)行后一個(gè)函數(shù)。nReturnCode = pThread-Run();這個(gè)一步驟在深入淺出MFC中被成為程序的活水源頭,在我看來(lái)它就是你開(kāi)車踩油門的步驟。待會(huì)我們會(huì)具體闡述!在設(shè)計(jì)窗口類以后,就應(yīng)該是注冊(cè),MFC自動(dòng)調(diào)用(跳轉(zhuǎn)到)AfxEndDeferRegisterClass(WINCORE.CPP中),為你注冊(cè)了五個(gè)窗口類,分別是:AfxWnd,AfxCreateBar,AfxMDIFrame,AfxFrameOrView,AfxOleControl以上窗口類MFC將自動(dòng)轉(zhuǎn)化成獨(dú)立無(wú)二的類名,供其調(diào)用。在窗口的注冊(cè)以后,就應(yīng)該是窗口的創(chuàng)建工作,此時(shí)會(huì)調(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é)請(qǐng)參看MSDN。此時(shí)你不禁要問(wèn),我們的事兒都讓MFC做完了?工業(yè)化生產(chǎn)出來(lái)的窗口都是千篇一律啊,我要有我自己的風(fēng)格!別急,MFC給用戶提供了一個(gè)修改窗口設(shè)計(jì)的機(jī)會(huì)那就是:PreCreateWindow(CREATESTRUCT& cs) 你在MSDN中查詢一下CREATESTRUCT這個(gè)結(jié)構(gòu)體,你會(huì)發(fā)現(xiàn)它和我們的CreateWindow幾乎是一模一樣,這個(gè)就是MFC留給你修改窗口的一個(gè)機(jī)會(huì)。在PreCreateWindow時(shí),會(huì)跳到CWnd:PreCreateWindow,里面有一個(gè)宏:AfxDeferRegisterClass,它的作用是:如果該窗口類沒(méi)有被注冊(cè),那么就注冊(cè)它;如果注冊(cè)了,就什么也不管!窗口類的設(shè)計(jì)、注冊(cè)、創(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)容,接下來(lái)該:nReturnCode = pThread-Run()了此時(shí)應(yīng)該調(diào)用CMyApp的Run()函數(shù),但是在CMyApp類中,根本沒(méi)有聲明或定義這樣一個(gè)函數(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();最后你會(huì)發(fā)現(xiàn),它又調(diào)用了一個(gè)CWinThread:Run(),此時(shí)你就看不到CWinThread:Run()的代碼了(至少筆者沒(méi)有找到,因?yàn)槲④浿惶峁┝瞬糠諱FC代碼。)但是你可以在MSDN中找到CWinThread:Run()的描述:Run 控制線程的函數(shù)。包含消息泵。一般不重寫。 再具體點(diǎn)就是:Run acquires and dispatches Windows messages

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論