MFC的程式執行的整個流程

2021-06-16 23:51:58 字數 3850 閱讀 1945

mfc

的程式執行的整個流程:

第一步:宣告乙個全域物件

(ex:myobject

在我們自己寫的程式裡頭。)

第二步:由於

winmain()

已經寫好了成

mfc函式,所以它編譯的時候會自動鏈結進來。於是,開始執行

afxwinmain()

第三步:它做什麼動作呢?先取得之前宣告物件的指標,然後開始呼叫

myobject

物件中的

、initinstance()

,及run()(

以上三個函式都是繼承自

第四步:改寫

initinstance()

的動作,在裡頭

new乙個

cframewnd()

的物件。

cframewnd()

這個建構式呼叫

create()。

第五步:

cframewnd

:create()

:做什麼事呢?註冊和建立乙個視窗。

第六步:執行

myobject->run()

。訊息迴圈放在此。

.若是要更改視窗圖示及游標形狀:方法為在rc檔找乙個叫afx_idi_td_frame東東。游標形狀則為呼叫全域函式afxregisterwndclasee()註冊自己的視窗類再將其值傳回,做為create的第乙個引數。

.自己的視窗類別:改寫precreatewindow()。先利用api函式,getclassinof()可以獲得該類別的乙個副本,更改其類別結構的lpszclassname,再以afxregistrtclass

第七步:如何將訊息和程式串接在一起? .

mfc的動態生成:

declare_dynamic:用途為宣告乙個static cruntimeclass資料元素和乙個可以抓到該物件位址的函式getruntimeclass()。

implement_dynamic:~~(

相當於)

_implement_runtimeclass用來將剛剛宣告過的cruntimeclass資料元素,填入初始值。

其中runtime_class用來取得資料元素位址。用途和getruntimeclass()一樣

afx_classinit則是用來串接型錄網用的。(因為它用到了static mpfirstclass指標,借由它的移動,只要一產生新類別就可以串接起來了。)

當然,只用上述的巨集只能完成一些資料的建構,要真的能夠動態生成,則要靠下面的兩個巨集:

1.declare_dyncreate

:(1)

包含declare_dynamic巨集

(2)乙個動態生成的函式:

createobject() 2.

implement_dyncreate:

(1) _implement_runtimeclass

(3) createobject()

的內容。

.mfc

的訊息對映:

如何讓訊息到處亂流,可以往前也可以向左向右?

首先如何建立乙個巨大的訊息網?

1.declare_message_map():用來宣告乙個static messagemap(資料結構為:乙個指向baseclass 的messagemap *指標,和乙個指向messageentry的指標)

、static messageentry、及getmessagemap()。

2.begin_message_map:定義getmessagemap()的內容,及填入messagemap的值。

3.on_command(id,pfn):填入messageentry的內容。

4.end_message_map():填入最後元素內容。

詳細說明:

map

map_entry{

uint nmessage; // windows message   

uint ncode; // control code or wm_notify code

uint nid; // control id (or 0 for windows messages)

uint nlastid; // used for entries specifying a range of control id's

uint nsig; // signature type (action) or pointer to message #

afx_pmsgpfn; // 此為函式指標,如左:typedef void (ccmdtarget::*afx_pmsg)(void);

完成之後利用# #definedeclare_message_map()\

static msgmap_entry _messageentries; \

static msgmap messagemap; \

virtual msgmap* getmessagemap() const;

得到乙個

1.map

2.map_entry

3.getmessagemap()//傳回the class map的指標

資料填空的動作由

1.#definebegin_message_map(theclass, baseclass)

\\(1)定義getmessagemap()的內容

\\(2)處理map

\\(3)處理msg_entry

2.#defineon_command(id, memberfxn) \\填入msg_entry

3.#defineend_message_map() \\填入msg_entry的最後乙個元素

整個訊息流動網由上到下建立完成,如下圖。

現在缺的就是由左到右,請問如何做?

一般的訊息

wm_***

,都是由下到上。

但是若是控制項的

wm_command

的話就會有由左到右的可能,要做特別處理。

為了要完成這個目的,需要以下的幾個新函式

上述的結果可以解決上、下流的問題,但是橫的怎麼辦呢?

一般的wm_***一定是上、下流。

但是若是命令wm_command的話就有特別處理了。

怎麼說呢?

請看下面:(call stack執行順序是由下往上看)

ccmdtarget::oncmdmsg()

cview::oncmdmsg()

cframewnd::oncmdmsg()

cwnd::oncommand()

cframewnd::oncmdmsg()

cwnd::oncommand()

cframewnd::oncommand()

cwnd::onwndmsg()

cwnd::windowproc()

afxcallwndproc()

afxwndproc()

afxwndprocbase()

cwinthread::run()

afxwinmain()

winmain()

winmaincrtstartup()

以這個程式為例在cframewnd::oncommand()呼叫了cwnd::oncommand(),而cwnd::oncommand()在函式中又呼叫了oncmdmsg()(此函式為virtual函式),於是cframewnd::oncmdmsg()被喚起,oncmdmsg()虛擬函依序一層一層的被喚起,最後來到ccmdtarget::oncmdmsg()做訊息比對的動作。完

RookeyFrame 整個執行流程

準備開始整理一下這個專案的整體框架,很久沒研究這個框架了,心裡還是念著的,今兒乘有時間弄一下。一丁點建議 先自己乙個乙個的搬作者的類庫,這樣就能很好的理解作者的專案結構 每搬乙個類庫都執行一下哦,看需要引用哪些dll和專案,直到編譯成功後,再進行下一步 自己組建和專案一樣的目錄結構,這樣可以理解一下...

MFC應用程式執行流程

extern c int winapi twinmain hinstance hinstance,hinstance hprevinstance,lptstr lpcmdline,int ncmdshow 這一下清楚了,mfc中的winmain函式其實什麼也沒做,只是呼叫了乙個函式afxwinmai...

MFC 程式入口和執行流程

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