MFC執行框架

2021-07-05 17:52:54 字數 3646 閱讀 9760

**:

2、winmain登場

extern "c" int winapi

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

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

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

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

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

相當於呼叫:

相當於呼叫:

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

cmyframewnd::cmyframewnd()

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

讓我們先挖出create函式都做了些什麼操作,create函式定義於winfrm.cpp的第538行(在此我就不把**copy過來了,你自己開啟出來看吧),函式在562行呼叫createex函式,由於createex是cwnd的成員函式,而cframewnd是從cwnd繼而來,故將呼叫cwnd::createex。此函式定義於wincore.cpp第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(cs.dwexstyle, cs.lpszclass,

cs.lpszname, cs.style, cs.x, cs.y, cs.cx, cs.cy,

cs.hwndparent, cs.hmenu, cs.hinstance, cs.lpcreateparams);

...

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

bool cframewnd::precreatewindow(createstruct& cs)

...}

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

#define afxdeferregisterclass(fclass) afxenddeferregisterclass(fclass)
注:這裡有巨集和《深入淺出mfc》的不一樣,以上**是從visual c++ 6.0摘取。

afxenddeferregisterclass定義於wincore.cpp第3619行,該函式很複雜,主要是註冊五個視窗類(哇!終於看到視窗類了,怎麼用5個呢?我還不清楚),不同類的precreatewindow成員函式都是在視窗產生之前一刻被呼叫,準備用來註冊視窗類。如果我們指定的視窗類是null,那麼就使用系統預設類。從cwnd及其各個派生類的precreatewindow成員函式可以看出,整個framework針對不同功能的視窗使用了哪些視窗類。

7、視窗顯示與更新

return cwinthread::run();}

函式呼叫cwinthread::run函式,該函式定義於thrdcore.cpp第456行,在這裡我就不copy出來了。函式在第480行呼叫了pumpmessage函式,該函式定義於thrdcore.cpp第810行,整理後的部分**如下:

bool cwinthread::pumpmessage()

// process this message

if (m_msgcur.message != wm_kickidle && !pretranslatemessage(&m_msgcur))

return true;

}

該函式主要操作是將訊息由::dispatchmessage送到視窗函式(cwnd::defwindowproc)中,但程式一般沒有提供任何視窗函式,但在afxenddeferregisterclass中,在註冊五種視窗類之前已經指定視窗函式為:

wndcls.lpfnwndproc = defwindowproc;
雖然視窗函式被指定為defwindowproc成員函式(cwnd::defwindowproc),但事實上訊息並不是被唧往該處,而是乙個名為afxwndproc的全域性函式去。

9、把訊息與處理函式連線在一起——message map機制

到此,主視窗已經產生,等待的就是各種訊息了,然後呼叫相應的處理函式,然而訊息和處理函式怎樣連線在一起呢?mfc採用了message map機制(訊息對映機制),提供給應用程式使用的「很方便的介面」的兩組巨集,其原理我還不大清楚,在這裡也無法講解,主要用法是:先在類宣告中結合declare_message_map()給出處理函式,如:

class cmyframewnd : public cframewnd

{public:

cmyframewnd();

afx_msg void onpaint(); // for wm_paint

afx_msg void onabout(); // for wm_command (idm_about)

declare_message_map()

再在相應的.cpp檔案的任何位置(當然不能在函式之內)使用bebin_message_map()和end_message_map()巨集把相應的訊息加入去,如:

begin_message_map(cmyframewnd, cframewnd)

on_command(idm_about, onabout)

on_wm_paint()

end_message_map()

為什麼經過這樣的巨集之後,訊息就會自動流往指定的函式去呢?謎底在於message map的結構設計,自己找《深入淺出mfc》第3章的message map**程式去啃一啃吧!

05 MFC框架執行大概流程

hellomfc.h ifndef hello mfc define hello mfc public virtual bool initinstance class cmainwindow public cframewnd endif hellomfc.cpp include include he...

MFC單文件框架分析及執行流程

首先來分析一下mfc單文件類的結構 它包括如下幾個類 caboutdlg 對話框框類,對應應用程式的 幫助 關於 選單,彈出 關於 對話方塊。cmainframe 派生自cframewnd類,為框架視窗物件,對應應用程式的主視窗。c view 派生自檢視類cview 為檢視物件,對應應用程式的客戶視...

MFC基本框架

mfc基本框架 by 小戴 發表於 2006 12 21 15 59 00 mfc 應用程式框架 1 mfc 簡介 mfc microsoft foundation class 是由微軟公司編寫的一套專門用於 windows 程式設計的 c 基礎類庫,vc 程式設計基本上都是圍繞著 mfc 類庫來進...