天天看點

模态對話框和非模态對話框的建立與銷毀

首先聲明:在網上看了很多資料,很多内容也是從别人那裡學到的,隻是結合自己的使用寫下來。

在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了。

繼續閱讀