这几天调一个程序时,遇到一个和OnOK, OnCancel有关的bug, 于是整理一下写了下面这篇文章。
首先OnOK是对ID_OK的响应, OnCancel是对IDCANCEL的响应. 前者对应键盘的Enter, 后者对应Esc.
两个函数都是CDialog类的virtual的成员函数, 也就是MFC是希望你去重载它们. 两个函数有一个共同点,就是都会调用EndDialog. 当然是调用CDialog的EndDialog. 那么这个EndDialog做个什么事呢? 看看MSDN上怎么说.
下面这段是从MSDN上摘下来的:
Call this method to destroy a modal dialog box
Do not call EndDialog to destroy a modeless dialog box. Call CWindow::DestroyWindow instead
从这段英文可以获得两个信息, 有模式的对话框可以用EndDialog来销毁, 无模式的对话框要用DestroyWindow来销毁. 而这一点,MSDN在OnOK的函数说明了也做了强调,内容如下:
If you implement the OK button in a modeless dialog box, you must override the OnOK method and call DestroyWindow inside it. Do not call the base-class method, because it calls EndDialog which makes the dialog box invisible but does not destroy it.
为什么强调用谁来销毁,因为这牵涉到资源释放的问题. 比如当你的这个对话框是无模式的,你关闭对话框时,就不能只调用CDialog的OnOK, 还应该DestroyWindow,像下面这样:
- void CMyDlg::OnOK()
- {
- CDialog::OnOK();//第一步,关闭窗口
- DestroyWindow();//第二步,释放资源
- }
void CMyDlg::OnOK()
{
CDialog::OnOK();//第一步,关闭窗口
DestroyWindow();//第二步,释放资源
}
那么怎么判断对话框是有模式的还是无模式的呢,很简单,如果你的对话框是用DoModal生成,它就是有模式的,如果是用Create生成的,它就是无模式的. 假设现在你用VC新建一个基于对话框的应用, 这个默认生成的对话框就是一个有模式的对话框。