模态对话框退出DoModal过程中需注意的陷阱
时间:2019-09-15
本文章向大家介绍模态对话框退出DoModal过程中需注意的陷阱,主要包括模态对话框退出DoModal过程中需注意的陷阱使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- 遇到问题
- 窗口ParentWnd下有一个子窗口ChildWndA,ChildWndA交互时弹出一个模态对话框ChildWndB,该模态对话框的父窗口是ParentWnd。
- 交互逻辑在ChildWndA对象的成员函数中处理。
- 当弹出对话框ChildWndB, 关闭子窗口ChildWndA, 再操作对话框使得对话框退出对话框窗口过程时,造成crash
- 出现问题的原因
- 对话框的窗口过程退出后,会返回产生对话框的函数中
- 由于交互逻辑在子窗口ChildWndA的成员函数中,当子窗口ChildWndA被关闭(即该对象被析构了),再关闭对话框时,对话框返回的成员函数中的this指针已经是一个野指针了
- 此时只要操作ChildWndA的类的成员变量或者成员函数,就会因为this是野指针而崩溃
- 解决方法
- ChildWndB的父窗口更改为ChildWndA
- 理论上在B弹出后,A无法操作(也就无法关闭)
- 添加强保护逻辑
- 在ChildWndA的窗口销毁过程中,调用对话框ChildWndB的
CDialog::EndDialog
函数后,再调用自身的DestroyWindow
- 在ChildWndA的窗口销毁过程中,调用对话框ChildWndB的
- ChildWndB的父窗口更改为ChildWndA
- 涉及的知识点
- 模态对话框会阻塞当前代码的堆栈
- 模态对话框使用
CDialog::DoModal
进入对话框窗口过程的消息循环 - 外部使对话框窗口过程退出,需要调用它的
CDialog::EndDialog
- 模态对话框的窗口过程正常退出后,会返回原先阻塞的代码堆栈(也就是说,如果返回的代码堆栈的this指针指向的对象已被析构,接下来使用该this指针访问成员变量或者调用虚成员函数(为什么不包含普通成员函数,可以查阅笔者另外一篇文章《是否可以使用空对象指针调用成员函数及访问成员变量》)极大概率会crash)
- 问题抽象与升华
- 对象的生命周期管理
- 子对象的生命周期管理应该由其父对象进行管理,而不应该由其兄弟对象进行管理
- 父对象退出时,应该清理子对象相关的资源
- 对象的生命周期管理
原文地址:https://www.cnblogs.com/HelloGreen/p/11522356.html
- 为WordPress 后台编辑器文本模式(HTML模式)添加按钮
- 360安全扫描之WordPress 页面异常导致本地路径泄漏 的漏洞修补
- Quartz.net官方开发指南 第九课: JobStore
- 数据中心运营中出现的错误
- Quartz.net官方开发指南 第十课: 配置、资源使用以及SchedulerFactory
- WCF服务上应用protobuf
- Quartz.net官方开发指南 第十一课: 高级(企业级)属性
- Quartz.net官方开发指南 第十二课:Quartz 的其他特性
- Protocol Buffers的应用
- WordPress 显示数据库查询次数、查询时间及内存占用的代码
- WCF服务在高负载下可能会变慢
- WordPress 后台管理菜单名称重命名的方法
- 从Akismet 黑名单中洗白的方法
- 移除除管理员之外的其他用户的WordPress 更新升级提示
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JSP开发之JSTL介绍和使用
- codeforces 1283E(贪心)
- codeforces1216C (矩形面积交)
- codeforces 1234C(思维)
- codeforces 1405B(思维)
- codeforces 1216D(数学)
- codeforces 1256D(优先队列+贪心)
- codeforces 1343D(差分数组)
- codeforces1385D (递归+分治)
- codeforces1294D(思维+暴力)
- codeforces 1367D(思维)
- 数据库事务处理与资源池
- codeforces 1328D(思维)
- codeforces 1283D(BFS)
- codeforces 1213D2(贪心+思维)