首页 > 其他分享 >WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数详解

WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数详解

时间:2023-11-06 19:45:13浏览次数:32  
标签:QUIT WM GetMessage 消息 DESTROY CLOSE

 

对WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数的功能及区别做出了分析比对,有助于读者更好的对消息投递函数加以理解。详情如下:

一、WM_CLOSE、WM_DESTROY、WM_QUIT区别

WM_CLOSE:关闭应用程序窗口

WM_DESTROY:关闭应用程序

WM_QUIT:关闭消息循环

只有关闭了消息循环,应用程序的进程才真正退出(在任务管理器里消失)。

win32应用程序的完整退出过程:点击窗口右上角的关闭按钮,发送WM_CLOSE消息。此消息处理中调用DestroyWindow函数,发送WM_DESTROY消息。此消息处理中调用PostQuitMessage(0)函数,发送WM_QUIT消息到消息队列中。GetMessage捕获到WM_QUIT,返回0,退出循环(应用程序真正退出)。

注意:按照上述正常流程,WM_QUIT是不会到达窗口过程的。(因为在GetMessage截获了WM_QUIT消息之后,程序已经彻底退出了!)

MFC应用程序的完整退出过程:点击窗口右上角的关闭按钮,或选择【File/Close】,发出 WM_CLOSE消息。CMyFrameWnd 并没有设置WM_CLOSE 处理常式,于是交给预设之处理常式。预设函数对于WM_CLOSE 的处理方式是呼叫 ::DestroyWindow, 并因而发出WM_DESTROY。预设之WM_DESTROY 处理方式是呼叫::PostQuitMessage,因此发出WM_QUIT。CWinApp::Run 收到WM_QUIT 后会结束其内部之讯息回路, 然后呼叫ExitInstance,这是CWinApp 的一个虚拟函数。如果自己应用程序类CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所呼叫的就是CMyWinApp::ExitInstance,否则就是 CWinApp::ExitInstance。最后回到 AfxWinMain,执行 AfxWinTerm,结束程序。

附加:当调用DestroyWindow函数后,操作系统就会进行一系列的删除动作,先发送WM_DESTROY消息,接着发送WM_NCDESTROY消息。如果这个窗口还有子窗口或者是其它窗口的所有者,就需要给所有子窗口发送删除消息。
WM_QUIT是唯一可以使GetMessage(&msg,NULL,0,0)返回假值的消息.
相关代码分析:

//主函数中进入消息循环的代码片断
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //将消息进行处理一下
DispatchMessage(&msg); //再将消息变量msg传给windows,让windows来调用消息处理函数
}

 

如果把GetMessage(&msg,NULL,0,0)改为GetMessage(&msg,hWnd,0,0),则发现关闭应用程序后,任务管理器中仍有该程序的进程,且占用大量的内存,why?

msdn中的原因解释是:对于GetMessage(&msg,hWnd,0,0),当第二个参数无效时,此函数返回值为-1。对于上述循环来说,此while条件为真,因此进入死循环,进程无法退出。

二、各种消息投递函数

1、SendMessage:发送消息给指定的窗口过程;直到窗口过程处理了消息才返回。

2、PostMessage:将消息放入消息队列(与指定窗口创建的线程相关)中;无需等待消息处理,立即返回。
   不能发送WM_QUIT消息,此消息只能由PostQuitMessage函数发送。

3、PostThreadMessage:发送消息给指定线程的消息队列;无需等待线程处理消息,立即返回。
   此函数发送的消息和窗口是无关的。我们只需指定线程ID就OK了,但要保证线程已创建,否则会失败。

4、GetMessage:从调用线程的消息队列中取消息。
   当第二个参数为NULL时,它检索以下两种消息:
     a、属于调用线程的任何窗口的消息;
     b、由PostThreadMessag投递给该调用线程的消息。

5、PeekMessage:功能同GetMessage。区别是:
   GetMessage:直到一个匹配了过滤条件的消息,被放到消息队列中才返回。
   PeekMessage:不管消息是否放入队列,立即返回。

6、DispatchMessage:派遣消息给相应的窗口过程。

7、TranslateMessage:转换虚拟键信息到字符消息。

 

 

转载: https://www.xp.cn/b.php/54499.html

标签:QUIT,WM,GetMessage,消息,DESTROY,CLOSE
From: https://www.cnblogs.com/Emotionless/p/17813550.html

相关文章

  • wpf 记一次诡异的PreviewMouseLeftButtonDown 无法触发问题
    1、原始代码<Grid><i:Interaction.Triggers><i:EventTriggerEventName="PreviewMouseLeftButtonDown">......
  • nginx ingress controller EWMA负载均衡策略工作原理及修改过程
    1、概念 EWMA(ExponentiallyWeightedMovingAverage)策略是NGINXIngressController中的一种负载均衡算法,它用于决定请求应该由后端服务的哪个实例处理。 2、工作原理 EWMA策略通过指数加权移动平均的方式计算每个后端服务实例的权重,并根据权重来分配请求。 它的......
  • STM32 PWM控制LED流水灯 学习记录随笔
    代码部分#include"stm32f10x.h"                 //Deviceheader#include"Delay.h"intmain(void){   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//启用系统寄存器时钟,使能GPIOC组,并启动   GPIO_InitTypeDefGPIO_InitStructure;  ......
  • 【WCH蓝牙系列芯片】-基于CH32V208开发板—PWM暂停输出,保持电平问题
    -------------------------------------------------------------------------------------------------------------------------------------     ......
  • ubuntu dwm 显示管理器 DM ,窗口管理器 WM, 桌面环境 DE , 的一些理解。
    我觉得要理解linux的桌面系统,必须要借助 archlinux 一些个基本的概念       来看一些具体的例子。       一些常用的窗口管理器WM比如: i3 dwm等。还有窗口合成器 ......
  • HookDeskTopWindowMsg
    .netwinform程序打开SaveFileDialog时,调试窗口显示这些信息,盲猜是对话框中的显示内容被第三方污染,比如图标,按钮的变化。HookDeskTopWindowMsg,Tencent\QQPCMgr\12.11.19357.218\QMInternalShellExt64.dllisnotexistssofa“App.exe”(Win32):已加载“C:\Windows\System32......
  • IMX6ULL PWM定时器
    1PWM定时器介绍一共有8路PWM信号,每个PWM包含一个16位的计数器和一个4x16的数据FIFO。一路框图如下:①、此部分是一个选择器,用于选择PWM信号的时钟源,一共有三种时钟源:ipg_clk,pg_clk_highfreq和ipg_clk_32k。②、这是一个12位的分频器,可以对①中选择的时钟......
  • fetchMetadata: sill resolveWithNewModule raw-loader@0.5.1 checking installable s
    在使用vue-element-admin,npm安装时一直卡在这里报错换源,跟换安装方式都不能解决。最后找到问题,这个是由于安装tui-editor时报错,解决的办法是删掉package.json的tui-editor配置项,之后再次安装大家可以查下tui-editor是干什么用的,不需要就直接删了,然后安装 ......
  • docker部署开源MQTT平台mosquitto
    一、安装docker在开始之前,确保你的系统上已经安装了Docker。Docker提供了一个开放的平台,可以在容器中打包、分发和运行应用程序。你可以从Docker官方网站下载和安装适合你操作系统的Docker版本。二、拉取MosquittoDocker镜像这里我们以阿里云的Ubuntu系统为例。想要在docker中部......
  • cesium 加载geoserver wms服务
    代码如下//加载geoserverwmsvarwmslayer=newCesium.WebMapServiceImageryProvider({url:"http://localhost:8880/geoserver/postgis/wms",layers:'postgis:ceshi0606',parameters:{transparent:true,forma......