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

相关文章

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(