無模式對話框

無模式對話框的創建:

1. 添加對話框資源,假設其資源名爲IDD_DIALOG1

2. 爲對話框創建類,假設其類名爲CTestDlg

3. 在stdafx.h文件中加入對CTestDlg類的頭文件引用, #include “TestDlg.h”

4. 在引用CTestDlg類的頭文件中添加成員變量:
    public:
            
CTestDlg dlg;

5. 顯示無模式對話框:
   
dlg.Create(IDD_DIALOG1,this); 
    dlg.ShowWindow(SW_SHOW);

這樣,一個無模式對話框就創建好了。然後,我設了一個計時器,讓它在5秒鐘後自動關閉。這很常用,一般都是以事件作爲驅動,多線程應用中比較多見。比如,在網絡通信中,一個操作可能需要較多的時間,爲了讓用戶知道程序在做些什麼,需要有這麼一個提示對話框。在操作完畢後自動關閉。現在就以計時器定時來驅動這個無模式對話框。

無模式對話框的關閉:

SetTimer(1,5000,NULL); //啓用計時器

響應WM_TIMER消息,在OnTimer中寫如下代碼:

if( nIDEvent == 1)
{
        dlg.PostMessage(WM_CLOSE); //向對話框發送關閉消息
        KillTimer(1);

}

無模式對話框的創建與使用
作者:張連成

在編程過程中,對話框經常用到,但對無模式和模式對話框的創建和銷燬過程,經常有誤解,下面提供一個無模式對話框的例子來剖析無模式對話框的形成:

無模式對話框與有模式對話框不同的是在創建後其他窗口都可以繼續接收用戶輸入,因此無模式對話框有些類似一個彈出窗口。創建無模式對話框需要調用BOOL CDialog::Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );之後還需要調用BOOL CDialog::ShowWindow( SW_SHOW);進行顯示,否則無模式對話框將是不可見的。相關代碼如下:

void CYourView::OnOpenDlg(void)
{
 /*假設IDD_TEST_DLG爲已經定義的對話框資源的ID號*/
 
 CTestDlg *dlg=new CTestDlg;
 dlg->Create(IDD_TEST_DLG,NULL);
 dlg->ShowWindows(SW_SHOW);
 
 /*不要調用 delete dlg;*/
}
在上面的代碼中我們新生成了一個對話框對象,而且在退出函數時並沒有銷燬該對象。因爲如果此時銷燬該對象(對象被銷燬時窗口同時被銷燬),而此時對話框還在顯示就會出現錯誤。那麼這就提出了一個問題:什麼時候銷燬該對象。我時常使用的方法有兩個:
在對話框退出時銷燬自己:在對話框中重載OnOK與OnCancel在函數中調用父類的同名函數,然後調用DestroyWindow()強制銷燬窗口,在對話框中映射WM_DESTROY消息,在消息處理函數中調用delete this;強行刪除自身對象。相關代碼如下:
void CTestDlg1::OnOK()
{
 CDialog::OnOK();
 DestroyWindow();
}

void CTestDlg1::OnCancel()
{
 CDialog::OnCancel();
 DestroyWindow();
}

void CTestDlg1::OnDestroy() 
{
 CDialog::OnDestroy();
 AfxMessageBox("call delete this");
 delete this;
}
這種方法的要點是在窗口被銷燬的時候,刪除自身對象。所以你可以在任何時候調用DestroyWindow()以達到徹底銷燬自身對象的作用。(DestroyWindow()的調用會引起OnDestroy()的調用) 通過向父親窗口發送消息,要求其他窗口對其進行銷燬:首先需要定義一個消息用於進行通知,然後在對話框中映射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: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
}

void CTestDlg2::OnOK()
{
 CDialog::OnOK();
 DestroyWindow();
}

void CTestDlg2::OnCancel()
{
 CDialog::OnCancel();
 DestroyWindow();
}

void CTestDlg2::OnDestroy() 
{
 CDialog::OnDestroy();
 /*向其他窗口發送消息,將自身指針作爲一個參數發送*/
 m_pParent->PostMessage(WM_DELETE_DLG,(WPARAM)this);
}
在頭文件中添加函數定義
afx_msg LONG OnDelDlgMsg(WPARAM wP,LPARAM lP);
添加消息映射代碼
ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg)
/*實現消息處理函數*/
LONG CMy53_s1View::OnDelDlgMsg(WPARAM wP,LPARAM lP)
{
 delete (CTestDlg2*)wP;
 return 0;
}

/*創建對話框*/
void CMy53_s1View::OnTest2() 
{
 CTestDlg2 *dlg=new CTestDlg2(this);
 dlg->Create(IDD_TEST_DLG_2);
 dlg->ShowWindow(SW_SHOW);
}
在這種方法中我們利用消息來進行通知,在Windows系統中利用消息進行通知和傳遞數據的用法是很多的。 同樣無模式對話框的另一個作用還可以用來在用戶在對話框中的輸入改變時可以及時的反映到其他窗口。下面的代碼演示了在對話框中輸入一段文字,然後將其更新到視圖的顯示區域中,這同樣也是利用了消息進行通知和數據傳遞。
/*在對話框中取出數據,並向其他窗口發送消息和數據,將數據指針作爲一個參數發送*/
void CTestDlg2::OnCommBtn() 
{
 char szOut[30];
 GetDlgItemText(IDC_OUT,szOut,30);
 m_pParent->SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut);
}
在消息接收窗口中映射消息處理函數
ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)
/*在視圖中繪製出字符串 m_szOut*/
void CMy53_s1View::OnDraw(CDC* pDC)
{
 CMy53_s1Doc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
 pDC->TextOut(0,0,"Display String");
 pDC->TextOut(0,20,m_szOut);
}

/*處理通知消息,保存信息並更新顯示*/
LONG CMy53_s1View::OnDlgNotifyMsg(WPARAM wP,LPARAM lP)
{
 m_szOut=(char*)wP;
 Invalidate();
 return 0;
}
希望通過以上的講解,理解無模式對話框的創建和使用過程. 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章