Windows/MFC_三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT

2024-05-03 08:18

本文主要是介绍Windows/MFC_三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、发送消息SendMessage、PostMessage

PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回

2、三个消息的区别

WM_CLOSE:

在系统菜单里选择了“关闭”或者点击了窗口右上角的“X”按钮,你的窗口过程就会收到WM_CLOSE。DefWindowProc对 WM_CLOSE的处理是调用DestroyWindow。当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改等。如果用户选择“取消”,你忽略此消息,那么程序照常运行;如果用户确认要退出,你就调用DestroyWindow。

WM_DESTROY:

接下来,DestroyWindow完成窗口的清理工作,最后像窗口过程发送WM_DESTROY。对于 WM_DESTROY,DefWindowProc不会处理。也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。一般处理 WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage。

WM_QUIT:

PostQuitMessage会发送WM_QUIT给消息队列。注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,从而结束消息循环,最后进程结束,程序退出。

假设使用者执行HELLOWIN,并且使用者最终单击了 Close按钮,或者假设用键盘或鼠标从系统菜单中选择了Close, DefWindowProc处理这一键盘或者鼠标输入,在检测到使用者选择了Close选项之后,它给窗口消息处理程序发送一条WM_SYSCOMMAND消息。WndProc将这个消息传给DefWindowProc。 DefWindowProc给窗口消息处理程序发送一条WM_CLOSE消息来响应之。WndProc再次将它传给DefWindowProc。 DestroyWindow呼叫DestroyWindow来响应这条WM_CLOSE消息。DestroyWindow导致Windows给窗口消息处理程序发送一条WM_DESTROY消息。WndProc再呼叫PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此消息。这个消息导致WinMain中的消息循环终止,然后程序结束。

3、退出程序语句

exit(0);

postquitmessage(0);

onok();oncancel();

sendmessage(wm_close,0,0);

exitprocess(0);

其中以exit(0)最为迅速,在实践方面

///

有三个消息看起来差不多,都是处理关闭的事情的,它们是WM_CLOSE,WM_DESTROY,和WM_QUIT。它们的确很相似,但你需要知道它们之间的不同!一个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,可以向用户提出是否真的要退出。你知道让用户作确认或有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框。 
插播:消息框 
int MessageBox( 
HWND hWnd, // handle of owner window 
LPCTSTR lpText, // address of text in message box 
LPCTSTR lpCaption, // address of title of message box 
UINT uType // style of message box 
); 
1. 当收到WM_CLOSE消息,你可以做两件事儿。一件是你接受默认的处理并返回一个值,你若这样做了,应用程序或窗口按照计划关闭;或者,你返回0,应用程序或窗口将保持原样。以下是代码的基本部分: 
if (msg == WM_CLOSE) 

if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO) 
return(0); 
// otherwise, let the default handler take care of it 

2. WM_DESTROY消息有点儿不同,它是窗口正在关闭时发出的。当收到WM_DESTROY消息的时候,窗口已经从视觉上被删除;但一个主窗口被关闭,并不意味着应用程序结束了,因为它可以在没有窗口的条件下继续运行。 
3. 然而,当一个用户关闭了主窗口,并希望这意味着是要结束应用程序时,如果你希望真的这么做,那么在收到WM_DESTROY消息的时候,你必须发出一个WM_QUIT消息。

4.  WM_QUIT是应用程序结束发出的消息,一般可以看成进程被kill掉的情况。

       5. PostQuitMessage是向系统发出要终止线程的请求,在终止线程前系统还要做些内存的清理工作。

我们关闭一个程序时是发送WM_CLOSE消息(函数SendMessage?),然后调用DestroyWindow函数,调用DestroyWindow时系统会向程序发WM_DESTROY消息,终止整个程序。

****************************************************************************************

一个对话框向另一个对话框发窗口关闭消息

对话框A CADlg ; 对话框B CBDlg 
A中声明B为成员变量 CBDlg m_BDlg; 
A发送消息关闭B :SendMessage(m_BDlg.GetSafeHwnd(), WM_CLOSE, 0, 0);  
或者直接:m_BDlg.SendMessage(WM_CLOSE); 
************************************************************************************

WM_DESTROY,WM_CLOSE   功能有什么不同  
下面程序执行时出错  
void   CMainFrame::OnClose()    
{  
CMDIFrameWnd::OnClose();  
CDocument   *doc;  
doc=this->GetActiveDocument();  
}  
下面程序执行时不出错,  
void   CMainFrame::OnDestroy()    
{  
CDocument   *doc;  
doc=this->GetActiveDocument();  
CMDIFrameWnd::OnDestroy();  
}   
原因分析: 
WM_CLOSE是在窗口关闭前发送的,你还可以决定是否真的关闭窗口  
WM_DESTROY是在窗口关闭过程中发送的,窗口已被移出屏幕  
你的程序的错误在于调用   CMDIFrameWnd::OnClose();   后窗体已经  
被Destroy掉了,this指针指向的窗口对象已经不存在了,所以出错 
也就是处理顺序是先处理WM_CLOSE(窗口未关闭),后处理WM_DESTROY(窗口已关闭)  
CMDIFrameWnd::OnClose();后的部分不执行,如需要执行,可放到OnDestroy()中,即你的第二段 
调用父类缺省处理   CMDIFrameWnd::OnClose()时,   系统又发出了  
WM_DESTROY消息将窗口destroy了,所以OnDestroy中this指针还可以用,  
等出了CMDIFrameWnd::OnClose()后this指针指向的窗口对象已经不存在了

同理: 
void   CMainFrame::OnClose()    
{  
CDocument   *doc;  
doc=this->GetActiveDocument();  
CMDIFrameWnd::OnClose();  
}    
将不出错  
下面程序执行时出错,  
void   CMainFrame::OnDestroy()    
{  
CMDIFrameWnd::OnDestroy();  
CDocument   *doc;  
doc=this->GetActiveDocument();  
}  
原因如下:  
OnClose()中调用DestoryWindow(),而DestoryWindow()中发送   WM_DESTROY   和   WM_NCDESTROY;DestoryWindow()执行结束时,OnDestroy()、OnNcDestory()也都执行了,在 CMDIFrameWnd::OnClose()返回后,CMainFrame   的对象已被释放,this指针不可再用。

这篇关于Windows/MFC_三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956267

相关文章

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ