模态对话框与非模态对话框的创建及的几种销毁方法与区别
2017-10-19 16:39
295 查看
对话框的创建:
CDialogEx* g_pDlg = NULL; 全局对话框指针模态对话框
void A()
{
CTest dlg;
dlg.DoModal(); //程序在这里暂停,只有关闭后才能往下执行
//只有关闭了 dlg创建的窗口才能执行到这里
}
非模态对话框 (可以直接使用,我正在用)
void A()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(NULL != g_pDlg->GetSafeHwnd())
{
g_pDlg->ShowWindow(SW_SHOW);
return 1;
}
CTest* pDlg = new CTest();
pDlg->Create:(IDD_TEST_DLG); //IDD_TEST_DLG 对话框ID
pDlg->ShowWindow(SW_SHOW);
}
void CTest::PostNcDestroy()
{
CDialogEx::PostNcDestroy();
delete this;
}
模态对话框与非模态对话的几种销毁方法与区别
先着一个注意点,自己误识了好久:
CloseWindow是一个函数,可以用来最小化指定的窗口,但并不销毁该窗口。
OnClose();
//关闭对话框,但不销毁该窗口, 可以用 ShowWindow(SHOW_WINDOW);重新显示
先说下模式对话框调用的原则。
在模式对话框下,用CDialog::OnOK()或CDialog::OnCancel()以及CDialog::OnClose()关闭对话框。
一定要注意之前的CDialog::(当然,你可以重载你自己对话框的这个虚函数,但是,后面必须调用基类的CDialog::)
具体我们再参照深入浅出的风格,来个解刨。
CDialog::Close()默认调用CDialog::OnCancel(),
CDialog::OnCancel()调用CDialog::EndDialog(IDCANCEL);
CDialog::EndDialog(IDCANCEL)调用CDialog::DestroyWindows(),
CDialog::DestroyWindows调用CDialog::OnDestroy();
CDialog::OnOK()调用CDialog::EndDialog(IDOK).
CDialog::EndDialog(IDOK)调用UpdateData()和CDialog::DestroyWindows(),
CDialog::DestroyWindows调用CDialog::OnDestroy()
看来上面你可能就知道了如下的过程
CDialog::Close()==>CDialog::OnCancel()==>CDialog::EndDialog(IDCANCEL)
CDialog::OnOK()==>CDialog::EndDialog(IDOK)
CDialog::DestroyWindows()==>CDialog::OnDestroy()
CDialog::EndDialog(IDOK) ==
CDialog::UpdateData() + CDialog::DestroyWindows()==>CDialog::OnDestroy()
CDialog::EndDialog(IDCANCEL) ==CDialog::DestroyWindows()==>CDialog::OnDestroy()
而CDialog::EndDialog(IDOK)跟CDialog::EndDialog(IDCANCEL)的区别就是,少了一个CDialog::UpdateData(),也就是CDialog::EndDialog(IDOK),在关闭对话框后,会把对话框上控件关联的变量的值更新为用户最后输入的值。而CDialog::EndDialog(IDCANCEL)就不会更新这个值。
希望自己把模式对话框的关闭讲清楚了。
下面说说非模态对话框。
调用原则是: 一定要用DestroyWindow()来结束非模态对话框...因为调用CDialog::Create() 时是在堆上 new的对象...需要DestroyWindow来delete 对象..不然会存在资源泄漏的风险...,不要用WM_CLOSE消息,它不会销毁非模态对话框,用DestroyWindow()是最正确的方法(当然,你可以在响应WM_CLOSE的时候调用
Destroywindow)
在无模式对话框,重载你自己的OnOK(),就是CMyDialog::OnOK()调用CDialog::DestroyWindows()。
注意:重载的OnOk中不不要调用父类的OnOk即CDialog::OnOK(),因为CDialog::OnOK()会调用EndDialog,而EndDialog是模态对话框专用的。
重载CMyDialog::OnCancel()调用CDialog::DestroyWindows()。
注意:重载的OnCancel中不不要调用父类的OnCancel即CDialog::OnCancel(),因为CDialog::OnCancel()会调用EndDialog,而EndDialog是模态对话框专用的。
听起来很简单,但是下面提到一个很具体的编程问题。
一般,我们用非模态对话框都是全局的,也就是通过new来创建,是在heap上的,而不是在stack上的。
这样我们当然还要通过delete 来销毁对象,不然可是有内存泄漏的。那么我们什么时候delete这个对象呢?
在msdn上面我们可以看到微软提供的方法是:WM_NCDESTROY
响应这个消息的时候是delete掉非模态对话对象的最佳时机
所以我们要响应WM_NCDESTROY消息:
void CMainShowDlg::OnNcDestroy() { CDialog::OnNcDestroy(); delete this; }
这样的话,我们的类就会Auto-Cleanup了。
相关文章推荐
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 非模态对话框相对于模态对话框,他的创建和销毁过程和模态对话框有一定的区别
- MFC创建模态对话框和非模态对话框的方法
- 模态对话框与非模态对话的几种销毁方法与区别
- java中创建线程的几种方法及区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框的销毁过程与非模态对话的几种销毁方法
- 模态对话框与非模态对话的几种销毁方法与区别
- VC中非模态对话框相对于模态对话框的创建和销毁过程
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- 模态对话框与非模态对话的几种销毁方法与区别
- JAVA中创建一个对象有哪几种方法,有什么区别?
- 创建模态对话框和非模态对话框的方法