①、模态对话框与非模态对话框的区别:
模态对话框:一旦创建模态对话框,则无法操作父对话框,只能操作当前创建的模态对话框,关闭当前模态对话框后才可以操作父对话框非模态对话框:和模态对话框相反,创建该对话框后可以继续操作父对话框
②、新对话框资源的添加及相关类的绑定:
首先是先创建一个对话框模板资源,在资源文件里鼠标放到工程名上左击然后选择添加,在选中资源,最后选择Dialog确定即可,然后在新生成的对话里,修改名字或者id,最后为窗口关联一个类,即选择新创建的窗口,右击添加类,选择基类为CDialog,添加类名即可关联,如果接下来就是在主窗口里创建模态或者非模态对话框即可,如下操作
③、模态对话框的创建:CDialog::DoModal
//模态对话框的创建
void CMFCtestDlg::OnCreateDialog()
{
//创建好模态对话框以后,程序就会阻塞在这里,后面的程序无法执行
//直到模态对话框被关闭
CMydialog dlg;
dlg.DoModal();
MessageBox(_T("关闭模态对话框后显示该窗口"));
}
④、非模态对话框的创建:CDialog::Create
//这样创建会出现问题,对话框一闪而过
void CMFCtestDlg::OnCreateNoDlg()
{
CMydialog dlg;//在这里定义的局部变量容易被释放,因此需要全局定义
dlg.Create(IDD_My_DIALOG,this);
dlg.ShowWindow(SW_SHOW);
//MessageBox(_T("非模态对话框显示同时显示该窗口"));
}
在创建非模态对话框时尽量不要申请局部变量,因为局部变量一旦执行完就会被释放,创建的非模态对话框也会被消除,通常申请变量 在堆中申请内存:new、malloc 。 静态存储区域:全局变量
使用全局变量进行解决:
使用全局变量进行解决:
//非模态对话框创建
//把窗口定义为全局变量,避免被释放
CMydialog dlg;
void CMFCtestDlg::OnCreateNoDlg()
{
//CMydialog dlg;//在这里定义的局部变量容易被释放,因此需要全局定义
dlg.Create(IDD_My_DIALOG,this);
dlg.ShowWindow(SW_SHOW);
//MessageBox(_T("非模态对话框显示同时显示该窗口"));
}
但是这种创建点击取消后第二次打开出现错误,其原因是非模态对话框需要我们自己释放资源,在CMydialog窗口类中添加取消的函数。以及添加确定的函数进行释放,如下,一般都是进行类向导或者点资源里面选择这个类并对其函数进行重载
具体如下:
void CMydialog::OnCancel()
{
DestroyWindow();
//CDialog::OnCancel();
}
void CMydialog::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
DestroyWindow();
//CDialog::OnOK();
}
这样就解决了二次创建出错的问题
使用new进行申请:
// CMFCtestDlg 对话框
class CMFCtestDlg : public CDialogEx
{
// 构造
public:
CMFCtestDlg(CWnd* pParent = nullptr); // 标准构造函数
CMydialog* pDlg;
}
//非模态对话框创建
void CMFCtestDlg::OnCreateNoDlg()
{
//CMydialog dlg;//在这里定义的局部变量容易被释放,因此需要全局定义
pDlg = new CMydialog();
pDlg->Create(IDD_My_DIALOG,this);
pDlg->ShowWindow(SW_SHOW);
//MessageBox(_T("非模态对话框显示同时显示该窗口"));
}
同样的问题,第二次打开出现错误,因为是没有释放,这时候还是需要重载类的函数,具体操作是在类向导,打开选择这个CMydialog类,然后选择重载函数,找到这个PostNcDestroy,然后添加如下代码即可。
void CMydialog::PostNcDestroy()
{
// TODO: 在此添加专用代码和/或调用基类
delete this;
CDialog::PostNcDestroy();
}
最后就是如果我们需要在模态或者非模态对话框进行初始化操作,这时你会发现对应的.cpp文件是没有BOOL CMydialog::OnInitDialog(),如何调出来呢?很简单,还是使用类向导进行重载即可,找到OnInitDialog()进程重载即可。