Window消息传递机制

原创 2007年09月20日 23:26:00
Window消息传递机制
2007-03-10 23:12
MFC将thread分成winddow thread和worker thread,在讨论多现程(Multi-thread)之前,我们先只考虑window thread。

     windows programming的基本工作方式和console application的不同,基本上是这样运行的,程序从WinMain()开始,然后进入一个message loop,程序在这里等待发给它的所有消息然后一一处理,直到接收到WM_QUIT的消息的时候,message loop终止,程序结束。所以整个主程序运行的过程就是等待消息,接收消息,然后处理消息的过程。

    窗口建立的时候CreateWindow, RegisterWindow之类的不必太费心,MFC已经全管理妥当了,需要提起一点注意的是程序开始时HINSTANCE hInstance这个参数,在和DLL打交道的时候会帮你解决很多问题,如果一个Bitmap Load不上来,或者一个Dialog DoModal之后不出来,估计就得向这个参数求助了,这是后话。

    具体处理的消息的函数叫window procedure,具体处理消息的code叫message handler。它可以是当前应用程序的API,也可以是调用的不同DLL的API。不同的DLL叫不同的module。以后的文章中我会具体说明module state。是个很重要的话题。(当项目大的时候)

   没有message handler的消息交给DefWindowProc()函数处理,差不多可以理解为什么也不作了。

   消息包括四个参数,window handle,message ID,和另外两个参数wParam, lParam。window handle可以作为window的识别ID来用。所以在发送消息的时候如果可以有两种格式:
CWnd *pWnd = ....
if (pWnd && pWnd->GetSafeWnd())

pWnd->SendMessage(message, wParam = 0, lParam);
或者
SendMessage(pWnd->GetSafeWnd(), message, wParam, lParam )

发送消息如果用SendMessage消息将立刻发送,如果用PostMessage,消息将进入Message queue按当前顺序发送,一般没有特别的要求PostMessage已经足够了。
处理消息的时候根据不同的Message ID交给不同的message handler去处理,一般的message handler的接收格式是用wParam传一个关键的参数,如这次操作的具体ID,把其余的大量辅助信息放在lParam里。需要注意的是如果lParam传递的是一个
指针(一般情况下是CObject类的或从CObject衍生出来的),这个指针指向的变量的寿命需要足够长,因为信息Post出去之后发送函数很可能就运行完毕了。如果发送的指针是个局部变量,接收方就一定会Crash。当然如果是发送方new出来的变量,接收方得负责帮他delete掉,这个操作很危险,而且不一定合适。有时候发送方把信息传给N个窗口,第一个窗口delete掉了第二个窗口就麻烦了,不delete掉又不能保证第二个窗口一定delete掉,所以如果可能,不用new为上策。用点什么成员变量,常数变量之类的比较好。

由于可能收到的信息种类很多,用传统的switch来处理在程序中会显得很乱,于是MFC采用了Message Map机制。Message Map 机制实现了收到的信息和处理信息函数的mapping。在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间定义的消息会在window接收到之后一一传给对应的message handler处理。

所有用于处理信息的函数的申明需要有afx_msg关键字。对于系统所要处理的message,ON_WN_XXX 一般跟三个参数,WPARAM(wParam),LOWORD(lParam) 和HIWORD(lParam).用不到的参数会省略。

下面列举一下Message Map中可能用到的关于宏

1。Window间SendMessage或PostMessage收到的消息如果是系统将要管理的,在Message Map中一般用ON_WM_XXX。“XXX”是具体消息名字。例如画窗口是ON_WM_PAINT。如果是自定义的消息ON_MESSAGE()。例如窗口pWndA发消息给窗口pWndB。pWndB->PostMessage(WM_MYMSG1),那么Window B要处理这个消息需要在Message Map里面写上 ON_MESSAGE(WM_MYMSG1, OnMessage1),然后写OnMessage1函数作message handler。WM_MYMSG1的定义应放在user message中,WM_USER+NNN。注意最好不要和其它已有的ID重复,这个没有办法自动检查。

2。ON_COMMAND,ON_UPDATE_COMMAND_UI,ON_COMAND_RANGE
ON_COMMAND只要用于menu和toolbar的点击处理,也可以用在accelerator中。管理用户的键盘输入用ON_COMMAND比管理ON_WN_CHAR好。ON_UPDATE_COMMAND_UI是用于更新menu或toolbar的。在这个message handler里面你可以根据不同的要求enable或者disable当前的菜单选项或toolbar button。ON_COMMAND_RANGE主要用于动态的菜单的选项中。当N个动态菜单选项加入时,你可以用一串连续的ID作为它们的消息管理ID,在ON_COMMAND_RANGE定义这串ID的起始和最大值,然后响应
函数就可以知道具体是哪个动态菜单选项被选中了。

3。ON_COMMAND_EX,ON_COMMAND_RANGE_EX
用处比较少,当多个class (CCmdTarget class)需要处理同一消息的时候,一个class如果用ON_COMMAND_EX处理,返回TRUE,表示消息处理完毕。返回FALSE则其它class可以继续处理。

4。ON_REGISTERED_MESSAGE
用于确认系统中新message ID唯一。

5。ON_CONTROL,ON_WM_XXX_REFLECT,ON_CONTROL_RANGE
用于window接收其控件发来的特殊消息。

 

Ogre消息传递机制

  • 2008年01月03日 15:16
  • 248KB
  • 下载

VC消息传递机制

  • 2017年05月02日 15:49
  • 49KB
  • 下载

Android学习笔记(38):Handler消息传递处理机制

先说为什么需要Handler: Android的主线程又叫UI线程,用于处理与UI相关的时间。Android只允许在主线程中修改UI组件,当我们在其他线程中需要修改UI界面时,就需要发送消息到主线程,...

MTK定时器消息传递机制

  • 2010年05月23日 16:36
  • 86KB
  • 下载

MFC的消息传递机制仿真

  • 2017年06月24日 20:27
  • 13.05MB
  • 下载

Handler消息传递机制(二) 教你认清Handler,Looper,MessageQueue

摘要: 在上篇文章中跟大家介绍了更新UI的几种方法,由此引出来的Handler消息传递的过程。这篇文章主要跟大家讲解,Handler,Looper,MessageQue他们分别是什么以及之间是如...

window进程间通信(消息传递)

  • 2017年11月03日 11:54
  • 3.56MB
  • 下载

深度解析VC中的消息传递机制

摘要:Windows编程和Dos编程,一个很大的区别就是,Windows编程是事件驱动,消息传递的。所以,要学好Windows编程,必须 对消息机制有一个清楚的认识,本文希望能够对消息的传递做一...
  • lxxmwe
  • lxxmwe
  • 2015年05月18日 15:55
  • 144

Chrome插件开发入门(二)——消息传递机制 转http://ju.outofmemory.cn/entry/74567

Chrome插件开发入门(二)——消息传递机制 Blog | Qiushi Chen 2014-03-31 10530 阅读 Chrome插件 由于插件的js运行环境有区别,所以消息传递机制是...

Android Handler类消息传递机制(三)不同类中使用Handler

Handler的关键,在不同类中使用需要注意参数的传递    分为两种情况 1.从其他类向activity类传送数据 下面以其他类和activity类通信交换数据为例讲解运行模式 /**...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Window消息传递机制
举报原因:
原因补充:

(最多只允许输入30个字)