無模式對話方塊與有模式對話方塊不同的是在建立後其他視窗都可以繼續接收使用者輸入,因此無模式對話方塊有些類似一個彈出視窗。建立無模式對話方塊需要呼叫
BOOLCDialog::Create(UINTnIDTemplate,CWnd*pParentWnd=NULL);之後還需要呼叫BOOLCDialog::ShowWindow(SW_SHOW);進行顯示,否則無模式對話方塊將是不可見的。相關程式碼如下:
voidCYourView::OnOpenDlg(void)
{
/*假設IDD_TEST_DLG為已經定義的對話方塊資源的ID號*/
CTestDlg*dlg=newCTestDlg;
dlg->Create(IDD_TEST_DLG,NULL);
dlg->ShowWindows(SW_SHOW);
/*不要呼叫deletedlg;*/
}
在上面的程式碼中我們新生成了一個對話方塊物件,而且在退出函式時並沒有銷燬該物件。因為如果此時銷燬該物件(物件被銷燬時視窗同時被銷燬),而此時對話方塊還在顯示就會出現錯誤。那麼這就提出了一個問題:什麼時候銷燬該物件。我時常使用的方法有兩個:
在對話方塊退出時銷燬自己:在對話方塊中過載OnOK與OnCancel在函式中呼叫父類的同名函式,然後呼叫DestroyWindow()強制銷燬視窗,在對話方塊中對映WM_DESTROY訊息,在訊息處理函式中呼叫deletethis;強行刪除自身物件。相關程式碼如下:
voidCTestDlg1::OnOK()
CDialog::OnOK();
DestroyWindow();
voidCTestDlg1::OnCancel()
CDialog::OnCancel();
voidCTestDlg1::OnDestroy()
CDialog::OnDestroy();
AfxMessageBox("calldeletethis");
deletethis;
透過向父親視窗傳送訊息,要求其他視窗對其進行銷燬:首先需要定義一個訊息用於進行通知,然後在對話方塊中對映WM_DESTROY訊息,在訊息處理函式中呼叫訊息傳送函式通知其他視窗。在接收訊息的視窗中利用ON_MESSAGE對映處理訊息的函式,並在訊息處理函式中刪除對話方塊物件。相關程式碼如下:/*更改對話方塊的有關檔案*/
CTestDlg2::CTestDlg2(CWnd*pParent/*=NULL*/)
:CDialog(CTestDlg2::IDD,pParent)
{/*m_pParent為一成員變數,用於儲存通知視窗的指標,
所以該指標不能是一個臨時指標*/
ASSERT(pParent);
m_pParent=pParent;
//{{AFX_DATA_INIT(CTestDlg2)
//NOTE:theClassWizardwilladdmemberinitializationhere
//}}AFX_DATA_INIT
voidCTestDlg2::OnOK()
voidCTestDlg2::OnCancel()
voidCTestDlg2::OnDestroy()
/*向其他視窗傳送訊息,將自身指標作為一個引數傳送*/
m_pParent->PostMessage(WM_DELETE_DLG,(WPARAM)this);
/*在訊息接收視窗中新增訊息對映*/
/*在標頭檔案中新增函式定義*/
afx_msgLONGOnDelDlgMsg(WPARAMwP,LPARAMlP);
/*新增訊息對映程式碼*/
ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg)
END_MESSAGE_MAP()
/*實現訊息處理函式*/
LONGCMy53_s1View::OnDelDlgMsg(WPARAMwP,LPARAMlP)
delete(CTestDlg2*)wP;
return0;
/*建立對話方塊*/
voidCMy53_s1View::OnTest2()
CTestDlg2*dlg=newCTestDlg2(this);
dlg->Create(IDD_TEST_DLG_2);
dlg->ShowWindow(SW_SHOW);
在這種方法中我們利用訊息來進行通知,在Window系統中利用訊息進行通知和傳遞資料的用法是很多的。
同樣無模式對話方塊的另一個作用還可以用來在使用者在對話方塊中的輸入改變時可以及時的反映到其他視窗。下面的程式碼演示了在對話方塊中輸入一段文字,然後將其更新到檢視的顯示區域中,這同樣也是利用了訊息進行通知和資料傳遞。
/*在對話方塊中取出資料,並向其他視窗傳送訊息和資料,將資料指標作為一個引數傳送*/
voidCTestDlg2::OnCommBtn()
charszOut[30];
GetDlgItemText(IDC_OUT,szOut,30);
m_pParent->SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut);
/*在訊息接收視窗中*/
/*對映訊息處理函式*/
ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)
/*在檢視中繪製出字串m_szOut*/
voidCMy53_s1View::OnDraw(CDC*pDC)
CMy53_s1Doc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:adddrawcodefornativedatahere
pDC->TextOut(0,0,"DisplayString");
pDC->TextOut(0,20,m_szOut);
/*處理通知訊息,儲存資訊並更新顯示*/
LONGCMy53_s1View::OnDlgNotifyMsg(WPARAMwP,LPARAMlP)
m_szOut=(char*)wP;
Invalidate();
此外這種用法利用訊息傳遞資料的方法對有模式對話方塊和其他的視窗間通訊也一樣有效。
無模式對話方塊與有模式對話方塊不同的是在建立後其他視窗都可以繼續接收使用者輸入,因此無模式對話方塊有些類似一個彈出視窗。建立無模式對話方塊需要呼叫
BOOLCDialog::Create(UINTnIDTemplate,CWnd*pParentWnd=NULL);之後還需要呼叫BOOLCDialog::ShowWindow(SW_SHOW);進行顯示,否則無模式對話方塊將是不可見的。相關程式碼如下:
voidCYourView::OnOpenDlg(void)
{
/*假設IDD_TEST_DLG為已經定義的對話方塊資源的ID號*/
CTestDlg*dlg=newCTestDlg;
dlg->Create(IDD_TEST_DLG,NULL);
dlg->ShowWindows(SW_SHOW);
/*不要呼叫deletedlg;*/
}
在上面的程式碼中我們新生成了一個對話方塊物件,而且在退出函式時並沒有銷燬該物件。因為如果此時銷燬該物件(物件被銷燬時視窗同時被銷燬),而此時對話方塊還在顯示就會出現錯誤。那麼這就提出了一個問題:什麼時候銷燬該物件。我時常使用的方法有兩個:
在對話方塊退出時銷燬自己:在對話方塊中過載OnOK與OnCancel在函式中呼叫父類的同名函式,然後呼叫DestroyWindow()強制銷燬視窗,在對話方塊中對映WM_DESTROY訊息,在訊息處理函式中呼叫deletethis;強行刪除自身物件。相關程式碼如下:
voidCTestDlg1::OnOK()
{
CDialog::OnOK();
DestroyWindow();
}
voidCTestDlg1::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
voidCTestDlg1::OnDestroy()
{
CDialog::OnDestroy();
AfxMessageBox("calldeletethis");
deletethis;
}
透過向父親視窗傳送訊息,要求其他視窗對其進行銷燬:首先需要定義一個訊息用於進行通知,然後在對話方塊中對映WM_DESTROY訊息,在訊息處理函式中呼叫訊息傳送函式通知其他視窗。在接收訊息的視窗中利用ON_MESSAGE對映處理訊息的函式,並在訊息處理函式中刪除對話方塊物件。相關程式碼如下:/*更改對話方塊的有關檔案*/
CTestDlg2::CTestDlg2(CWnd*pParent/*=NULL*/)
:CDialog(CTestDlg2::IDD,pParent)
{/*m_pParent為一成員變數,用於儲存通知視窗的指標,
所以該指標不能是一個臨時指標*/
ASSERT(pParent);
m_pParent=pParent;
//{{AFX_DATA_INIT(CTestDlg2)
//NOTE:theClassWizardwilladdmemberinitializationhere
//}}AFX_DATA_INIT
}
voidCTestDlg2::OnOK()
{
CDialog::OnOK();
DestroyWindow();
}
voidCTestDlg2::OnCancel()
{
CDialog::OnCancel();
DestroyWindow();
}
voidCTestDlg2::OnDestroy()
{
CDialog::OnDestroy();
/*向其他視窗傳送訊息,將自身指標作為一個引數傳送*/
m_pParent->PostMessage(WM_DELETE_DLG,(WPARAM)this);
}
/*在訊息接收視窗中新增訊息對映*/
/*在標頭檔案中新增函式定義*/
afx_msgLONGOnDelDlgMsg(WPARAMwP,LPARAMlP);
/*新增訊息對映程式碼*/
ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg)
END_MESSAGE_MAP()
/*實現訊息處理函式*/
LONGCMy53_s1View::OnDelDlgMsg(WPARAMwP,LPARAMlP)
{
delete(CTestDlg2*)wP;
return0;
}
/*建立對話方塊*/
voidCMy53_s1View::OnTest2()
{
CTestDlg2*dlg=newCTestDlg2(this);
dlg->Create(IDD_TEST_DLG_2);
dlg->ShowWindow(SW_SHOW);
}
在這種方法中我們利用訊息來進行通知,在Window系統中利用訊息進行通知和傳遞資料的用法是很多的。
同樣無模式對話方塊的另一個作用還可以用來在使用者在對話方塊中的輸入改變時可以及時的反映到其他視窗。下面的程式碼演示了在對話方塊中輸入一段文字,然後將其更新到檢視的顯示區域中,這同樣也是利用了訊息進行通知和資料傳遞。
/*在對話方塊中取出資料,並向其他視窗傳送訊息和資料,將資料指標作為一個引數傳送*/
voidCTestDlg2::OnCommBtn()
{
charszOut[30];
GetDlgItemText(IDC_OUT,szOut,30);
m_pParent->SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut);
}
/*在訊息接收視窗中*/
/*對映訊息處理函式*/
ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)
/*在檢視中繪製出字串m_szOut*/
voidCMy53_s1View::OnDraw(CDC*pDC)
{
CMy53_s1Doc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:adddrawcodefornativedatahere
pDC->TextOut(0,0,"DisplayString");
pDC->TextOut(0,20,m_szOut);
}
/*處理通知訊息,儲存資訊並更新顯示*/
LONGCMy53_s1View::OnDlgNotifyMsg(WPARAMwP,LPARAMlP)
{
m_szOut=(char*)wP;
Invalidate();
return0;
}
此外這種用法利用訊息傳遞資料的方法對有模式對話方塊和其他的視窗間通訊也一樣有效。