1. 程式人生 > >MFC 程式入口和執行流程

MFC 程式入口和執行流程

一 MFC程式執行過程剖析

1)我們知道在WIN32API程式當中,程式的入口為WinMain函式,在這個函式當中我們完成註冊視窗類,建立視窗,進入訊息迴圈,最後由作業系統根據傳送到程式視窗的訊息呼叫程式的視窗函式。而在MFC程式當中我們不在能找到類似WinMain這樣的程式入口,取而代之的是一系列派生類的宣告和定義以及一個衝CWinApp類派生而來的類的全域性物件。CWinApp類被稱之為應用程式物件,在一個MFC程式當中只允許有一個應用程式物件。由於CWinApp的派生物件是全域性的,因此這個物件的建構函式會在所有的其他程式碼執行之前被呼叫,而由於CWinApp類當中包含了HWND、HINSTANCE等控制代碼的存在,其建構函式就執行了對這些成員資料的初始化操作,這裡的所謂初始化僅僅是把所有的控制代碼物件賦值為NULL。

2)在呼叫完CWinApp的建構函式以後由聯結器向程式內自動連結的AfxWinMain函式將被呼叫,而這個函式可以被看作MFC程式的入口函式。在這個函式當中呼叫全域性AfxGetApp()函式獲得應用程式物件,這時將呼叫AfxInit全域性函式,這個函式的功能是使用作業系統傳遞給AfxWinMain函式的引數初始化應用程式物件當中的相關控制代碼資料成員。

3)之後AfxWinMain函式呼叫CWinApp::InitApplication成員函式,這個成員函式用來初始化應用程式物件當中的關於文件部分的內容。

4)隨後呼叫CWinApp::InitInstance成員函式,在這個成員函式當中,使用new操作在堆上宣告一個框架視窗物件,由此導致框架視窗物件的建構函式被呼叫,在框架視窗建構函式當中呼叫Create函式來建立視窗,而呼叫的Create函式一般將WNDCLASS引數設定成NULL,這樣就由MFC內部呼叫PreCreateWindow函式,在這個函式當中由MFC註冊幾個預設的WNDCLASS供框架視窗的Create使用。這時程式控制權交還給CWinApp::InitInstance成員函式內部,由這個函式呼叫CWnd::ShowWindow顯示視窗並且呼叫CWnd::UpdateWindow向視窗傳送WM_PAINT訊息。呼叫完CWinApp::InitInstance成員函式後由AfxWinMain函式呼叫CWinApp::Run成員函式,並由這個函式來建立和處理訊息迴圈,並且在沒有訊息的時候處理OnIdle空閒處理。至此整個程式的建立過程完成。
 5)在程式的執行過程當中,由作業系統源源不斷的傳送訊息給應用程式,並且由CWinApp::Run當中的訊息迴圈處理並且分發給相關的視窗物件的DefWindowProc成員函式,並由這個成員函式查詢視窗物件的訊息對映表,如果查到對應項,則由登記在訊息對映表當中的類成員函式處理,否則則按照Message Route當中的順序象父層類傳送。
 6)在訊息執行結束,使用者按下關閉按鈕後,作業系統向程式傳送WM_CLOSE訊息,預設狀況下程式呼叫DestoryWindow並且傳送WM_DESTORY訊息,應用程式接受到這個訊息以後的預設操作是呼叫PostQuitMessage函式,由這個函式傳送WM_QUIT訊息。當程式物件接受到WM_QUIT訊息後訊息迴圈結束,由AfxWinMain函式呼叫AfxTerm函式清理程式使用過的資源並且結束整個程式。
小結:以上的所有描述涵蓋了一個程式從開始、執行到結束的所有過程。

 相信大家有點暈點了吧,實際程式設計中沒有必要深刻理解這麼多,這些大都是由MFC內部自動幫我們完成的。實際MFC程式設計過程中,其實懂得MFC程式中各個函式的執行流程即可。有時候過於追究MFC細節會白白浪費我們的精力,應該將主要精力放在使用MFC解決實際問題上。

 

二 VC6中SDI程式的執行流程
下面以VC6中的sdi工程為例,通過給每個函式前設定斷點後調式執行,可以看出MFC的SDI的執行流程。記錄如下,希望對MFC執行有疑惑的人有幫助。

1)CSdiApp theApp;          //sdi.cpp

2)CSdiApp::CSdiApp()             //sdi.cpp

3)BOOL CSdiApp::InitInstance()         //sdi.cpp

4)CSdiDoc::CSdiDoc()                   //sdiDoc.cpp

5)CMainFrame::CMainFrame()          //MainFrm.cpp

6)BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)    //MainFrm.cpp

7)int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)    //MainFrm.cpp

8)CSdiView::CSdiView()                     //sdiView.cpp

9)BOOL CSdiView::PreCreateWindow(CREATESTRUCT& cs)         //sdiView.cpp

10)BOOL CSdiDoc::OnNewDocument()                //sdiDoc.cpp

11) void CSdiView::OnDraw(CDC* pDC)                //sdiView.cpp

// ---------------- 關閉視窗後-------------------------------------

12) CSdiView::~CSdiView()

13) CMainFrame::~CMainFrame()

14) CSdiDoc::~CSdiDoc() 

一切源於對計算機的熱愛