VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別_第1頁(yè)
VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別_第2頁(yè)
VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別_第3頁(yè)
VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別_第4頁(yè)
VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、VC 模式對(duì)話框和非模式對(duì)話框的創(chuàng)建,銷(xiāo)毀和區(qū)別在WIN32中,模式對(duì)話框的創(chuàng)建一般是使用DialogBox來(lái)進(jìn)行創(chuàng)建的。而非模式對(duì)話框則是利用CreateWindow來(lái)創(chuàng)建的。在MFC或是WTL中,模式對(duì)話框一般是使用DoModal,而非模式對(duì)話框的創(chuàng)建則是使用Create。模式對(duì)話框創(chuàng)建后,程序的其他窗口便不能進(jìn)行操作,必須將該窗口關(guān)閉后,其他窗口才能進(jìn)行操作。而非模式對(duì)話框則無(wú)需這樣,它不強(qiáng)制要求用戶立即反應(yīng),而是與其他窗口同時(shí)接受用戶操作。Create的Dialog一般是modalless,如果你的程序本身就是只有一個(gè)Dialog,就無(wú)所謂了,看不出modalless的效果。modal

2、less本來(lái)就是讓有機(jī)會(huì)切換到本程序的其他窗口。非模態(tài)對(duì)話框的特點(diǎn):與模態(tài)對(duì)話框不同,非模態(tài)對(duì)話框不壟斷用戶的輸入,用戶打開(kāi)非模態(tài)對(duì)話框后,仍然可以與其它界面進(jìn)行交互。非模態(tài)對(duì)話框的設(shè)計(jì)與模態(tài)對(duì)話框基本類(lèi)似,也包括設(shè)計(jì)對(duì)話框模板和設(shè)計(jì)CDialog類(lèi)的派生類(lèi)兩部分。但是,在對(duì)話框的創(chuàng)建和刪除過(guò)程中,非模態(tài)對(duì)話框與模態(tài)對(duì)話框相比有下列不同之處:非模態(tài)對(duì)話框的模板必須具有Visible風(fēng)格,否則對(duì)話框?qū)⒉豢梢?jiàn),而模態(tài)對(duì)話框則無(wú)需設(shè)置該項(xiàng)風(fēng)格。更保險(xiǎn)的辦法是調(diào)用CWnd:ShowWindow(SW_SHOW)來(lái)顯示對(duì)話框,而不管對(duì)話框是否具有Visible風(fēng)格。非模態(tài)對(duì)話框?qū)ο笫怯胣ew操作符在堆中

3、動(dòng)態(tài)創(chuàng)建的,而不是以成員變量的形式嵌入到別的對(duì)象中或以局部變量的形式構(gòu)建在堆棧上。通常應(yīng)在對(duì)話框的擁有者窗口類(lèi)內(nèi)聲明一個(gè)指向?qū)υ捒蝾?lèi)的指針成員變量,通過(guò)該指針可訪問(wèn)對(duì)話框?qū)ο蟆Mㄟ^(guò)調(diào)用CDialog:Create函數(shù)來(lái)啟動(dòng)對(duì)話框,而不是CDialog:DoModal,這是模態(tài)對(duì)話框的關(guān)鍵所在。由于Create函數(shù)不會(huì)啟動(dòng)新的消息循環(huán),對(duì)話框與應(yīng)用程序共用同一個(gè)消息循環(huán),這樣對(duì)話框就不會(huì)壟斷用戶的輸入。Create在顯示了對(duì)話框后就立即返回,而DoModal是在對(duì)話框被關(guān)閉后才返回的。眾所周知,在MFC程序中,窗口對(duì)象的生存期應(yīng)長(zhǎng)于對(duì)應(yīng)的窗口,也就是說(shuō),不能在未關(guān)閉屏幕上窗口的情況下先把對(duì)應(yīng)的窗

4、口對(duì)象刪除掉。由于在Create返回后,不能確定對(duì)話框是否已關(guān)閉,這樣也就無(wú)法確定對(duì)話框?qū)ο蟮纳嫫?,因此只好在堆中?gòu)建對(duì)話框?qū)ο螅荒芤跃植孔兞康男问絹?lái)構(gòu)建之。必須調(diào)用CWnd:DestroyWindow而不是CDialog:EndDialog來(lái)關(guān)閉非模態(tài)對(duì)話框。調(diào)用CWnd:DestroyWindow是直接刪除窗口的一般方法。由于缺省的CDialog:OnOK和CDialog:OnCancel函數(shù)均調(diào)用EndDialog,故程序員必須編寫(xiě)自己的OnOK和OnCancel函數(shù)并且在函數(shù)中調(diào)用DestroyWindow來(lái)關(guān)閉對(duì)話框。因?yàn)槭怯胣ew操作符構(gòu)建非模態(tài)對(duì)話框?qū)ο?,因此必須在?duì)話框關(guān)

5、閉后,用delete操作符刪除對(duì)話框?qū)ο?。在屏幕上一個(gè)窗口被刪除后,框架會(huì)調(diào)用CWnd:PostNcDestroy,這是一個(gè)虛擬函數(shù),程序可以在該函數(shù)中完成刪除窗口對(duì)象的工作,具體代碼如下void CModelessDialog:PostNcDestroy delete this; /刪除對(duì)象本身這樣,在刪除屏幕上的對(duì)話框后,對(duì)話框?qū)ο髮⒈蛔詣?dòng)刪除。擁有者對(duì)象就不必顯式的調(diào)用delete來(lái)刪除對(duì)話框?qū)ο罅恕1仨氂幸粋€(gè)標(biāo)志表明非模態(tài)對(duì)話框是否是打開(kāi)的。這樣做的原因是用戶有可能在打開(kāi)一個(gè)模態(tài)對(duì)話框的情況下,又一次選擇打開(kāi)命令。程序根據(jù)標(biāo)志來(lái)決定是打開(kāi)一個(gè)新的對(duì)話框,還是僅僅把原來(lái)打開(kāi)的對(duì)話框激活。

6、通??梢杂脫碛姓叽翱谥械闹赶?qū)υ捒驅(qū)ο蟮闹羔樧鳛檫@種標(biāo)志,當(dāng)對(duì)話框關(guān)閉時(shí),給該指針賦NULL值,以表明對(duì)話框?qū)ο笠巡淮嬖诹恕L崾荆涸贑+編程中,判斷一個(gè)位于堆中的對(duì)象是否存在的常用方法是判斷指向該對(duì)象的指針是否為空。這種機(jī)制要求程序員將指向該對(duì)象的指針初始化為NULL值,在創(chuàng)建對(duì)象時(shí)將返回的地址賦給該指針,而在刪除對(duì)象時(shí)將該指針置成NULL值。根據(jù)上面的分析,我們很容易把Register程序中的登錄數(shù)據(jù)對(duì)話框改成非模態(tài)對(duì)話框。這樣做的好處在于如果用戶在輸入數(shù)據(jù)時(shí)發(fā)現(xiàn)編輯視圖中有錯(cuò)誤的數(shù)據(jù),那么不必關(guān)閉對(duì)話框,就可以在編輯視圖中進(jìn)行修改。窗口對(duì)象的自動(dòng)清除:一個(gè)MFC窗口對(duì)象包括兩方面的內(nèi)容:一

7、是窗口對(duì)象封裝的窗口,即存放在m_hWnd成員中的HWND(窗口句柄),二是窗口對(duì)象本身是一個(gè)C+對(duì)象。要?jiǎng)h除一個(gè)MFC窗口對(duì)象,應(yīng)該先刪除窗口對(duì)象封裝的窗口,然后刪除窗口對(duì)象本身。刪除窗口最直接方法是調(diào)用CWnd:DestroyWindow或:DestroyWindow,前者封裝了后者的功能。前者不僅會(huì)調(diào)用后者,而且會(huì)使成員m_hWnd保存的HWND無(wú)效(NULL)。如果DestroyWindow刪除的是一個(gè)父窗口或擁有者窗口,則該函數(shù)會(huì)先自動(dòng)刪除所有的子窗口或被擁有者,然后再刪除父窗口或擁有者。在一般情況下,在程序中不必直接調(diào)用DestroyWindow來(lái)刪除窗口,因?yàn)镸FC會(huì)自動(dòng)調(diào)用De

8、stroyWindow來(lái)刪除窗口。例如,當(dāng)用戶退出應(yīng)用程序時(shí),會(huì)產(chǎn)生WM_CLOSE消息,該消息會(huì)導(dǎo)致MFC自動(dòng)調(diào)用CWnd:DestroyWindow來(lái)刪除主框架窗口,當(dāng)用戶在對(duì)話框內(nèi)按了OK或Cancel按鈕時(shí),MFC會(huì)自動(dòng)調(diào)用CWnd:DestroyWindow來(lái)刪除對(duì)話框及其控件。窗口對(duì)象本身的刪除則根據(jù)對(duì)象創(chuàng)建方式的不同,分為兩種情況。在MFC編程中,會(huì)使用大量的窗口對(duì)象,有些窗口對(duì)象以變量的形式嵌入在別的對(duì)象內(nèi)或以局部變量的形式創(chuàng)建在堆棧上,有些則用new操作符創(chuàng)建在堆中。對(duì)于一個(gè)以變量形式創(chuàng)建的窗口對(duì)象,程序員不必關(guān)心它的刪除問(wèn)題,因?yàn)樵搶?duì)象的生命期總是有限的,若該對(duì)象是某個(gè)對(duì)象

9、的成員變量,它會(huì)隨著父對(duì)象的消失而消失,若該對(duì)象是一個(gè)局部變量,那么它會(huì)在函數(shù)返回時(shí)被清除。對(duì)于一個(gè)在堆中動(dòng)態(tài)創(chuàng)建的窗口對(duì)象,其生命期卻是任意長(zhǎng)的。初學(xué)者在學(xué)習(xí)C+編程時(shí),對(duì)new操作符的使用往往不太踏實(shí),因?yàn)橛胣ew在堆中創(chuàng)建對(duì)象,就不能忘記用delete刪除對(duì)象。讀者在學(xué)習(xí)MFC的例程時(shí),可能會(huì)產(chǎn)生這樣的疑問(wèn),為什么有些程序用new創(chuàng)建了一個(gè)窗口對(duì)象,卻未顯式的用delete來(lái)刪除它呢?問(wèn)題的答案就是有些MFC窗口對(duì)象具有自動(dòng)清除的功能。如前面講述非模態(tài)對(duì)話框時(shí)所提到的,當(dāng)調(diào)用CWnd:DestroyWindow或:DestroyWindow刪除一個(gè)窗口時(shí),被刪除窗口的PostNcDest

10、roy成員函數(shù)會(huì)被調(diào)用。缺省的PostNcDestroy什么也不干,但有些MFC窗口類(lèi)會(huì)覆蓋該函數(shù)并在新版本的PostNcDestroy中調(diào)用delete this來(lái)刪除對(duì)象,從而具有了自動(dòng)清除的功能。此類(lèi)窗口對(duì)象通常是用new操作符創(chuàng)建在堆中的,但程序員不必操心用delete操作符去刪除它們,因?yàn)橐坏┱{(diào)用DestroyWindow刪除窗口,對(duì)應(yīng)的窗口對(duì)象也會(huì)緊接著被刪除。不具有自動(dòng)清除功能的窗口類(lèi)如下所示。這些窗口對(duì)象通常是以變量的形式創(chuàng)建的,無(wú)需自動(dòng)清除功能。所有標(biāo)準(zhǔn)的Windows控件類(lèi)。從CWnd類(lèi)直接派生出來(lái)的子窗口對(duì)象(如用戶定制的控件)。切分窗口類(lèi)CSplitterWnd。缺省的

11、控制條類(lèi)(包括工具條、狀態(tài)條和對(duì)話條)。模態(tài)對(duì)話框類(lèi)。具有自動(dòng)清除功能的窗口類(lèi)如下所示,這些窗口對(duì)象通常是在堆中創(chuàng)建的。主框架窗口類(lèi)(直接或間接從CFrameWnd類(lèi)派生)。視圖類(lèi)(直接或間接從CView類(lèi)派生)。讀者在設(shè)計(jì)自己的派生窗口類(lèi)時(shí),可根據(jù)窗口對(duì)象的創(chuàng)建方法來(lái)決定是否將窗口類(lèi)設(shè)計(jì)成可以自動(dòng)清除的。例如,對(duì)于一個(gè)非模態(tài)對(duì)話框來(lái)說(shuō),其對(duì)象是創(chuàng)建在堆中的,因此應(yīng)該具有自動(dòng)清除功能。綜上所述,對(duì)于MFC窗口類(lèi)及其派生類(lèi)來(lái)說(shuō),在程序中一般不必顯式刪除窗口對(duì)象。也就是說(shuō),既不必調(diào)用DestroyWindow來(lái)刪除窗口對(duì)象封裝的窗口,也不必顯式地用delete操作符來(lái)刪除窗口對(duì)象本身。只要保證非自

12、動(dòng)清除的窗口對(duì)象是以變量的形式創(chuàng)建的,自動(dòng)清除的窗口對(duì)象是在堆中創(chuàng)建的,MFC的運(yùn)行機(jī)制就可以保證窗口對(duì)象的徹底刪除。如果需要手工刪除窗口對(duì)象,則應(yīng)該先調(diào)用相應(yīng)的函數(shù)(CWnd:DestroyWindow)刪除窗口,然后再刪除窗口對(duì)象對(duì)于以變量形式創(chuàng)建的窗口對(duì)象,窗口對(duì)象的刪除是框架自動(dòng)完成的對(duì)于在堆中動(dòng)態(tài)創(chuàng)建了的非自動(dòng)清除的窗口對(duì)象,必須在窗口被刪除后,顯式地調(diào)用delete來(lái)刪除對(duì)象(一般在擁有者或父窗口的析構(gòu)函數(shù)中進(jìn)行)對(duì)于具有自動(dòng)清除功能的窗口對(duì)象,只需調(diào)用CWnd:DestroyWindow即可刪除窗口和窗口對(duì)象。注意,對(duì)于在堆中創(chuàng)建的窗口對(duì)象,不要在窗口還未關(guān)閉的情況下就用dele

13、te操作符來(lái)刪除窗口對(duì)象提示:在非模態(tài)對(duì)話框的OnCancel函數(shù)中可以不調(diào)用CWnd:DestroyWindow,取而代之的是調(diào)用CWnd:ShowWindow(SW_HIDE)來(lái)隱藏對(duì)話框在下次打開(kāi)對(duì)話框時(shí)就不必調(diào)用Create了,只需調(diào)用CWnd:ShowWindow(SW_SHOW)來(lái)顯示對(duì)話框這樣做的好處在于對(duì)話框中的數(shù)據(jù)可以保存下來(lái),供以后使用由于擁有者窗口在被關(guān)閉時(shí)會(huì)調(diào)用DestroyWindow刪除每一個(gè)所屬窗口,故只要非模態(tài)對(duì)話框是自動(dòng)清除的,程序員就不必?fù)?dān)心對(duì)話框?qū)ο蟮膭h除問(wèn)題以下是一點(diǎn)資料供參考,非模態(tài)對(duì)話框的銷(xiāo)毀順序:MFC應(yīng)用程序中處理消息的順序1.AfxWndPro

14、c() 該函數(shù)負(fù)責(zé)接收消息,找到消息所屬的CWnd對(duì)象,然后調(diào)用AfxCallWndProc2.AfxCallWndProc() 該函數(shù)負(fù)責(zé)保存消息(保存的內(nèi)容主要是消息標(biāo)識(shí)符和消息參數(shù))供應(yīng)用程序以后使用,然后調(diào)用WindowProc()函數(shù)3.WindowProc() 該函數(shù)負(fù)責(zé)發(fā)送消息到OnWndMsg()函數(shù),如果未被處理,則調(diào)用DefWindowProc()函數(shù)4.OnWndMsg() 該函數(shù)的功能首先按字節(jié)對(duì)消息進(jìn)行排序,對(duì)于WM_COMMAND消息,調(diào)用OnCommand()消息響應(yīng)函數(shù),對(duì)于WM_NOTIFY消息調(diào)用OnNotify()消息響應(yīng)函數(shù)。任何被遺漏的消息將是一個(gè)窗口

15、消息。OnWndMsg()函數(shù)搜索類(lèi)的消息映像,以找到一個(gè)能處理任何窗口消息的處理函數(shù)。如果OnWndMsg()函數(shù)不能找到這樣的處理函數(shù)的話,則把消息返回到WindowProc()函數(shù),由它將消息發(fā)送給DefWindowProc()函數(shù)5.OnCommand() 該函數(shù)查看這是不是一個(gè)控件通知(lParam參數(shù)不為NULL,如果lParam參數(shù)為空的話,說(shuō)明該消息不是控件通知),如果它是,OnCommand()函數(shù)會(huì)試圖將消息映射到制造通知的控件;如果他不是一個(gè)控件通知(或者如果控件拒絕映射的消息)OnCommand()就會(huì)調(diào)用OnCmdMsg()函數(shù)6.OnCmdMsg() 根據(jù)接收消息的

16、類(lèi),OnCmdMsg()函數(shù)將在一個(gè)稱(chēng)為命令傳遞(Command Routing)的過(guò)程中潛在的傳遞命令消息和控件通知。例如:如果擁有該窗口的類(lèi)是一個(gè)框架類(lèi),則命令和通知消息也被傳遞到視圖和文檔類(lèi),并為該類(lèi)尋找一個(gè)消息處理函數(shù)MFC應(yīng)用程序創(chuàng)建窗口的過(guò)程1.PreCreateWindow() 該函數(shù)是一個(gè)重載函數(shù),在窗口被創(chuàng)建前,可以在該重載函數(shù)中改變創(chuàng)建參數(shù)(可以設(shè)置窗口風(fēng)格等等)2.PreSubclassWindow() 這也是一個(gè)重載函數(shù),允許首先子分類(lèi)一個(gè)窗口3.OnGetMinMaxInfo() 該函數(shù)為消息響應(yīng)函數(shù),響應(yīng)的是WM_GETMINMAXINFO消息,允許設(shè)置窗口的最大或

17、者最小尺寸4.OnNcCreate() 該函數(shù)也是一個(gè)消息響應(yīng)函數(shù),響應(yīng)WM_NCCreate消息,發(fā)送消息以告訴窗口的客戶區(qū)即將被創(chuàng)建5.OnNcCalcSize() 該函數(shù)也是消息響應(yīng)函數(shù),響應(yīng)WM_NCCALCSIZE消息,作用是允許改變窗口客戶區(qū)大小6.OnCreate() 該函數(shù)也是一個(gè)消息響應(yīng)函數(shù),響應(yīng)WM_Create消息,發(fā)送消息告訴一個(gè)窗口已經(jīng)被創(chuàng)建7.OnSize() 該函數(shù)也是一個(gè)消息響應(yīng)函數(shù),響應(yīng)WM_SIZE消息,發(fā)送該消息以告訴該窗口大小已經(jīng)發(fā)生變化8.OnMove() 消息響應(yīng)函數(shù),響應(yīng)WM_MOVE消息,發(fā)送此消息說(shuō)明窗口在移動(dòng)9.OnChildNotify()

18、 該函數(shù)為重載函數(shù),作為部分消息映射被調(diào)用,告訴父窗口即將被告知一個(gè)窗口剛剛被創(chuàng)建MFC應(yīng)用程序關(guān)閉窗口的順序(非模態(tài)窗口)1.OnClose() 消息響應(yīng)函數(shù),響應(yīng)窗口的WM_CLOSE消息,當(dāng)關(guān)閉按鈕被單擊的時(shí)候發(fā)送此消息2.OnDestroy() 消息響應(yīng)函數(shù),響應(yīng)窗口的WM_DESTROY消息,當(dāng)一個(gè)窗口將被銷(xiāo)毀時(shí),發(fā)送此消息3.OnNcDestroy() 消息響應(yīng)函數(shù),響應(yīng)窗口的WM_NCDESTROY消息,當(dāng)一個(gè)窗口被銷(xiāo)毀后發(fā)送此消息4.PostNcDestroy() 重載函數(shù),作為處理OnNcDestroy()函數(shù)的最后動(dòng)作,被CWnd調(diào)用MFC應(yīng)用程序中打開(kāi)模式對(duì)話框的函數(shù)調(diào)用

19、順序1.DoModal() 重載函數(shù),重載DoModal()成員函數(shù)2.PreSubclassWindow() 重載函數(shù),允許首先子分類(lèi)一個(gè)窗口3.OnCreate() 消息響應(yīng)函數(shù),響應(yīng)WM_Create消息,發(fā)送此消息以告訴一個(gè)窗口已經(jīng)被創(chuàng)建4.OnSize() 消息響應(yīng)函數(shù),響應(yīng)WM_SIZE消息,發(fā)送此消息以告訴窗口大小發(fā)生變化5.OnMove() 消息響應(yīng)函數(shù),響應(yīng)WM_MOVE消息,發(fā)送此消息,以告訴窗口正在移動(dòng)6.OnSetFont() 消息響應(yīng)函數(shù),響應(yīng)WM_SETFONT消息,發(fā)送此消息,以允許改變對(duì)話框中控件的字體7.OnInitDialog() 消息響應(yīng)函數(shù),響應(yīng)WM_I

20、NITDIALOG消息,發(fā)送此消息以允許初始化對(duì)話框中的控件,或者是創(chuàng)建新控件8.OnShowWindow() 消息響應(yīng)函數(shù),響應(yīng)WM_SHOWWINDOW消息,該函數(shù)被ShowWindow()函數(shù)調(diào)用9.OnCtlColor() 消息響應(yīng)函數(shù),響應(yīng)WM_CTLCOLOR消息,被父窗口發(fā)送已改變對(duì)話框或?qū)υ捒蛏厦婵丶念伾?0. OnChildNotify() 重載函數(shù),作為WM_CTLCOLOR消息的結(jié)果發(fā)送MFC應(yīng)用程序中關(guān)閉模式對(duì)話框的順序1.OnClose() 消息響應(yīng)函數(shù),響應(yīng)WM_CLOSE消息,當(dāng)"關(guān)閉"按鈕被單擊的時(shí)候,該函數(shù)被調(diào)用2.OnKillFocus

21、() 消息響應(yīng)函數(shù),響應(yīng)WM_KILLFOCUS消息,當(dāng)一個(gè)窗口即將失去鍵盤(pán)輸入焦點(diǎn)以前被發(fā)送3.OnDestroy() 消息響應(yīng)函數(shù),響應(yīng)WM_DESTROY消息,當(dāng)一個(gè)窗口即將被銷(xiāo)毀時(shí),被發(fā)送4.OnNcDestroy() 消息響應(yīng)函數(shù),響應(yīng)WM_NCDESTROY消息,當(dāng)一個(gè)窗口被銷(xiāo)毀以后被發(fā)送5.PostNcDestroy() 重載函數(shù),作為處理OnNcDestroy()函數(shù)的最后動(dòng)作被CWnd調(diào)用打開(kāi)無(wú)模式對(duì)話框的順序1.PreSubclassWindow() 重載函數(shù),允許用戶首先子分類(lèi)一個(gè)窗口2.OnCreate() 消息響應(yīng)函數(shù),響應(yīng)WM_Create消息,發(fā)送此消息以告訴一個(gè)

22、窗口已經(jīng)被創(chuàng)建3.OnSize() 消息響應(yīng)函數(shù),響應(yīng)WM_SIZE消息,發(fā)送此消息以告訴窗口大小發(fā)生變化4.OnMove() 消息響應(yīng)函數(shù),響應(yīng)WM_MOVE消息,發(fā)送此消息以告訴窗口正在移動(dòng)5.OnSetFont() 消息響應(yīng)函數(shù),響應(yīng)WM_SETFONT消息,發(fā)送此消息以允許改變對(duì)話框中控件的字體MSDN.原文說(shuō)明:CWnd:DestroyWindow See AlsoCWnd Overview | Class Members | Hierarchy Chart | CWnd:OnDestroy | CWnd:Detach | DestroyWindowDestroys the Wind

23、ows window attached to the CWnd object.virtual BOOL DestroyWindow( );Return ValueNonzero if the window is destroyed; otherwise 0.RemarksThe DestroyWindow member function sends appropriate messages to the window to deactivate it and remove the input focus. It also destroys the window's menu, flus

24、hes the application queue, destroys outstanding timers, removes Clipboard ownership, and breaks the Clipboard-viewer chain if CWnd is at the top of the viewer chain. It sends WM_DESTROY and WM_NCDESTROY messages to the window. It does not destroy the CWnd object.DestroyWindow is a place holder for p

25、erforming cleanup. Because DestroyWindow is a virtual function, it is shown in any CWnd-derived class in Class View. But even if you override this function in your CWnd-derived class, DestroyWindow is not necessarily called. If DestroyWindow is not called in the MFC code, then you have to explicitly

26、 call it in your own code if you want it to be called.Assume, for example, you have overridden DestroyWindow in a CView-derived class. Since MFC source code does not call DestroyWindow in any of its CFrameWnd-derived classes, your overridden DestroyWindow will not be called unless you call it explic

27、itly. If the window is the parent of any windows, these child windows are automatically destroyed when the parent window is destroyed. The DestroyWindow member function destroys child windows first and then the window itself. The DestroyWindow member function also destroys modeless dialog boxes crea

28、ted by CDialog:Create.If the CWnd being destroyed is a child window and does not have the WS_EX_NOPARENTNOTIFY style set, then the WM_PARENTNOTIFY message is sent to the parent.Example/ CModeless is CDialog class representing a modeless dialog/ Destruction of the modeless dialog involves calling Des

29、troyWindow in / OnOK() & OnCancel() handlersvoid CModeless:OnOK() if (!UpdateData(TRUE) TRACE0("UpdateData failed during dialog termination/n"); / The UpdateData routine will set focus to correct item return; DestroyWindow();void CModeless:OnCancel() DestroyWindow();非模態(tài)對(duì)話框相對(duì)于模態(tài)對(duì)話框,他的創(chuàng)建

30、和銷(xiāo)毀過(guò)程和模態(tài)對(duì)話框有一定的區(qū)別 先看一下MSDN的原文:When you implement a modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Dont call the base class CDialog:OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it. Yo

31、u should also override PostNcDestroy for modeless dialog boxes in order to delete this, since modeless dialog boxes are usually allocated with new. Modal dialog boxes are usually constructed on the frame and do not need PostNcDestroy cleanup.MS的指示:非模態(tài)對(duì)話框需要重載函數(shù)OnCanel,并且在這個(gè)函數(shù)中調(diào)用DestroyWindow。并且不能調(diào)用基類(lèi)

32、的OnCancel,因?yàn)榛?lèi)的OnCancel調(diào)用了EndDialog這個(gè)函數(shù),這個(gè)函數(shù)是針對(duì)模態(tài)對(duì)話框的。還有一個(gè)必須重載的函數(shù)就是PostNcDestroy,這也是一個(gè)虛函數(shù),通常的非模態(tài)對(duì)話框是用類(lèi)的指針,通過(guò)new創(chuàng)建的,這就需要在PostNcDestroy函數(shù)中delete掉這個(gè)指針。模式對(duì)話框會(huì)和非模式對(duì)話框在運(yùn)行原理上有一定的差別。下面是創(chuàng)建模式對(duì)話框和非模式對(duì)話框的幾段代碼,可以比較其中的不同之處:void CMainWindow:OnModel() / 用戶點(diǎn)擊“Model Dialog”按鈕 CMyDialog dlg(this); / 顯示模式對(duì)話框 dlg.DoModa

33、l();void CMainWindow:OnModeless() / 用戶點(diǎn)擊“Modeless Dialo”按鈕 CMyDialog* pDlg = new CMyDialog(this); pDlg->m_bModeless = TRUE; / 創(chuàng)建無(wú)模式對(duì)話框 pDlg->Create(IDD_MYDIALOG); / 移動(dòng)窗口到主窗口的中央 pDlg->CenterWindow(); / 顯示更新窗口 pDlg->ShowWindow(SW_NORMAL); pDlg->UpdateWindow();void CMyDialog:OnCancel() /

34、 用戶關(guān)閉對(duì)話框 if(m_bModeless) DestroyWindow(); else CDialog:OnCancel(); void CMyDialog:PostNcDestroy() if(m_bModeless) /這么做可以使模式對(duì)話框不調(diào)用PostNcDestroy,因?yàn)樗膶?shí)例會(huì)自動(dòng)刪除 delete this;其中OnModel是對(duì)彈出模式對(duì)話框的按鈕的函數(shù)響應(yīng),OnModeless是對(duì)彈出非模式對(duì)話框的按鈕的函數(shù)響應(yīng),從代碼可以看到兩者創(chuàng)建的方法不一樣。由于創(chuàng)建模式對(duì)話框的方法比較簡(jiǎn)潔,可想而知,CMyDialog類(lèi)默認(rèn)是創(chuàng)建模式對(duì)話框的。再來(lái)看下面兩個(gè)CMyDialo

35、g重載的函數(shù)OnCancel和PostNcDestroy,為什么要重載這兩個(gè)函數(shù)呢?這得從兩種對(duì)話框的運(yùn)行原理來(lái)分析。模式對(duì)話框在關(guān)閉之前不允許用戶切換到主窗口。模式對(duì)話框使得消息循環(huán)限制在對(duì)話框內(nèi),而不會(huì)流向主窗口,所以對(duì)主窗口的任何操作都是無(wú)效的。這樣就類(lèi)似于在主窗口消息循環(huán)里內(nèi)嵌了一個(gè)屬于對(duì)話框的消息循環(huán)(不知道這樣的描述是否恰當(dāng)),有點(diǎn)函數(shù)機(jī)制的味道。事實(shí)上,模式對(duì)話框?qū)嵗▽?duì)象)就是在函數(shù)堆棧中申請(qǐng)的,這樣在對(duì)話框窗口銷(xiāo)毀時(shí)就用不著刪除自己了。因?yàn)楹瘮?shù)機(jī)制的作用本身就是這樣的。下面來(lái)澄清一下對(duì)話框窗口銷(xiāo)毀和對(duì)話框?qū)嵗N(xiāo)毀的區(qū)別。一個(gè)對(duì)話框如果要銷(xiāo)毀,要做兩個(gè)步驟,先是要銷(xiāo)毀對(duì)話框窗口

36、,這是由OnCancel函數(shù)來(lái)完成的;然后是銷(xiāo)毀對(duì)話框?qū)嵗@是由PostNcDestroy函數(shù)來(lái)完成的。所以,如果是單單創(chuàng)建模式對(duì)話框,就不需要在CMyDialog中重載OnCancel和PostNcDestroy了,用CDialog中的就行了(況且模式對(duì)話框根本就不需要PostNcDestroy函數(shù))。但是,如果是創(chuàng)建非模式對(duì)話框就不同了,CDialog:Create會(huì)立即返回,進(jìn)入普通的循環(huán),即主窗口循環(huán),不像模式對(duì)話框的DoModel函數(shù)要到對(duì)話框窗口關(guān)閉之后才返回,其內(nèi)部有消息循環(huán)。所以,非模式對(duì)話框?qū)嵗裰鞔翱趯?shí)例一樣在進(jìn)程堆中申請(qǐng),實(shí)例銷(xiāo)毀時(shí)也要調(diào)用PostNcDestroy函

37、數(shù)。void CMyDialog:OnCancel() / 用戶關(guān)閉對(duì)話框 if(m_bModeless) /如果是非模式對(duì)話框,就不能在內(nèi)置循環(huán)中調(diào)用OnCancel函數(shù),因?yàn)?DestroyWindow(); /那么做了,程序可能會(huì)把消息發(fā)送給主窗口,那么關(guān)閉的就是主窗口 else /了,就不能關(guān)閉對(duì)話框了 CDialog:OnCancel(); 消息響應(yīng)的區(qū)別在消息響應(yīng)方面,模式對(duì)話框和非模式對(duì)話框之間又有著很大的區(qū)別。模式對(duì)話框工作的時(shí)候,它有內(nèi)部的消息泵機(jī)制,控件之間的交互不用我們?nèi)藶榈娜タ刂?,系統(tǒng)會(huì)幫助我們?nèi)ヌ幚?。非模式?duì)話框則像普通窗口一樣,則由WinMain中書(shū)寫(xiě)的消息循環(huán)驅(qū)動(dòng)

38、。但由于是對(duì)話框,它對(duì)一些消息有特殊的處理。因此,在消息循環(huán)中,需要先對(duì)對(duì)話框提供截獲消息的機(jī)會(huì)。while (GetMessage(&msg, NULL, 0, 0) if (hDlgModeless = 0 | !IsDialogMessage(hDlgModeless, &msg) TranslateMessage(&msg); DispatchMessage( &msg); 如果當(dāng)前取得的消息是對(duì)話框的消息,IsDialogMessage 將它交由對(duì)話消息處理函數(shù)處理,并返回TRUE。不需要再派發(fā)了。注意:這個(gè)方法并不是很好用,因?yàn)楫?dāng)對(duì)話框過(guò)多的時(shí)候,處

39、理起來(lái)就比較麻煩了。另一種處理的方法是利用子類(lèi)化控件的方法,來(lái)處理控件間的交互。銷(xiāo)毀的區(qū)別模式對(duì)話框的銷(xiāo)毀是使用EndDialog,而非模式對(duì)話框的銷(xiāo)毀是使用DestroyWindow.。所以我們?cè)阡N(xiāo)毀對(duì)話框的時(shí)候,也要對(duì)其進(jìn)行區(qū)別。非模式對(duì)話框,用戶關(guān)閉對(duì)話框時(shí),對(duì)話框消息處理函數(shù)將收到WM_CLOSE消息,接到后調(diào)用DestroyWindow以銷(xiāo)毀非模式對(duì)話框。模式對(duì)話框,則一般響應(yīng)IDOK和IDCANCEL。在PPC上,我們對(duì)于OK鍵和X鍵的處理要注意這點(diǎn)。其他非模態(tài)對(duì)話框的模板必須具有Visible風(fēng)格,否則對(duì)話框?qū)⒉豢梢?jiàn),而模態(tài)對(duì)話框則無(wú)需設(shè)置該項(xiàng)風(fēng)格。更保險(xiǎn)的辦法是調(diào)用ShowWindow(hDialog, SW_SHOW)來(lái)顯示對(duì)話框,而不管對(duì)話框是否具有Visible風(fēng)格。非模態(tài)對(duì)話框?qū)ο笫怯胣ew操作符在堆中動(dòng)態(tài)創(chuàng)建的,而不是以成員變量的形式嵌入到別的對(duì)象中或以局部變量的形式構(gòu)建在堆棧上。通常應(yīng)在對(duì)話框的擁有者窗口類(lèi)內(nèi)聲明一個(gè)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論