MFC非模态对话框实例
【轉載】MFC非模態對話框實例??
2012-06-17 16:21:41|??分類: C++/MFC |??標簽: |字號大中小?訂閱
實例目的
在Windows環境中,對話框是一種常用的輸入輸出手段。對話框有兩種類型,非模態和模態。非模態對話框與模態對話框不同,在非模態對話框活動的同時,用戶還可以在應用程序的其他地方工作,而模態對話框在其關閉之前,用戶不能在同一個應用程序的其他地方工作。本例將從主框架窗口創建一個簡單的非模態對話框,在該對話框關閉之前,用戶可以在主框架窗口中的其他地方工作,比如選擇“打開”文件等。
實現方法
非模態對話框的創建比較復雜。下面介紹具體的方法:
首先,創建一個新的對話框資源,并新建一個類與之關聯(用AppWizard);
其次,調用CDialog的默認構造函數來構造對話框對象(注意,創建的不是窗口),這一步在主框架窗口的構造函數中實現。
再次,調用CDialog::Create成員函數創建窗口,Create把資源ID作為參數,并且,在對話框窗口仍然在屏幕上顯示時,就立刻返回控件。
最后,在關閉非模態對話框時,注意要調用DestroyWindow函數而不是CloseWindow。刪除的只是對話框窗口,對話框對象并未刪除,留待創建新的窗口。在程序退出時,再刪除該對話框對象。這個過程中對話框與主窗口之間消息的傳遞必須由用戶實現,自定義消息映射(在代碼的第10步詳細說明)。
在編程過程中必須準確了解何時構造對話框對象,何時創建對話框窗口,何時刪除對話框。
程序代碼
1.??利用AppWizard生成一個名為ShowModelessDialog的SDI工程,其他步驟均采用VC的默認配置(取消Print?And?PrintView的選定)。
2.??使用對話框編輯器創建對話框資源。從Insert菜單選擇Resource,然后選定Dialog。改變對話框標題為Modeless?Dialog。添加一個靜態文本控件和一個編輯控件。靜態文本控件標題可以任意指定,本例指定為“Password”。
3.??使用ClassWizard創建CModelessDialog類,該類與剛才創建的資源相關聯。添加消息處理函數OnCancel和OnOK,代碼如下:
void?CModelessDialog::OnCancel()?
{
if(m_pView?!=?NULL)
{
//非模式對話框不調用基類CDialog的OnCancel函數
//發送用戶定義的消息WM_GOODBYE
m_pView->PostMessage(WM_GOODBYE,?IDCANCEL);
}
else
{
//模態對話框直接調用基類的OnConcel函數
CDialog::OnCancel();
}
}
void?CModelessDialog::OnOK()?
{
if(m_pView?!=?NULL)
{
//非模式對話框不調用基類CDialog的OnOK函數
UpdateData(TRUE);
m_pView->PostMessage(WM_GOODBYE,?IDOK);
}
else
{
//模態對話框直接調用基類的OnOK函數
CDialog::OnOK();
}
}
4.??為CModelessDialog類增加如下成員變量和構造函數原型:
private:
CView?*m_pView; //指向調用此對話框的視類對象的指針
Public:
CModelessDialog(CView?*pView); //保留原有的構造函數,從而可以兼容模態對話框
BOOL?Create();
5.??在CModelessDialog.h中定義WM_GOODBYE消息的ID:
#define?WM_GOODBYE?WM_USER+5
6.??在CModelessDialog.cpp中增加非模態的構造函數和Create函數:
CModelessDialog::CModelessDialog(CView?*pView)
{
//非模態對話框的構造函數,m_pView不為空
m_pView?=?pView;
}
BOOL?CModelessDialog::Create()
{
return?CDialog::Create(CModelessDialog::IDD);
}
7.??在CShowModelessDialogView.h中添加一個指向非模態對話框的指針:
private:
CModelessDialog?*m_pDlg;
8.??在CShowModelessDialogView.cpp中修改構造函數和析構函數。構造函數在堆上構造對話框對象,并且最終由視圖析構函數刪除它:
CShowModelessDialogView::CShowModelessDialogView()
{
//?TODO:?add?construction?code?here
//在堆中生成CModelessDialog對象
m_pDlg?=?new?CModelessDialog(this);
}
CShowModelessDialogView::~CShowModelessDialogView()
{
//刪除對話框對象,釋放堆空間
delete?m_pDlg;
}
9.??在CShowModelessDialogView.cpp中添加代碼到虛函數OnDraw中,提示用戶按下選擇“演示?->?非模態對話框”來進行演示,并添加頭文件的包含語句:
#include?“ModelessDialog.h”
void?CShowModelessDialogView::OnDraw(CDC*?pDC)
{
//?TODO:?add?draw?code?for?native?data?here
pDC->TextOut(0,?0,?"請選擇?演示?->?非模態對話框?進行演示");
}
10.??為WM_GOODBYE增加自己的消息代碼。因為ClassWizard不支持用戶定義的消息,所以,我們必須自己編寫代碼。
在CShowModelessDialogView.cpp中,BEGIN_MESSAGE_MAP語句之后AFX_MSG_MAP括號外增加如下代碼,定義消息映射:
ON_MESSAGE(WM_GOODBYE,?OnGoodbye);
在CShowModelessDialogView.h中,DECLARE_MESSAGE_MAP語句之前AFX_MSG括號之外,增加如下消息映射的聲明:
afx_msg?LRESULT?OnGoodbye(WPARAM?wParam,?LPARAM?lParam);
同樣,在CShowModelessDialogView.cpp中,增加消息處理函數:
LRESULT?CShowModelessDialogView::OnGoodbye(WPARAM?wParam,?LPARAM?lParam)
{
//輸出按鈕的ID,OK按鈕ID為1,CANCLE按鈕ID為2
//可以根據此消息進行用戶的工作
TRACE("CShowModelessDialogView::OnGoodbye?%x,?%x\n",?wParam);
m_pDlg->DestroyWindow();
return?0L;
}
11.??使用菜單編輯器添加菜單項“演示—〉非模式對話框”,對應ID為ID_MODELESS。為它創建消息處理函數如下:
void?CShowModelessDialogView::OnShowMD()?
{
//如果對話框窗口不存在則創建一個
if(m_pDlg->GetSafeHwnd()?==?0)
{
//創建對話框窗口,顯示Show?Modeless?Dialog對話框
m_pDlg->Create();
}
}
編譯并運行該程序,選擇“演示—〉非模式對話框”,非模態對話框Modeless?Dialog跳出,這時,我們仍可以在該對話框中工作,也可以在應用程序的其他地方工作,譬如選擇“文件?—〉打開”,就會跳出打開文件對話框。但是打開文件對話框是模態對話框,所以在關閉它之前我們不能在應用程序的其他地方工作了。從中我們也可以體會到非模態對話框與模態對話框的不同。
本例中對非模態對話框傳遞的消息并未做處理,只是簡單的輸出了用戶所做的選擇:確定或取消。如果讀者想要根據傳遞的消息做一些工作,可以自己添加代碼實現。
總結
以上是生活随笔為你收集整理的MFC非模态对话框实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 请问:如何实现文件日志功能?要求每天换一
- 下一篇: MATLAB figure中提取数据