1. 程式人生 > >模態對話方塊和非模態對話方塊的建立與銷燬

模態對話方塊和非模態對話方塊的建立與銷燬

首先宣告:在網上看了很多資料,很多內容也是從別人那裡學到的,只是結合自己的使用寫下來。

在VS中對話方塊分兩種:模態對話方塊和非模態對話方塊。

模態對話方塊就是一旦我被打開了,就得完全做我的事情,只有把我關了,你才能做其他的事情。

非模態對話方塊就是你把我打開了,可以去幹點別的,什麼時候想起我來了,就用用,甚至可以直接把我滅了。

  • 不管要哪種對話方塊,以下兩步必須得做:

1、在資源中(或者其他地方)新增一個Dialog資源;


圖1. 新建對話方塊資源

2、右鍵 在【Add class 】,為你新建的對話方塊加新建一個類,為什麼要新增類呢?因為面向物件程式設計,後續你要使用這個對話方塊,總得有個東西代表這個對話方塊吧!

圖2中①處寫對話方塊類的名稱,一般以C****,代表類。

②處選擇類的基類,我只選過CDialog和CDialogEx,後者是前者的派生,介面更美化了點。

③處世自動產生的兩個關於這個類的檔案。


圖2. 新增對話方塊類

下一步就是如何呼叫?如何銷燬?

  • 對話方塊的呼叫。

模態:

CTestDlg d1; d1.DoModal();//推薦使用

兩句就可以了,建立顯示都自動完成。也可以用CTestDlg *d1=new CTestDlg;d1->DoModal();,但是要顯示的在後面新增delete d1.

非模態:

CTestDlg *pDlg=new CTestDlg;

pDlg->Create

(IDD_TESTDLG,this); 

pDlg->ShowWindow(SW_SHOW);

對於非模態對話方塊最好使用new建立物件,如果是直接建立一個區域性物件,在函式結束時對話方塊就消失了,因為非模態對話方塊是一建立好就返回,而模態對話方塊是要等到關閉了對話方塊才返回,所以模態對話方塊可以使用區域性物件。也可以採用全域性物件來解決非模態對話方塊的作用域問題。

  • 對話方塊的銷燬

一個對話方塊關閉時,根據關閉的方法不同,會呼叫OnOK(剛開始建立對話方塊預設的【確定】按鈕裡面的呼叫的這個函式)或OnCancle(剛開始建立對話方塊預設的【取消】按鈕裡面的呼叫的這個函式)或者OnClose(右上角的×),然後會呼叫OnDestroy()——OnNcDestroy()——PostNcDestroy(),完全結束


關閉模態對話方塊,只需要使用預設的函式就能正常關閉。刪除動態建立的物件就像上面下劃線標記即可。

MFC應用程式中關閉模式對話方塊的順序

1.OnClose()        訊息響應函式,響應WM_CLOSE訊息,當"關閉"按鈕被單擊的時候,該函式被呼叫

2.OnKillFocus()    訊息響應函式,響應WM_KILLFOCUS訊息,當一個視窗即將失去鍵盤輸入焦點以前被髮送

3.OnDestroy()      訊息響應函式,響應WM_DESTROY訊息,當一個視窗即將被銷燬時,被髮送

4.OnNcDestroy()    訊息響應函式,響應WM_NCDESTROY訊息,當一個視窗被銷燬以後被髮送

5.PostNcDestroy() 過載函式,作為處理OnNcDestroy()函式的最後動作被CWnd呼叫

對於非模態對話方塊,新新增的對話方塊類必須過載 OnCancel() 和 PostNcDestroy()函式。

預設的CDialog::OnOK和CDialog::OnCancel函式均呼叫EndDialog,故程式設計師必須編寫自己的OnOK和OnCancel函式並且在函式中呼叫DestroyWindow來關閉對話方塊。在OnCancel()函式中刪除原來的,重新新增DestroyWindow();。

在螢幕上一個視窗被刪除後,框架會呼叫CWnd::PostNcDestroy,這是一個虛擬函式,程式可以在該函式中完成刪除視窗物件的工作。在PostNcDestroy() 函式的程式碼中新增delete this

MFC應用程式關閉視窗的順序(非模態視窗)

1.OnClose()       訊息響應函式,響應視窗的WM_CLOSE訊息,當關閉按鈕被單擊的時候傳送此訊息

2.OnDestroy()     訊息響應函式,響應視窗的WM_DESTROY訊息,當一個視窗將被銷燬時,傳送此訊息

3.OnNcDestroy()   訊息響應函式,響應視窗的WM_NCDESTROY訊息,當一個視窗被銷燬後傳送此訊息

4.PostNcDestroy() 過載函式,作為處理OnNcDestroy()函式的最後動作,被CWnd呼叫

注意:如果一個對話方塊還有一個子對話方塊,那就更要注意了。如果子對話方塊還在顯示的時候,父對話方塊由於某種原因關閉了(如從其他執行緒接收到了WM_CLOSE訊息),父對話方塊在執行完OnClose函式後會等待,直到子對話方塊銷燬了,才會繼續執行自己的如第一段所說的關閉過程。所以如果子對話方塊使用的是指標並且父視窗被先關閉了,就要在OnClose()後面執行的函式(比如PostNcDestroy())中delete了