[MFC] MFC消息机制的补充

之前写了[MFC] 消息映射机制的使用和原理浅析,还有些需要补充的,都记在这里。

MFC 消息的分类

MFC消息分为系统消息和自定义消息。
在这里插入图片描述
图片来源:C语言/C++教程 大型源码案例分析:MFC消息系统的代码解析 易道云编程

系统消息分为窗口消息、命令消息、通知消息。消息ID是0 ~ 1023。
每个窗口的自定义消息的消息ID需要从1024开始。声明方法为:

#define MY_MSG_1 (WM_USER + 1)

SendMessage

[MFC] 消息映射机制的使用和原理浅析中,用SendMessage发了一个消息。

void CMFCApplication1Dlg::OnBnClickedButton1()
{
	::SendMessage(this->GetSafeHwnd(),MY_MSG_1,NULL,NULL);	
}

SendMessage发出的消息是不经过消息循环的。
所以debug时可以看到,没有经过任何loop函数,直接就是AfxWndProc了,最终通过MessageMap找到对应的响应函数。
此时的函数堆栈调用:
在这里插入图片描述

未排队的消息
未排队的消息会立即发送到目标窗口过程,绕过系统消息队列和线程消息队列。 系统通常发送未排队的消息,以通知窗口影响它的事件。 例如,当用户激活新的应用程序窗口时,系统会向窗口发送一系列消息,包括 WM_ACTIVATE、 WM_SETFOCUS和 WM_SETCURSOR。 这些消息通知窗口已激活,键盘输入已定向到窗口,鼠标光标已在窗口边框内移动。 当应用程序调用某些系统函数时,也可能导致未排队的消息。 例如,在应用程序使用 SetWindowPos 函数移动窗口后,系统会发送WM_WINDOWPOSCHANGED消息。
发送非排队消息的一些函数包括 BroadcastSystemMessage、 BroadcastSystemMessageEx、 SendMessage、 SendMessageTimeout 和 SendNotifyMessage。
来源:关于消息和消息队列

PostMessage 和 消息循环

把上面的SendMessage改成PostMessage试一下。

void CMFCApplication1Dlg::OnBnClickedButton1()
{
	::PostMessage(this->GetSafeHwnd(),MY_MSG_1,NULL,NULL);	
}

此时的函数堆栈调用:
在这里插入图片描述
可以看到调用堆栈不同。
在进入AfxWndProc之前,进入了RunModalLoop。
RunModalLoop就是CWnd的消息循环处理函数。

所以用SendMessage发出的消息,没有经过消息队列。
使用PostMessage发出的消息,会进入系统的消息队列,需要窗口的消息循环来处理。

线程可以使用 PostMessage 或 PostThreadMessage 函数将消息发布到其自己的消息队列或另一个线程的队列。
来源:关于消息和消息队列

消息循环中,主要做了以下事情:
第一个循环:

// phase1: check to see if we can do idle work
while (bIdle &&
			!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
......

PeekMessage 消息,获取消息,而不在队列中删除消息。
在这个消息中进行IDLE判断和处理。

第二个循环:

// phase2: pump messages while available
do
{
	......
}while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));

这个循环也是PeekMessage获取消息,然后在循环体中,进行pump meessage(消息泵)

// pump message, but quit on WM_QUIT
if (!AfxPumpMessage())

AfxPumpMessage中,会GetMessage()、AfxPreTranslateMessage()、TranslateMessage()、DispatchMessage()。

参考

C语言/C++教程 大型源码案例分析:MFC消息系统的代码解析 易道云编程

SendMessage() 发出的消息 PreTranslateMessage() 不一定能接收到!

关于消息和消息队列

MFC学习(一):MFC的消息循环 --讲解到位

相关推荐

  1. Android消息机制--Handler

    2024-02-04 07:26:01       51 阅读
  2. ROS发布消息与接受消息机制

    2024-02-04 07:26:01       64 阅读
  3. 消息队列确认机制和持久化选项

    2024-02-04 07:26:01       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-04 07:26:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-04 07:26:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-04 07:26:01       87 阅读
  4. Python语言-面向对象

    2024-02-04 07:26:01       96 阅读

热门阅读

  1. 力扣日记1.31-【回溯算法篇】90. 子集 II

    2024-02-04 07:26:01       54 阅读
  2. 【云计算】opentack的高级服务部署与调优

    2024-02-04 07:26:01       43 阅读
  3. 前端html+css笔记

    2024-02-04 07:26:01       59 阅读
  4. RPC原理

    2024-02-04 07:26:01       50 阅读
  5. C++设计模式-里氏替换原则

    2024-02-04 07:26:01       51 阅读
  6. 分布式(一)Redis的数据结构

    2024-02-04 07:26:01       52 阅读
  7. Android14 WMS-DisplayArea层级结构生成

    2024-02-04 07:26:01       47 阅读