转载请注明出处
作者:小马
网上没见到几个说得比较清楚的,自己发表一些看法, 讲几个相关的知识点. 以备日后脑子不好使了, 可以找来
温习一下.
当我们用创建一个新的对话框时, 上面会有两个按钮, 他们的ID是IDOK和IDCANCEL,这两个ID是MFC的保留ID,任何按钮,不管它叫什么名字, 只有他们的ID是这两个, 如果你不重载他们(在资源视图双击后,添加自己的代码), 点一下的效果都是关闭窗体.
虽然效果是一样的, 但是底层调用确是有差异的, IDOK实际动作是调用了CDialog::OnOK(), 而IDCANCEL是调用CDialog::OnCancel().可以看一下这两个基类函数的源码(设个断点,F11跟进去可以看到源码)
void CDialog::OnOK()
{
if (!UpdateData(TRUE))
{
TRACE0("UpdateData failed during dialog termination./n");
// the UpdateData routine will set focus to correct item
return;
}
EndDialog(IDOK);
}
void CDialog::OnCancel()
{
EndDialog(IDCANCEL);
}
他们都调用了EndDialog.
来说说这个EndDialog, msdn上如是说:
Call this member function to terminate a modal dialog box.
这个就是最终用来结束模态对话框的底层API函数, 它的参数用来传给
"the caller of DoModal", 这就是为什么我们可以用类似
if(dlg.DoModal()==IDOK)
语句类判断用户点击的是"ok"还是"cancel".
两个函数唯一的区别就是OnOK多调了一个UpdateData的函数, 这个函数应该不会太陌生,
它负责控件和变量之间的数据交换和更新. 它的参数为TRUE表示数据由控件赋值给变量.
如果你是一个善于思考的人, 这个时候至少应该想到两个问题了.
第一个问题, 在什么样的应用场合都体现出OnOK和OnCancel的差别呢?
你可以先在这里想一会儿......,不过我要继续写.
试想下面一种情况, dialog1窗体上有一个button,点这个button调起
一个模态的对话框dialog2, dialog2上有一个edit box控件, 关联一个CString型的变量叫m_str.
在dialog2从DoModal函数返回时, 读m_str的值, 你会发现,如果你是点dialog2上的OK返回, m_str
的值就是你在edit box里输入的字符串, 如果你点Cancel返回, m_str是空值.
第二个问题, 是你应该认识到的, 如果你在结束对话框之前, 已经销毁了一些具体关联关系的控件(比如调用了DestroyWindow), 然后你用OnOK来关闭窗体,程序肯定会崩溃.
MFC的窗体有这样的两个消息, 分别是WM_CLOSE和WM_DESTROY.
在win32时代, 一个标准的windows窗体(用CreateWindow建立), 当你点击右上角的X时,
系统送出WM_CLOSE消息, 程序不必处理,直接交由DefWindowProc来处理, 而它处理的操作就是调用
DestroyWindow, 而DestroyWindow会送出WM_DESTROY. 你的程序响应WM_DESTROY标准处理流程是释放资源,然后调用PostQuitMessage函数.
PostQuitMessage会引出WM_QUIT消息(这个消息完全不用理会,系统自己处理), 系统检测这个消息,退出程序.
MFC对上述操作做了封装, 很多细节可以不必理会. 比如在MFC应用中, 已经很难看到PostQuitMessage的身影了. 这个函数在MFC中要慎用,因为它是关闭窗体的最后一步了, 如果你在不恰当的地方调用了它,可能MFC本身一些默认的处理得不到执行, 从而程序出现错误.
我们可以响应上述两个消息(WM_CLOSE和WM_DESTROY)然后做一些特殊化的处理.
比如,WM_CLOSE,我们可以在适当的地方通过SendMessage来向窗体发出这个消息, 完成一些操作.
而WM_DESTROY消息则最好不要由程序自己发送,这个消息应该无论任何时候,都应该由系统来发送.
对于MFC的对话框应用, 如果我们拦截WM_CLOSE和WM_DESTROY消息, 就会发现, 当你点击窗体右上角的"X"时,
程序会先响应WM_CLOSE,再响应WM_DESTROY.但是正像前面讲到的, MFC中, 对话框程序基本采用OnOK或OnCancel的形式来关闭, 拦截WM_CLOSE或WM_DESTROY的意义不大.
仅一家之言, 欢迎拍砖!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pony_maggie/archive/2011/03/17/6256984.aspx