所有的对话框类都基于CDialog基类,CDialog类又继承于CWnd类。对话框分为模态对话框和非模态对话框
(一)创建模态对话框:
void CMyboleView::OnDialog()
{
// TODO: Add your command handler code here
CTestDlg dlg;
dlg.DoModal();
}
CDialog::DoModal()创建、显示模态对话框并停止程序直到模态对话框被关闭,细心的同学会发现,你定义的对话框类的对象是个局部变量,当OnDialog函数一旦执行完毕那么对象dlg的生命周期就结束了,与该对象相关联的对话框就会被销毁了,也就是说你创建的对话框会一闪而逝或者不显示了,事实会是这样吗?不会,因为当执行到DoModal函数时,程序会在该条语句处停止,这也是DoModal函数的一个功能,直到模态对话框关闭(用EndDialog函数来关闭一个模态对话框),也就是说dlg的生命周期的结束是在模态对话框结束关闭的时候。
CDialog::EndDialog()关闭一个模态对话框,该函数的返回值作为DoModal的返回值,它只是隐藏了模态对话框,并没有将之销毁。
(二)创建非模态对话框:
void CMyboleView::OnDialog()
{
// TODO: Add your command handler code here
CTestDlg dlg;
dlg.DoModal();
}
CDialog::Create()创建一个非模态对话框并将该非模态对话框资源与dlg对象相关联,该函数的功能比较弱,在调用该函数创建一个非模态对话框还需要调用dlg.ShowWindow(SW_SHOW)函数来显示。因为该函数没有DoModal的停止功能,所以dlg对象不能是局部变量,也就是说dlg的生命周期不能随着OnDialog函数的结束而结束,解决办法有二,第一种是将dlg设置成全局变量,第二种是定义一个指针子,再堆上分配内存,用new来分配一个堆空间(堆空间里的变量的生命周期与整个程序的生命周期是一致的),代码如下:
voidCMyboleView::OnDialog()
{
// TODO: Add your command handler codehere
/*CTestDlg dlg;
dlg.DoModal();
CTestDlg dlg;
dlg.Create(IDD_DIALOG1,this);
dlg.ShowWindow(SW_SHOW);*/
CTestDlg *pDlg=new CTestDlg();
pDlg->Create(IDD_DIALOG1,this);
pDlg->ShowWindow(SW_SHOW);
}
不过一旦该函数结束后,创建的非模态对话框就不能被引用了。因为OnDialog函数结束后pDlg的生命周期结束了,就不能通过指针pDlg保存的地址来找到原先分配的内存了,需要在析构函数中delete这块内存。
CWnd::ShowWindow()用来设置一个窗体的显示状态,因为对话框类继承于CWnd,所以对话框也是一个窗口。
(三)小结:
OnOk和OnCancel函数是CDialog类的虚函数。
对于模态对话框上的Ok按钮和cancel按钮被点击时,如果OnOk和OnCancel函数没有被覆盖,那么就会调用CDialog类的OnOk和OnCancel函数,此时模态对话框会被destroy掉。
对于非模态对话框上的Ok按钮和Cancel按钮被点击时,如果OnOk和OnCancel函数也没有被覆盖,那么程序调用的也是CDialog类的OnOk和OnCancel函数,但这两个函数仅仅使非模态对话框不可见,所以当在一个非模态对话框上实现Ok按钮时必须重写OnOk函数,并且在重写的OnOk函数里调用DestroyWindow函数,不要调用基类的EndDialog函数。