天天看點

C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類

對話框的種類

有兩種類型的對話框:模态( Modal)對話框和非模态( Modeless)對話框

  • 模态對話框
模态對話框是指當其顯示時,程式會暫停執行,直到關閉這個模态對話框後,才能繼續執行程式中其他任務。例如,在Word中利用【檔案打開】菜單指令顯示一個“打開”對話框後,再用滑鼠去選擇其他菜單,或者進行該對話框以外的任何操作時,隻會聽到嘟嘟聲,這是因為“打開”對話框是一個模态對話框。模态對話框壟斷了使用者的輸入,當模态對話框打開時,使用者隻能與該對話框進行互動,而其他使用者界面對象接收不到輸入資訊。我們平時所遇到的大部分對話框都是模态對話框。
  • 非模态對話框

當非模态對話框顯示時,允許轉而執行程式中其他任務,而不用關閉這個對話框。典型的例子是 Windows提供的記事本程式中的“查找”對話框,該對話框不會壟斷使用者的輸入,打開“査找”對話框後,仍可以與其他使用者界面對象進行互動,使用者可以一邊查找,一邊修改文章,這樣,就大大友善了使用

總結:簡單說就是模态對話框顯示時不能進行其他操作,而非模态對話框顯示時可以對其他界面進行操作

建立:

首先插入一個對話框:如圖所示點選插入(Insert),再點選資源(Resource),選擇Dialog,或者在資源視圖右擊點選插入(Insert Dialog)

C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類

在MFC中,對資源的操作通常都是通過一個與資源相芙的類來完成的。對話框資源也有一個相應的基類: CDialog.

根據MSDN提供的幫助資訊,可以知道 CDialog類派生于CWnd類,是以它是一個與視窗相關的類,主要用來在螢幕上顯示一個對話框。由此可知,實際上,對話框本身也是一個視窗界面。既然在MFC中,對資源的操作是通過一個類來完成的,那麼就需要建立一個類與這個建立的對話框資源相關聯。為此,在ⅤC++開發環境中,選擇【view】菜單下的【 Class Wizard】菜單指令,這時會彈出對話框,提示ID: IDD DIALOG1資源是一個新資源,并且因為它是一個對話框資源,是以需要為它建立一個相關聯的類,或者可以選擇程式中已有的一個類與之相關聯。單擊【OK】按鈕,然後彈出一個對話框利用這個對話框就可以為建立的對話框資源建立一個關聯的類,,然後取一個名字,例:CTestDlg.

C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類
C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類

如何調用與顯示對話框:

對于模态對話框:      例:點選按鈕彈出一個模态對話框

首先拖入按鈕控件,輕按兩下按鈕,添加響應函數,在函數中敲下如下代碼(在這之前要先添加對應對話框類的頭檔案TestDlg.h)

void CTestDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	CTestDlg dlg;
	dlg.DoModal();
}
           

編譯運作:   點選Button1按鈕,顯示為圖二

C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類
C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類
在建立模态對話框時,當執行到調用 DoModal函數以顯示這個對話框時,程式就會暫停執行,直到模态對話框關閉之後,程式才繼續向下執行。也就是說,當模态對話框顯示時,程式中建立的dlg這個對象的生命周期并未結束。是以,在建立非模态對話框時,不能把對話框對象定義為局部對象。對于這個問題,有兩種解決辦法:一種就是把這個對話框對象定義為類的成員變量;另一種方式是将它定義為指針,在堆上配置設定記憶體。我們知道,在堆上配置設定的記憶體,與程式的整個生命周期是一緻的,當然這裡是指程式中不主動銷毀的情況這裡,我們采用後一種方式

對于非模态對話框:     例:點選按鈕彈出一個非模态對話框

void CModleDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
//	CTestDlg dlg;
//	dlg.DoModal();
	CTestDlg* pDlg = new CTestDlg;
	pDlg->Create(IDD_DIALOG1,this);    //建立對話框
	pDlg->ShowWindow(SW_SHOW);    //顯示對話框
}
           
C++ MFC深入詳解之----模态對話框與非模态對話框對話框的種類
可是,上例所示的這段程式仍有問題,首先,我們定義的pDlg這個指針變量是個局部對象,這樣當它的生命周期結束時,它所儲存的記憶體位址就丢失了,那麼在程式中也就無法再引用到它所指向的那塊記憶體了。這個問題的解決辦法有兩種:一是将這個指針變量定義為類的成員變量,然後在 CMybole View類的析構函數中調用 delete函數來釋放這個指針變量所指向的那塊記憶體;二是在 CTestDlg類中重載PostNcDestroy虛函數,釋放this指針所指向的記憶體。