在Windows開發中彈出對話方塊是一種常用的輸入/輸出手段,同時編輯好的對話方塊可以儲存在資源檔中。Visual C++提供了對話方塊編輯工具,利用編輯工具可以方便的添加各種控制項到對話方塊中,而且利用ClassWizard可以方便的產生新的對話方塊類和映射訊息。
首先資源清單中按下右鍵,可以在快顯功能表中選擇“插入對話方塊”。然後再開啟該對話方塊進行編輯,你會在螢幕上看到一個控制項板。你可以將所需要添加的控制項拖到對話方塊上,或是先選中後再在對話方塊上用滑鼠畫出所佔的地區。
對於有強制回應對話方塊使用DoModal()產生,對於無強制回應對話方塊使用Create()產生。相關執行個體代碼如下;
void CMy51_s1View::OnCreateDlg()
{//產生無強制回應對話方塊
CTestDlg *dlg=new CTestDlg;
dlg->Create(IDD_TEST_DLG);
dlg->ShowWindow(SW_SHOW);
}
void CMy51_s1View::OnDoModal()
{//產生有強制回應對話方塊
CTestDlg dlg;
int iRet=dlg.DoModal();
TRACE("dlg return %d/n",iRet);
}
如果你在調試這個程式時你會發現程式在退出後會有記憶體流失,這是因為沒有釋放無強制回應對話方塊所使用的記憶體。
關於在使用對話方塊時Enter鍵和Escape鍵的處理:在使用對話方塊是你會發現當你按下Enter鍵或Escape鍵都會退出對話方塊,這是因為Enter鍵會引起CDialog::OnOK()的調用,而Escape鍵會引起CDialog::OnCancel()的調用。而這兩個調用都會引起對話方塊的退出。在MFC中這兩個成員函數都是虛擬函數,所以我們需要進行重載,如果我們不希望退出對話方塊那麼我們可以在函數中什麼都不做,如果需要進行檢查則可以添加檢查代碼,然後調用父類的OnOK()或OnCancel()。相關代碼如下;
void CTestDlg::OnOK()
{
AfxMessageBox("你選擇確定");
CDialog::OnOK();
}
void CTestDlg::OnCancel()
{
AfxMessageBox("你選擇取消");
CDialog::OnCancel();
}
2 建立有強制回應對話方塊
使用有強制回應對話方塊時在對話方塊彈出後調用函數不會立即返回,而是等到對話方塊銷毀後才會返回(請注意在對話方塊彈出後其他視窗的訊息依然會被傳遞)。所以在使用對話方塊時其他視窗都不能接收使用者輸入。建立有強制回應對話方塊的方法是調用CDialog::DoModal()。下面的代碼示範了這種用法:
CYourView::OnOpenDlg()
{
CYourDlg dlg;
int iRet=dlg.DoModal();
}
CDialog::DoModal()的傳回值為IDOK,IDCANCEL。表明操作者在對話方塊上選擇“確認”或是“取消”。由於在對話方塊銷毀前DoModal不會返回,所以可以使用局部變數來引用對象。在退出函數體後對象同時也會被銷毀。而對於無強制回應對話方塊則不能這樣使用,下節3 建立無強制回應對話方塊中會詳細講解。
你需要根據DoModal()的傳回值來決定你下一步的動作,而得到傳回值也是使用有強制回應對話方塊的一個很大原因。
使用有強制回應對話方塊需要注意一些問題,比如說不要在一些反覆出現的事件處理過程中產生有強制回應對話方塊,比如說在定時器中產生有強制回應對話方塊,因為在上一個對話方塊還未退出時,定時器訊息又會引起下一個對話方塊的彈出。
同樣的在你的對話方塊類中為了向調用者返回不同的值可以調用CDialog::OnOK()或是CDialog::OnCancel()以返回IDOK或IDCANCEL,如果你希望返回其他的值,你需要調用
CDialog::EndDialog( int nResult );其中nResult會作為DoModal()調用的傳回值。
下面的代碼示範了如何使用自己的函數來退出對話方塊:
void CMy52_s1View::OnLButtonDown(UINT nFlags, CPoint point)
{//建立對話方塊並得到傳回值
CView::OnLButtonDown(nFlags, point);
CTestDlg dlg;
int iRet=dlg.DoModal();
CString szOut;
szOut.Format("return value %d",iRet);
AfxMessageBox(szOut);
}
//重載OnOK,OnCancel
void CTestDlg::OnOK()
{//什麼也不做
}
void CTestDlg::OnCancel()
{//什麼也不做
}
//在對話方塊中對三個按鈕訊息進行映射
void CTestDlg::OnExit1()
{
CDialog::OnOK();
}
void CTestDlg::OnExit2()
{
CDialog::OnCancel();
}
void CTestDlg::OnExit3()
{
CDialog::EndDialog(0XFF);
}
由於重載了OnOK和OnCancel所以在對話方塊中按下Enter鍵或Escape鍵時都不會退出,只有按下三個按鈕中的其中一個才會返回。 點擊視窗右上方紅色x按鈕回產生OnClose事件,可以在這裡實現退出。
此外在對話方塊被產生是會自動調用BOOL CDialog::OnInitDialog(),你如果需要在對話方塊顯示前對其中的控制項進行初始化,你需要重載這個函數,並在其中填入相關的初始化代碼。利用ClassWizard可以方便的產生一些預設代碼,首先開啟ClassWizard,選擇相應的對話方塊類,在右邊的訊息列表中選擇WM_INITDIALOG並雙擊,,ClassWizard會自動產生相關代碼,代碼如下:
BOOL CTestDlg::OnInitDialog()
{
/*先調用父類的同名函數*/
CDialog::OnInitDialog();
/*填寫你的初始化代碼*/
return TRUE;
}