MFC的消息机制
MFC的消息循环(::GetMessage,::PeekMessage)消息泵(CWinThread::PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情 分两个步骤完成:
1 “消息派送”:非对话框程序(MFC Doc/View架构)和对话框程序略有不同,但原理相差不大。但除了少数的消息例如WM_QUIT,所有消息的派送流程基本一致。2 “消息路由”:其中消息分有3种类型,各类型的路由过程不一样。非对话框程序和对话框程序的处理相同。 消息派送消息派送过程如下图
注意:方框代表类函数,圆圈代表执行函数的对象实体。类函数和执行函数的对象一定要分清楚。 程序启动后,构造全局变量tApp,并调用_tWinMain ->AfxWinMain ->AfxWinInit ->CWinThread::InitApplication ->CWinThread::InitInstance ->CWinThread::Run最终进入tApp对象的 CWinThread::Run 函数中。其中右框图中所有操作都是tApp对象完成的。
CWinThread的Run函数里面,调用了PumpMessage函数。PumpMessage是关键函数,它做了两件事情:调用PreTranslateMessage。MFC的消息预处理机制。 调用DispatchMessage做消息分发。 其中PreTranslateMessage函数的作用是:让每个消息的目标窗口(包括他的父窗口,注意不是父类)都有机会参与消息到来之前的处理。下文有具体该函数的内部处理。 DispatchMessage则调用AfxWndProc ,AfxWndProc 调用AfxCallWndProc ,而AfxCallWndProc 则做了关键的一步骤,调用 pWnd->WindowProc(nMsg, wParam, lParam);其中 pWnd为目标窗口对象。完成消息派送,消息成功派送到目标窗口对象的WindowProc函数中。 而后的事情,就是“目标窗口对象”收到消息后,进行消息路由和映射,找到改消息的处理函数。 再看看PreTranslate的内部处理:
tApp对象的PreTranslateMessage操作有3种走向:如果(pMsg->hwnd == NULL),说明这是一个线程消息。调用CWinThread::DispatchThreadMessageEx到消息映射表找到消息入口,然后调用消息处理函数。
NOTE: 一般用PostThreadMessage函数发送线程之间的消息,他和窗口消息不同,需要指定线程id,消息被系统放入到目标线程的消息队列中;用ON_THREAD_MESSAGE( message, memberFxn )宏可以映射线程消息和他的处理函数。这个宏必须在应用程序类(从CWinThread继承)中,因为只有应用程序类才处理线程消息。
消息的目标窗口的PreTranslateMessage函数首先得到消息处理权,如果函数返回FALSE,那么他的父窗口将得到消息的处理权,直到主窗口;如果函数返回TRUE(表示消息已经被处理了),那么就不需要调用父类的PreTranslateMessage函数。这样,保证了消息的目标窗口以及他的父窗口都可以有机会调用PreTranslateMessage--在消息发送到窗口之前进行预处理 如果消息的目标窗口和主窗口没有父子关系,那么再调用主窗口的PreTranslateMessage函数。例如非模式对话框
消息路由/映射

到现在消息已经被目标窗口得到了。
主要分2种情况去找处理函数:WM_COMMAND,WM_NOTIFY处理类似
NOTE:MFC 把消息分为三大类:
命令消息(WM_COMMAND):凡由UI 对象产生的消息都是这种命令消息,可能来自菜单或加速键或工具栏。SDK程序主要靠消息的wParam 辨识之,MFC 程序则主要靠菜单项目的识别码(menu ID)辨识之-- 两者其实是相同的。
凡衍生自CCmdTarget 的类别,皆有资格接收改类型消息。几乎构造应用程序的最重要的几个类别都衍生自CCmdTarget。标准消息- 除WM_COMMAND 之外,任何以WM_ 开头的都算是这一类。任何
衍生自CWnd 之类别,均可接收此消息。Control Notification - 这种消息由控制组件产生,为的是向其父窗口通知某种情况。例如当你在ListBox 上选择其中一个项目,ListBox 就
会产生LBN_SELCHANGE 传送给父窗口。这类消息也是以WM_COMMAND 形
式呈现。
“标准消息”处理最直观,直接调用AfxFindMessageEntry函数去“消息映射表”中寻找对应的处理函数。遍历顺序是沿着父类一直上溯。其中消息映射表是MFC代码类似于DECLARE_MESSAGE_MAP()等的宏搭建起来的网。

按照MFC的规定。WM_COMMAND消息就不同了,消息经过了一个由MFC指定的路线。
路线图如下所示:
就是在OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)实现了这个路线。

至此。消息处理全部完成。全图如下:

其他备注:
只要线程有界面元素或者调用GetMessage,或者有线程消息发送过来,系统就会为线程创建一个消息队列。窗口属于创建他的线程。用SendMessage等发送消息到指定窗口,则把该消息放到窗口所在的消息队列。或者可以直接用PostThreadMessage给指定id线程发送消息。 ::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)的最后一个参数指定检查消息后,把不把消息移出消息队列。 关注OnIdle函数:在CThreadWnd发现消息队列中并没有消息的时候,则调用该函数。用户可重载该函数。在这个处理中将更新UI界面(比如工具栏按钮的enable和disable状态),删除临时对象(比如用FromHandle得到的对象指针。由于这个原因,在函数之间传递由FromHandle得到的对象指针是不安全的,因为他没有持久性)
MFC的消息机制的更多相关文章
- <MFC_1>深入剖析MFC的WinMain和消息机制
一.开篇引论 熟悉Win32开发的朋友,应该非常了解它的基本组成和流程 1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗 ...
- MFC学习-第4课 消息机制和MFC作图
转自: 1.http://blog.sina.com.cn/s/blog_6b5180bf01012kbz.html 2.http://blog.csdn.net/happyhhb/article/d ...
- MFC的消息映射机制揭秘
MFC的设计者们在设计MFC时,紧紧把握一个目标,那就是尽可能使得MFC的代码要小,速度尽可能快.为了这个目标,他们使用了许多技巧,其中很多技巧体现在宏的运用上,实现MFC的消息映射的机制就是其中之一 ...
- vc++窗口的创建过程(MFC消息机制的经典文章)
一.什么是窗口类 在Windows中运行的程序,大多数都有一个或几个可以看得见的窗口,而在这些窗口被创建起来之前,操作系统怎么知道该怎样创建该窗口,以及用户操作该窗口的各种消息交给谁处理呢?所以VC ...
- MFC消息机制
何谓消息.消息处理函数.消息映射?消息简单的说就是指通过输入设备向程序发出指令要执行某个操作.具体的某个操作是你的一系列代码.称为消息处理函数. 在SDK中消息其实非常容易理解,当窗口建立后便会有一个 ...
- MFC六大核心机制之五、六:消息映射和命令传递
作为C++程序员,我们总是希望自己程序的所有代码都是自己写出来的,如果使用了其他的一些库,也总是千方百计想弄清楚其中的类和函数的原理,否则就会感觉不踏实.所以,我们对于在进行MFC视窗程序设计时经常要 ...
- MFC的消息响应机制说明
MFC的快速理解: 1.MFC的设计者们在设计MFC时,有一个主要的方向就是尽可能使得MFC的代码要小,速度尽可能快.为了这个方向,工程师们使用了许多技巧,主要表现在宏的运用上,实 现MFC的消息映射 ...
- 我对windows消息机制的理解(参考深入浅出MFC,欢迎批评指正!!)
以消息为基础,以事件驱动之 程序的进行依靠外部消息来驱动,即:程序不断等待任何可能的输入,然后做判断,然后再做适当的处理. 消息输入:操作系统捕获,以消息形式进入程序.(操作系统通过其USERS模块中 ...
- MFC学习(四) 消息机制
1 消息机制的要点: 消息队列:先进先出 消息循环:通过循环while,不断的从消息队列中取得队首消息,并分发消息. 消息处理:根据不同的消息类型做不同的处理 事件:事件响应函数 2 消息机制 _tW ...
随机推荐
- methanol 模块化的可定制的网页爬虫软件,主要的优点是速度快。
methanol模块化的可定制的网页爬虫软件,主要的优点是速度快. 下载:http://sourceforge.net/projects/methabot/?source=typ_redirect R ...
- OnPaint()函数的作用原理
WM_PAINT是窗口每次重绘都会产生的一个消息. OnPaint是对这个消息的反应函数 mfc 的 CWnd::OnPaint 没做什么,只是丢给系统处理. 一 : 先执行OnEraseBkgnd, ...
- 斯坦福大学IOS开发课程笔记(第七课第一部分)
转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/31462099 作者:小马 这节课的内容太多,分两部分介绍.本节课主要是介绍怎样开发 ...
- 网页制作之html基础学习1-简介
学习网页制作主要分为三大块 1.HTML 超文本标记语言( 全称:Hyper Text Markup Language) 专门编辑静态网页 2.CSS 网页美化:是HTML控制的样式 ...
- 【转】linux下 postgres的一些操作总结
参考博文: PostgreSQL详解 1. 基本操作命令 安装完成后,PostgreSQL默认创建了名为postgres数据库用户账户,其与MySQL的root以及SQL Server的sa账 ...
- Introduction to the Build Lifecycle
Introduction to the Build Lifecycle Table Of Contents Build Lifecycle Basics Setting Up Your Project ...
- vim添加删除多行注释
CTRL+V进入可视化模式 移动光标上移或者下移,选中多行的开头 选择完毕后,按大写的的I键,此时下方会提示进入“insert”模式,输入你要插入的注释符 最后按ESC键,你就会发现多行代码已经被注释 ...
- 高级特性(6)- 高级Swing
6.1 列表 6.1.1 JList构件 6.1.2 列表模式 6.1.3 插入和移除值 6.1.4 值的绘制6.2 表格 6.2.1 简单表格 6.2.2 表格模型 6.2.3 对行和列的操作 6. ...
- 基于visual Studio2013解决算法导论之007优先队列(堆实现)
题目 优先队列 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- 【jQuery】smartMenu右键自定义上下文菜单插件(似web QQ)
(前端用重点整理博客地址)链接地址:http://www.cnblogs.com/atree/archive/2011/06/30/jQuery-smartMenu-javascript.html 一 ...