MFC程序啟動過程與函式執行順序

2023-01-27 22:30:08 字數 3321 閱讀 3208

1、建立application object物件theapp

程式一開始生產乙個(且只有乙個)application object物件theapp,也即乙個cwinapp物件,這個全域性物件一產生,便執行其建構函式,因為並沒有定義cmywinapp建構函式,所以即執行cwinapp類的建構函式。該函式定義於第75行,你可以自己搜出來啃一啃,因此,cwinapp之中的成員變數將因為theapp這個全域性物件的誕生而獲得配置與初值。

2、winmain登場

用sdk程式設計序時,程式的入口點是winmain函式,而在mfc程式裡我們並沒有看到winmain函式,哦!~ 原來她是被隱藏在mfc**裡面了。當theapp配置完成後,winmain登場,慢!

細看程式,並沒連到winmain函式的**啊!這個我也不知道,mfc早已準備好並由鏈結器直接加到應用程式**中了,原來她在裡面,好,我們就認為當theapp配置完成後,程式就轉到來了。那執行什麼呢?

看看下面從摘出來的**:

extern "c" int winapi

_twinmain(hinstance hinstance, hinstance hprevinstance, lptstr lpcmdline, int ncmdshow)

_twinmain函式的「_t」是為了支援unicode而準備的乙個巨集。

_twinmain函式返回值是afxwinmain函式的返回值,afxwinmain函式定義於第21行,稍加整理,去蕪存菁,就可以看到這個「程式進入點」主要做些什麼事:

int afxapi afxwinmain(hinstance hinstance, hinstance hprevinstance, lptstr lpcmdline, int ncmdshow)

afxgetapp()函式是取得cmywinapp物件指標,故上面函式第6至8行相當於呼叫:

cmywinapp::initapplication();

cmywinapp::initinstance()

cmywinapp::run();

因而導致呼叫:

cwinapp::initapplication(); //因為 cmywinapp 並沒有改寫 initapplication

cmywinapp::initinstance() //因為 cmywinapp 改寫了 initinstance

cwinapp::run(); //因為 cmywinapp 並沒有改寫 run

用過sdk寫程式的朋友,現在可能會發出會心的微笑。

3、afxwininit——afx內部初始化操作

afxwininit是繼cwinapp建構函式之後的第乙個操作,主要做的是afx內部初始化操作,該函式定義於第24行,這裡就不掏出來了,你自己搜出來啃吧!

4、執行cwinapp::initapplication

afxwininit之後的操作是papp->initapplication,我們已知道papp指向cmywinapp物件,當呼叫:

papp->initapplication();

相當於呼叫:

cmywinapp::initapplication();

但是你要知道,cmywinapp繼承自cwinapp,而initapplication又是cwinapp的乙個虛函式,我們並沒有改寫它(大部分情況下不需改寫它),所以上述操作相當於呼叫:

cwinapp::initapplication();

此函式定義於第125行,你自己搜出來看吧!我就不搬出來了,裡面的操作都是mfc為了內部管理而做的(其實我也看不懂,知道有這回事就好了)。

5、執行cwinapp::initinstance

繼initapplication函式之後,afxwinmain呼叫papp->initinstance。當程式呼叫:

papp->initinstance();

相當於呼叫:

cmywinapp::initinstance();

但是你要知道,cmywinapp繼承自cwinapp,而initinstance又是cwinapp的乙個虛函式。由於我們改寫了它,所以上述操作就是呼叫我們自己(cmywinapp)的這個initinstance函式。

6、cframewnd::create產生主視窗(並先註冊視窗類)

現在已經來到cwinapp::initinstance了,該函式先new乙個cmyframewnd物件,從而產生主視窗。在建立cmyframewnd對之前,要先執行建構函式cmyframewnd::

cmyframewnd(),該函式用create函式產生視窗:

cmyframewnd::cmyframewnd()

其中create是cframewnd的成員函式,它將產生乙個視窗,用過sdk程式設計序的朋友都知道,要建立主視窗時要先註冊乙個視窗類,規定視窗的屬性等,但,這裡使用哪乙個視窗類呢?create函式第乙個引數(其它引數請參考msdn或《深出淺出mfc》詳解)指定視窗類設為null又是什麼意思啊?意思是要以mfc內建的空中類產生乙個標準的外框視窗,但,我們的程式一般都沒有註冊任何視窗類呀!

噢,create函式在產生視窗之前會引發視窗類的註冊操作。

讓我們先挖出create函式都做了些什麼操作,create函式定義於的第538行(在此我就不把**copy過來了,你自己開啟出來看吧),函式在562行呼叫createex函式,由於createex是cwnd的成員函式,而cframewnd是從cwnd繼而來,故將呼叫cwnd::createex。此函式定義於第665行,下面是部分**:

bool cwnd::createex(dword dwexstyle, lpctstr lpszclassname,

lpctstr lpszwindowname, dword dwstyle,

int x, int y, int nwidth, int nheight,

hwnd hwndparent, hmenu nidorhmenu, lpvoid lpparam)

afxhookwindowcreate(this);

hwnd hwnd = ::createwindowex(

...} 用過sdk程式設計序的朋友,看到上面**應該有一點感覺了吧,函式中呼叫的precreatewindows是虛函式,在cwnd和cframewnd之中都有定義。由於this指標所指物件的緣故,這裡應該呼叫的是cframewnd::precreatewindow。

該函式定義於第521行,以下是部分**:

bool cframewnd::precreatewindow(createstruct& cs)

...} 其中afxdeferregisterclass是乙個定義於中的巨集。該巨集如下:

#define afxdeferregisterclass(fclass) afxenddeferregisterclass(fclass)

電腦啟動過程介紹

電腦啟動到底是怎麼一回事,啟動過程是什麼,這些你知道嗎?下面就為大家簡要介紹一下系統的啟動過程 1 電源bios自檢程式開始執行 2 主引導記錄被裝入記憶體,並且程式開始執行 3 活動分割槽的引導扇區被裝入記憶體 4 ntldr從引導扇區被裝入並初始化 5 將處理器的實模式改為32位平滑記憶體模式 ...

windows啟動過程介紹

電腦啟動到底是怎麼一回事,下面就為大家簡要介紹一下系統的啟動過程 1 電源bios自檢程式開始執行 2 主引導記錄被裝入記憶體,並且程式開始執行 3 活動分割槽的引導扇區被裝入記憶體 4 ntldr從引導扇區被裝入並初始化 5 將處理器的實模式改為32位平滑記憶體模式 6 ntldr開始執行適當的小...

資料庫啟動過程

啟動資料庫 1 首先開啟兩台資料庫伺服器的電源,看到數字滾動證明電源已經開啟。伺服器啟動大約需要幾分鐘的時間。2 啟動後伺服器風扇會高速旋 出噪音,同時前面板上右側會有兩個綠燈點亮。3 當系統啟動後顯示器上會出現如下對話方塊,請輸入使用者名稱小寫的root回車。4 當出現如下對話方塊時請再次輸入密碼...