VC 中MFC視窗物件的清除

2021-04-17 20:01:39 字數 1793 閱讀 6121

對於vc++初學者來說,總覺得視窗物件的清除過程有些莫名其妙.在程式中看不到對delete的顯式呼叫,這似乎違反了c++中有關初始化和清除的規則.那麼,程式是怎樣取消乙個視窗物件?

要消除視窗物件,必須清楚視窗物件的構成.在乙個通常的程式中,先建立c++視窗物件,然後由windows建立實際的視窗結構,並返回控制代碼與c++物件連線.也就是說,視窗物件包含c++視窗物件和windows視窗物件,兩者通過控制代碼hwnd聯絡.

現在,讓我們看看"正規"的視窗物件清除流程.所謂物件的清除是指釋放物件所佔的資源,視窗物件中windows視窗物件佔有的是系統資源,c++物件佔 有的是記憶體資源.釋放系統資源相對要簡單一些:呼叫虛函式destroywindow刪除windows視窗物件.如果destroywindow刪除的 是父視窗,windows會自動為子視窗呼叫destroywindow.一般來說,程式不必呼叫destroywindow.因為當使用者關閉視窗時, windows便傳送wm_close訊息,wm_close的預設訊息處理函式cwnd::onclose呼叫destroywindow.

到這時,清除工作已經完成了一半,螢幕上的視窗已經不見了!但是別忘了,在記憶體中還有乙個c++視窗物件.讓我們再看看c++物件清除的過程:當 視窗被取消時,視窗最後傳送的乙個訊息是wm_ncdestroy.它預設的訊息處理函式cwnd::onncdestroy把c++視窗物件與控制代碼 hwnd分離,並呼叫乙個很重要的虛函式postncdestroy.這個函式是搞清視窗物件清除的關鍵.cwnd中的postncdestroy什麼都 不做.有些mfc視窗類會過載它,並加入delete this**刪除c++物件.這些視窗類常常是以new操作符建立在堆中的.由於過載了postncdestroy,使視窗有自動清除功能.因此,我們不 用關心清除問題了.另外的一些mfc視窗類一般是以變數形式建立的,mfc沒有為也沒必要為它們過載postncdestroy函式.

不具備自動清除功能的視窗類,一般在堆疊中建立或嵌入於其它c++物件中:

所有標準的windows控制項類(如cstatic, cedit, clistbox等等)

由cwnd類直接派生出來的子視窗物件(如使用者定製的控制項)

拆分視窗類(csplitterwnd)

預設的控制條類(ccontrolbar的派生類)

對話方塊類(cdialog)在堆疊上建立的模態對話方塊類

所有的windows通用對話方塊(除cfindreplacedialog)

由classwizard建立的對話方塊

具有自動清除功能的視窗類,一般在堆中建立:

主框架視窗類(直接或間接從cframewnd類派生)

檢視類(直接或間接從cview類派生)

從某種程度上來說,mfc的"服務到家"使初學者有些找不著北.不過,不得不承認:mfc幹的很漂亮!

談到這裡,我們應該明白c++裡一條重要的準則:用destroywindow清除視窗物件,不要用"delete".

對於不具備自動清除功能的視窗類使用"delete"時,"delete"先呼叫析構函式裡的destroywindow,由於在析構函式中,虛 機制不起作用,這裡只能呼叫本地版本(cwnd類)destroywindow函式,顯然這不是我們想要的.對於有自動清除功能的視窗類,好象問題更嚴重 一點,前面提到了過載的postncdestroy已經含有了"delete this",這樣c++物件就被釋放了兩次.

很多人認為,vc++同vb一樣,是乙個完全視覺化的產品,不用在看c++的書了.通過上面對視窗物件的清除的介紹,可以發現,windows程式是與 windows緊密結合的,而且牽涉到很多c++的知識(如虛函式、析構函式、new操作符等).要對vc++有進一步理解,必須理解windows機 制,深入學習c++.

VC 中MFC視窗物件的清除

對於vc 初學者來說 總覺得視窗物件的清除過程有些莫名其妙 在程式中看不到對 delete 的顯式呼叫 這似乎違反了 c 中有關初始化和清除的規則.那麼 程式是怎樣取消乙個視窗物件 要消除視窗物件 必須清楚視窗物件的構成 在乙個通常的程式中,先建立 c 視窗物件 然後由 windows 建立實際的視...

視窗物件的自動清除

乙個mfc視窗物件包括兩方面的內容 一是視窗物件封裝的視窗,即存放在m hwnd成員中的hwnd 視窗控制代碼 二是視窗物件本身是乙個c 物件。要刪除乙個mfc視窗物件,應該先刪除視窗物件封裝的視窗,然後刪除視窗物件本身。刪除視窗最直接方法是呼叫cwnd destroywindow或 destroy...

MFC中的視窗

mfc 視窗 mfc視窗不對視窗進行直接的控制,而在api環境中卻是可以的。如果不能在api環境中實現某項功能,那麼 肯定也不能在mfc環境中實現。舉例來說,mfc庫的cwnd可以建立乙個視窗,但它只是過去在api環境中使用 api呼叫的封裝。建立mfc視窗是複雜的,首先,建立類cwnd的乙個例項,...