总结OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别

第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数,即WM消息响应函数。从应用程序结构的角度,拿对话框来说,红色的X对应的是CWnd,而处于对话框中的“确定”、“取消”按钮则对应了CDialog。

第二,OnClose()和OnDestroy()

在单视图程序中,根据<<深入浅出MFC>>所讲,程序退出时执行的操作顺序为(从点X按钮开始)
(1)用户点击X退出按钮,发送了WM_CLOSE消息----->响应OnClose()
(2)在WM_CLOSE消息的处理函数中,调用DestroyWindow()----->销毁与指定CWnd窗口对象关联的窗口,但未销毁CWnd对象
(3)在DestroyWindow()中发送了WM_DESTROY消息----->窗口销毁后响应OnDestroy()
(4)在WM_DESTROY消息中调用PostQuitMessage(),发送WM_QUIT消息,结束消息循环

可以看到,程序的退出过程,是先响应OnClose(),然后响应OnDestroy(),在响应OnDestroy()之前,窗口对象已经被销毁。OnDestroy()到底干了什么呢?它就像一个teller,先通知CWnd对象告诉它即将被销毁,尔后OnDestroy的真正运行是在CWnd对象已经从屏幕上清除以后被调用的。

第三,OnOK()、OnCancel()()、OnClose()、OnDestroy()

CDialog::OnOK首先调用UpdateData(TRUE)将数据传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框;  
CDialog::OnCancel只调用CDialog::EndDialog关闭对话框;  
OnClose()是响应   WM_CLOSE   的.一定程度上可以说CDialog::EndDialog()和OnClose()完成类似的工作,但处理的机制不一样,前者是CDialog的对象机制,后者是WM的消息映射机制。

CDialog::EndDialog()-------->OnDestroy()

OnClose()-------->OnDestroy()

EndDialog()和OnClose()属于“同级别”的,所以我们在按下OK按钮的时候,程序是不会执行OnClose()的,但两种机制都必须经过OnDestroy()

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wind1987321/archive/2009/09/21/4576585.aspx

对话框默认用的两个按钮的ID分别是IDOK和IDCANCEL,这两个都是在winuser.h 中预定义的系统标准控件ID。
对于标准ID,你不重载时MFC会自动调用父类的相应处理函数。
比如IDOK映射到CDialog::OnOK()函数,IDCANCEL映射到CDialog::OnCancel()。

在这两个函数的源码如下:
void CDialog::OnOK()
{
if (!UpdateData(TRUE))
{
TRACE(traceAppMsg, 0, "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()函数调用了DestroyWindow()函数,DestroyWindow()函数又发送了WM_DESTROY消息,该消息的处理函数是OnDestroy(),对话框的生存期最后一个函数是PostNcDestroy()函数。

点那个叉叉呢,首先向对话框发送WM_CLOSE消息,由OnClose()函数处理,它调用DestroyWindow(),其后是和上面一样的路由。
可以看出点叉叉的时候绕过了OnOK()和OnCancel()。

小结一下:
1. 点“确定”、“取消”时的关闭路由为
OnOK()或OnCancel() ---> EndDialog() ---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()
2. 点“关闭”标题栏按钮的关闭路由为
OnClose()---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()

OK和Cancle按钮的联系

为什么按下OK或者Cancle按钮会终止模式对话框呢?因为它们都调用了EndDialog函数,代码如下:

注:IDOK和IDCANCEL将会作为DoModal的返回值。

从下面的代码可以看出,OnOK()和OnCancel()消息响应函数并没有调用DestroyWindow,它们只是调用了EndDialog跳出循环,并没有销毁窗库。对模式对话框,DoModal函数自动调用DestroyWindow,而对非模式对话框,我们若要使用OK或者Cancle按钮结束对话框,必须重写OnOK按钮以使其调用DestroyWindow销毁窗口。

void CDialog::OnOK()

{

if (!UpdateData(TRUE))

{

TRACE(traceAppMsg, 0, "UpdateData failed during dialog termination.\n");

// the UpdateData routine will set focus to correct item

return;

}

EndDialog(IDOK);

}

void CDialog::OnCancel()

{

EndDialog(IDCANCEL);

}

总结OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别相关推荐

  1. onok oncancel onclose ondestroy

    第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数, 即WM消息响应函数.   从应用程序结构的角度,拿对话框 ...

  2. 总结OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别(转)

    目录(?)[+] cDialogonokenddialogdestroywindow区别 收藏 1摘要 2模式对话框的显示 3模式对话框的循环等待 4模式对话框的循环终止 5与OK和Cancle按钮的 ...

  3. OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别

    第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数, 即WM消息响应函数.   从应用程序结构的角度,拿对话框 ...

  4. 总结MFC中OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别

    第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数, 即WM消息响应函数.   从应用程序结构的角度,拿对话框 ...

  5. 关于OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别

    第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数,即WM消息响应函数.从应用程序结构的角度,拿对话框来说,红 ...

  6. OnOK()、OnCancel()、OnClose()、OnDestroy()之间的区别归纳

    首先,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和OnDestroy()是CWnd基类的成员函数,即WM消息响应函数.从应用程序结构的角度,拿对话框来说,红 ...

  7. 总结OnOK、OnCancel、OnDestroy函数之间的区别

    第一,OnOk()和OnCancel()是CDialog基类的成员函数,即ID为ID_OK和ID_CANCEL的按钮的通知消息的响应函数,而OnClose()和OnDestroy()是CWnd基类的成 ...

  8. onok oncancel ondestroy onclose

    按esc只会调用OnCancel() 按alt+f4会先调用OnClose()后调用OnCancel() 按X或关闭按扭时会先调用OnClose()后调用OnCancel() 第一,OnOK()和On ...

  9. MFC中解决回车和ESC关闭的问题,重载OnOk(),OnCancel()函数的正确做法

    本文参考了如下文章: http://msdn.microsoft.com/en-us/library/66b3y2ab(VS.71).aspx http://topic.csdn.net/u/2010 ...

最新文章

  1. 综述:基于点云的自动驾驶3D目标检测和分类方法
  2. 帝国cms商城微信小程序之后台sku多规格的开发说明
  3. windows常见的运行命令以及各快捷键组合
  4. Philip S. Yu 讲的广度学习到底是什么?
  5. MVC — 初步理解IIS工作流程
  6. sklearn—特征工程
  7. resin服务器中间件
  8. 截止失真放大电路_这些基本放大器的知识,你会了吗?
  9. mip-html自动跳转页面,MIP建站系统常见问题汇总
  10. RFID之M1卡数据分析
  11. windows下postgres数据库软件被损坏的情况下data文件存在恢复数据库
  12. 矩阵导数(Matrix Differentia)
  13. 【Java SE】SE“细节”知识大总结
  14. UCOSIII移植STM32(Cotex-M4)HAL库相关问题
  15. 老婆问我Spring Boot怎么学
  16. 我所参加的最贵的培训
  17. 15 【Pinia】
  18. 随心所欲版xp阴道镜_鼠年兽三小只出道!《魔域口袋版》x三只松鼠联动开启
  19. Xcode打开后Target 出现AppIcon不显示
  20. 企业微信如何能快速加好友呢? 有什么工具能批量导入好友吗?

热门文章

  1. html改变单选形状,用css实现html中单选框样式改变
  2. ThreeJs控制器controls
  3. 实验1 Java语言基础作业2022
  4. 现在后端开发都在用什么数据库存储数据?
  5. 同城废品垃圾废纸家电塑料金属废品回收+家政保洁+回收员骑手+商家入驻+回收站入住【uniapp+thinkphp】开源独立
  6. c语言写我爱你中国编程,.请用户输入一组字符串,”我爱你中国”,然后倒序输出该字符串;...
  7. 设备和打印机或设备管理器中有多个爱奇艺客厅电视越来越多解决办法
  8. AT命令发短信和GPRS通信
  9. 京东面试真题解析,薪资翻倍
  10. 锁屏界面提示某些设置已隐藏_息屏还有这些“骚操作”,华为这几个隐藏小功能快用起来...