学习笔记之深入浅出MFC 第3讲 消息循环
来源:互联网 发布:独立游戏开发者 知乎 编辑:程序博客网 时间:2024/05/19 23:58
在上一节中讲的WinMain()函数中,最后一部分是消息处理循环,如下图所示:
其中,TranslateMessage是为了将键盘消息转化,DispatchMessage会将消息传给窗口函数去处理。
消息循环中的GetMessage是window 3.x非强制性多任务的关键。应用程序籍由此操作,提供了释放控制权的机会:如果消息队列上没有我的消息,我就把机会让给别人。通过程序之间彼此协调让步的方式,达到多任务功能。Windows 9x和NT具备强制性多任务功能,不再非靠GetMessage释放CPU控制权,但程序依然这么写,因为应用程序仍然需要消息推动。它还是需要抓消息的!
除此之外,很多朋友可能会疑惑DispatchMessage(&msg)是怎么实现消息分派的,这里我们大体的介绍一下:在消息发生时,操作系统会根据当前窗口激活状况为消息标明所属的窗口,而窗口所属的窗口类中又已经明白的标明了窗口函数(即wc.lpfnWndPro所指的函数),所以DispatchMessage就可以按照这个脉络传递消息给窗口函数了。
那么,我们就要顺着消息传递的脉络介绍一下窗口函数了。
消息经由DispatchMessage函数发送给窗口函数之后,窗口函数通过switch/case方式判断消息的种类来决定处置方式。这里不得不提一下窗口函数的调用方式,窗口函数是被Windows系统所调用的,我们不需要在任何地方调用这个函数,所以这是一种call back函数,意思就是“在你的程序中,被windows系统调用的函数”。这些函数虽然是由你设计的,但是永远不会也不应该被你调用,它们是为windows系统准备的。
窗口函数的形式如下所示:
在这个窗口函数中,是由switch/case结构来分别处理每一种消息的,对应每一种消息,都会有一种处理方式。但是,这里需要注意,所有的消息都必须被处理,所以除了我们明确需要处理的消息之外,其他消息必须用default处调用DefWindowProc进行默认的处理,这是一个Windows内部默认的消息处理函数。
窗口函数的wparam和lparam的意义随消息的不同而不同。wparam在16位环境中是16位,在32位环境中是32位。因此,参数的内容在不同的环境中就有了不同。
上面所介绍的消息传递及处理过程就是消息的原始循环原理,但是为了为了更加的模块化、一般化,在MFC中对消息映射(Message Map)做了一些结构化的处理。
首先,定义了一个MESSAGE_ENTRY结构和一个dim宏:
在这个结构体中,nMessagge是消息,第二个元素pfn是一个函数指针,在这里用此指针所指的函数处理nMessage消息。这正体现了面向对象观念中的把“数据”和“处理数据的方法”封装起来的一种具体实现。
然后,我们组织两个数组_messageEntries[]和_commandEntries[],把程序中欲处理的消息和消息处理例程的关联性建立起来:
注意,这是一个MESSAGE_ENTRY结构体数组,正好每一个数组元素对应一个消息及其处理函数。
这是命令项及其处理函数的结构体数组。
有了这两个结构体中消息和其处理函数的对应关系,接下来我们就可以这么设计窗口函数来处理消息了,如下:
在上面的代码中我们可以看到,在窗口函数中设计了两个for循环,分别处理两类消息。第一个for循环中,循环一遍消息,对于当前传入的消息message,在messageEntries结构体中找到此消息,并调用其结构体中对应的处理函数,也就是*pfn指针函数。同理处理命令消息。这样通过结构体和循环对应关系,取代了原来的switch/case结构消息处理机制。这样有个好处,WndProc和OnCommand永远不需要改变,每次有新的需要处理的消息的时候,只需要在_messageEntries[]和_commandEntries[]两个数组总加上新元素,并针对新消息撰写处理例程就可以了。
这种处理消息的机制正式MFC采取的消息处理方式,只不过MFC的Messae Map更加的精致。在MFC中定义一个新的消息的时候,只需要在Message Map中声明响应的处理函数,然后建立这个处理函数并在函数中做出处理就可以了。
- 学习笔记之深入浅出MFC 第3讲 消息循环
- 学习笔记之深入浅出MFC 第2讲 窗口类注册与窗口的诞生
- 深入浅出MFC学习笔记:MFC六大关键技术仿真之消息映射和消息流动
- 深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:消息映射)
- 深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:消息映射)
- 深入浅出MFC学习笔记(第9章:消息映射与命令传递。)
- 深入浅出MFC学习笔记(第9章:消息映射与命令传递。)
- 学习笔记之深入浅出MFC 第9章 仿真MFC之二
- 深入浅出MFC学习笔记2--消息映射和消息路由
- 学习笔记之深入浅出MFC 第9章 仿真MFC 之一
- 深入浅出MFC学习笔记1_GetMessage、PeekMessage、TranslateMessage、DispachMessage等等用法 消息循环中的TranslateMessage函数和Dis
- 《深入浅出MFC》学习笔记之二
- 《深入浅出MFC》学习笔记之二
- 《深入浅出MFC》学习笔记之二
- 深入浅出MFC笔记3-MFC程序的消息流转
- MFC深入浅出之消息映射
- 《深入浅出mfc》学习笔记
- 《深入浅出mfc》学习笔记
- 安装Maven并搭建Maven私有仓库
- 研究Golang
- LayoutInflater的inflate函数用法详解
- Oracle 数据库存储过程
- 179. Largest Number
- 学习笔记之深入浅出MFC 第3讲 消息循环
- 数据库三范式
- GCJ Round 1A 2016
- JQuery API Reference
- [算法练习]找到单向链表的中间节点
- jsp内容
- HDOJ 1420 Prepared for New Acmer(DP)
- c语言
- iOS block代码块强引用问题