MFC 視窗封裝

2021-08-22 12:50:17 字數 2657 閱讀 7450

mfc對window作了一層比較淺的封裝,其建立過程基本與sdk差不多。它簡化了視窗的註冊,並將視窗過程與類關聯起來;後者是比較重要的封裝,它使訊息能夠分流給「類的視窗過程」,既而通過訊息對映,才能到達各個處理函式。

使用傳統的sdk來建立乙個視窗有點繁瑣,偽**是這樣的:

if(registerclass(…))

registerclass

根據乙個classname

註冊乙個視窗類,並指定視窗過程;createwindowex

建立該視窗,其中的引數用於設定樣式、位置等。

這段**的繁瑣之處其實在於函式的引數,createwindowex

有12個引數,這常常讓初學者望而生畏。作為良好封裝的視窗框架,乙個重要任務是簡化這些引數,讓它成為可分別設定的屬性。

要看mfc如何建立乙個視窗,cview

應該是最合適的了,cframewnd::createview

建立了乙個檢視視窗:

cwnd

* cframewnd::createview

(ccreatecontext* pcontext, uint nid)

要建立cview

,只需要乙個cwnd::create

就可以了,不過這裡面必然隱藏著一些事情,包括註冊視窗類,指定視窗過程:

bool cwnd::create

呼叫下面的函式

bool cwnd::createex

(dword dwexstyle, lpctstr lpszclassname, ...)

createex

直接呼叫createwindowex

將視窗建立出來,我們注意到上面呼叫create時傳給lpszclassname

的是乙個空值,那麼視窗類在什麼時候註冊的呢,只有乙個地方,那就是precreatewindow

。precreatewindow

是乙個虛函式,cwnd

在這裡預設地為視窗註冊名字為afxwnd42的視窗類,而派生類可以覆蓋這個函式註冊其他的視窗類名,比如cview

:bool cview::precreatewindow

(createstruct & cs)

return true; }

cview

以afxwndframeorview

註冊視窗類,它的具體名字是:afxframeorview42。註冊的行為就在afxdeferregisterclass

裡面,不過到這裡我們可以打住了。

註冊視窗類的時候要指定視窗過程,afxdeferregisterclass

是乙個巨集,會呼叫afxenddeferregisterclass

作具體的呼叫,在函式裡看到這一句**:wndcls.lpfnwndproc

= defwindowproc;視窗過程竟指定給系統的預設視窗過程,真正的視窗過程是在什麼時候指定的呢?

在cwnd::createex

裡面,createwindowex

的前後各有一行**,從字面上可以推斷mfc監視了視窗的建立:

void

afxapi afxhookwindowcreate(cwnd* pwnd)

mfc使用乙個cbt鉤子來監視視窗的建立,當pwnd

的視窗控制代碼建立時,_afxcbtfilterhook

將被呼叫,這個函式的用意已經非常明顯,將新建立的視窗控制代碼附加到pwnd

,並為pwnd

指定視窗過程。這個函式較長,我就不列**了,只是將大概的幾點列舉如下:

1. 通過cwnd::attach

將控制代碼附加給pwnd

,attach還做了另一件事,建立pwnd

與控制代碼的哈唏表,這是為了後面處理訊息時可以找到正確的cwnd

物件。哈唏表在mfc中大量地被使用。

2.子類化視窗過程,將視窗過程指定為afxwndproc

,並儲存舊的視窗過程;通過presubclasswindow

,你還可以指定自己的視窗過程,不過似乎只在afxwndproc

之後才能被呼叫。

由於整個程序的所有視窗建立都會先被_afxcbtfilterhook

鉤住,所以裡面也進行了一些過濾,比如ime視窗。這種情況對於多執行緒是否有效呢,也許_afxthreadstate

可以確保在多執行緒情況視窗建立的順序,我並沒有去深究。

總而言之,視窗過程最後被替換為afxwndproc

:lresult callback afxwndproc

(hwnd hwnd, uint nmsg, wparam wparam, lparam lparam)

通過fromhandlepermanent

從哈唏表找到與控制代碼對應的視窗類,執行點又進入afxcallwndproc

,接下來我們就會看到熟悉的windowproc

lresult afxapi afxcallwndproc

(cwnd* pwnd, hwnd hwnd, uint nmsg,

wparam wparam = 0, lparam lparam = 0)

pthreadstate

似乎與執行緒同步有關,從這一點可以看出mfc在多執行緒方面做得比vcl好得多,找個時間再來探索這個主題。

到此,視窗建立到訊息處理就連慣起來了。儘管不同的視窗類在處理上有些差異,但核心流程大概就是這樣。

從普通函式到物件方法》。

MFC 使用MFC建立視窗

標頭檔案 mfc是乙個封裝了windowsapi且物件導向的c 類庫,同時也是乙個應用程式的框架結構。另外,並非所有mfc提供的函式都是類的成員,mfc也以 全域性函式的形式,為使用者提供了各類字首為afx的函式,可供使用者在必要時隨時隨地進行呼叫。由mfc建立的應用,我們不能夠直接看到其程式的入口...

MFC視窗訊息

mfc應用程式中處理訊息的順序 1.afxwndproc 該函式負責接收訊息,找到訊息所屬的cwnd物件,然後呼叫afxcallwndproc 2.afxcallwndproc 該函式負責儲存訊息 儲存的內容主要是訊息識別符號和訊息引數 用程式以後使用,然後呼叫windowproc 函式 3.win...

MFC視窗訊息

mfc應用程式中處理訊息的順序 1.afxwndproc 該函式負責接收訊息,找到訊息所屬的cwnd物件,然後呼叫afxcallwndproc 2.afxcallwndproc 該函式負責儲存訊息 儲存的內容主要是訊息識別符號和訊息引數 用程式以後使用,然後呼叫windowproc 函式 3.win...