1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:class CTestDlg : public CDialog
2.创建话话框对象
模态对话框的创建:
如:
CTestDlg dlg;
dlg.DoModal();
非模态对话框创建:
如:
CTestDlg dlg;
dlg.Create(IDD_DIALOG, this);
但这样是得不到一个正常显示的非模态对话框的。因为模态与非模态对话框的实现方式并不相同,这里我们还要注意几点。
- 非模态对话框创建完成后是隐藏着的,必须调用ShowWindow来进行显示。
- 对于模态对话框,当执行到DoModal 函数以创建对话框时,程序会暂停执行,直至模态对话框关闭。所以创建模态对话框可以采用局部对象。
但是,对于非模态对话框,当执行Create函数时并不会暂停执行,当执行到大括号"}后Dlg局部对象被销毁生命周期结束,于是异常出现了。
解决方法有两个:
一、在View类中定义一个CTestDlg 成员变量。
二、动态创建一个CTestDlg 变量,并重写CTestDlg 类的 PostNcDestroy函数,在该函数里销毁对象 delete this; - 无论创建的是模态对话框,还是非模态对话框,当我们单击确定或取消按钮后对话框都会消失。但这时低层的操作却是不同的。
对于模态对话框,此时对话框对象的确是被销毁了,但对于非模态对话框,这时只是隐藏起来不再显示。这需要我们自己调用DestoryWindow函数来进行销毁工作。
这时我们必须重写 CTestDlg 的 OnOK 、 OnCancel 两个函数(这两个是基类CDialog的虚函数),在这两个函数内调用DestroyWindow函数,并注意不再调用基类CDialog相应的函数。
正确地创建非模态对话框的代码如下:
CTestDlg *pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);
同时,在CTestDlg 类的 PostNcDestroy函数中销毁对象:delete this;
非模态对话框相对于模态对话框,他的创建和销毁过程和模态对话框有一定的区别,MSDN:When you implement a modeless dialog box, always override the On
MSDN:非模态对话框需要重载函数On
还有一个必须重载的函数就是PostNcDestroy,这也是一个虚函数,通常的非模态对话框是用类的指针,通过new创建的,这就需要在PostNcDestroy函数中delete掉这个指针。
参考以下简单例子:
CMainDlg CPP:
class CMainDlg : public CDialog
{
public:
CMainDlg(CWnd* pParent = NULL); // standard constructor
void BoxDone();
// Dialog Data
//{{AFX_DATA(CMainDlg)
enum { IDD = IDD_MAIN_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
CAdderDialog* m_pModeless;
// Generated message map functions
//{{AFX_MSG(CMainDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMainDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMainDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pModeless = NULL;
}
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
//{{AFX_MSG_MAP(CMainDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CMainDlg message handlers
void CMainDlg::OnOK() //enter
{
// if our modeless child isn't already up, create it and display it
// otherwise, just set focus to it
if (m_pModeless == NULL)
{
m_pModeless = new CAdderDialog(this);
if (m_pModeless->Create() == TRUE)
GetDlgItem(IDOK)->EnableWindow(FALSE);
}
else
m_pModeless->SetActiveWindow();
}
void CMainDlg::BoxDone()
{
// this function is called by the modeless dialog as it terminates
// just reset our pushbutton to be enabled again.
// I _don't_ delete the MFC CDialog object because the dialog's own
// code will do that.
m_pModeless = NULL;
// don't delete m_pModeless; !
GetDlgItem(IDOK)->EnableWindow();
}
CAdderDialog CPP:
class CAdderDialog : public CDialog
{
// Construction
public:
CAdderDialog(CWnd* pParent); // standard constructor
BOOL Create();
// Dialog Data
//{{AFX_DATA(CAdderDialog)
enum { IDD = IDD_ADDME };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAdderDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
protected:
CWnd* m_pParent;
int m_nID;
// Generated message map functions
//{{AFX_MSG(CAdderDialog)
virtual void OnOK();
virtual void OnCancel();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAdderDialog::CAdderDialog(CWnd* pParent)
: CDialog(CAdderDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CAdderDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
ASSERT(pParent != NULL);
m_pParent = pParent;
m_nID = CAdderDialog::IDD;
}
BEGIN_MESSAGE_MAP(CAdderDialog, CDialog)
//{{AFX_MSG_MAP(CAdderDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CAdderDialog message handlers
void CAdderDialog::OnOK()
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_NEWTEXT);
CListBox* pList = (CListBox*) (m_pParent->GetDlgItem(IDC_LIST));
ASSERT(pList != NULL);
ASSERT(pEdit != NULL);
if (pList != NULL && pEdit != NULL)
{
CString str;
pEdit->GetWindowText(str);
pList->AddString(str);
}
// ((CMainDlg*)m_pParent)->BoxDone();
// DestroyWindow();
}
BOOL CAdderDialog::Create()
{
return CDialog::Create(m_nID, m_pParent);
}
void CAdderDialog::OnCancel() //CAdderDialog::done
{
((CMainDlg*)m_pParent)->BoxDone();
DestroyWindow();
}
void CAdderDialog::PostNcDestroy()
{
delete this;
}
自:http://www.cnblogs.com/lidabo/archive/2012/07/19/2598646.html