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
  • 下载

深入理解Handler消息传递机制详解

Handler详解 1、出于线程考虑,Android的UI不是线程安全的,者意味着如果有多个线程并发操作UI组件,可能导致线程安全问题。为了解决这一问题,Android指定了一个简单的规则:只允许UI...

VC消息传递机制

  • 2017-05-02 15:49
  • 48KB
  • 下载

MTK定时器消息传递机制

  • 2010-05-23 16:36
  • 86KB
  • 下载

IOS消息传递机制

注1:本文由破船译自Communication Patterns。 本文目录如下所示: 可用的机制做出正确的选择Framework示例小结 每个应用程序或多或少,都由一些...

MFC的消息传递机制仿真

  • 2017-06-24 20:27
  • 13.05MB
  • 下载

安卓开发中Handler消息传递机制

在安卓开发中,经常会遇到让程序在运行过程中修改界面属性的问题,然而当我们试图用其他线程机制(如timer线程)去修改界面属性时,会经常出现程序挂掉的问题,这也让好多初学安卓开发的人感到莫名其妙。   ...

Handler消息传递机制(二)Handler,Loop,Message,MessageQueue的工作原理

Loop,Message,MessageQueue概念理解: Message:Handler发送、接收和处理的消息对象 Looper:每个线程只能拥有一个Looper.它的looper()方法负责循环...

Object-C的消息传递机制和method swizzling方法混淆

objc_msgSend 在Object-C中,我们经常调用一个对象的方法,通常我们将这个过程成为 消息传递。不同于 C 语言对对象方法的静态调用,Object-C 是通过 Dynamic Bind...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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