剖析Windows消息处理机制

1.窗口

   Windows程序是由一系列的窗口构成的,每个窗口都有自己的窗口过程,窗口过程就是一个拥有有固定 Signature 的 C函数,具体格式如下:

   LRESULT CALLBACK WindowProc(HWND hwnd,
       UINT uMsg,
       WPARAM wParam,
       LPARAM lParam
   );
   
   窗口类型:
   可重叠窗口(Overlapped Window),
   弹出窗口(Pop-up Window),
   子窗口(Child Window)
   
   窗口之间的关系: 父子关系,拥有关系,前后关系。
   
2.线程
    一个进程至少拥有一个线程,称为主线程,如果一个线程创建了窗口,拥有GUI资源,那么也称该线程为GUI线程,否则就为工作线程。窗口是由线程创建的,
 创建窗口的线程就拥有该窗口。这种线程拥有关系的概念对窗口有重要的意义:建立窗口的线程必须是为窗口处理所有消息的线程。为了使这个概念更加明
 确具体,可以想像一个线程建立了一个窗口,然后就结束了。在这种情况下,窗口不会收到一个WM_DESTROY或WM_NCDESTROY消息,因为线程已经结束,不可
 能被用来使窗口接收和处理这些消息。每个线程,如果它至少建立了一个窗口,都由系统对它分配一个消息队列。这个队列用于窗口消息的派送(dispatch)。
 为了使窗口接收这些消息,线程必须有它自己的消息循环,消息循环一般如下:
 
 MSG msg;
 while( GetMessage(&msg, NULL, 0, 0) )
 {
  TranslateMessage (&msg);
  DispatchMessage (&msg);
 }
 
 应用程序不断的从消息队列中获取消息,然后系统通过DispatchMessage函数分派消息到相应窗口的窗口过程,使得消息得到处理。当获取到WM_QUIT消息时,
 GetMessage返回0,循环结束。
 
3.消息
 消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息
 给应用程序,它被定义为:
  typedef struct {
  HWND hwnd;    //窗口句柄, 发生在哪个窗口上
  UINT message;   //消息标识号 ( WM_MOUSEMOVE, WM_LBUTTONDOWN, ... )
  WPARAM wParam;   //消息参数1
  LPARAM lParam;   //消息参数2
  DWORD time;
  POINT pt;
 } MSG, *PMSG;
 一个消息结构体包含了该事件 所有完备信息,当应用程序收到该消息时,就可以做出相应处理了。
 
 消息分类

 <1>.队列消息和非队列消息

  从消息的发送途径上看,消息分两种:队列消息和非队列消息。
  队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。

  这里,对消息队列阐述如下:
  Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。鼠标、键盘事件由鼠标或键盘驱动
  程序转换成输入消息并把消息放进系统消息队列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。Windows每次从系统消息队列移走一个
  消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。线程消息队列接收送给该线程所创建窗口
  的消息。线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。
  
  除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。这些队列消息以外的绝大多数消息是非队列消息。


 <2>.系统消息和应用程序消息

  从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。

  系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息
  由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使用::RegisterWindowMessage来得到该范围的消息ID。
 
 <3>.窗口消息,命令消息,控件通知消息
  根据处理过程的不同,可以分为三类:窗口消息,命令消息,控件通知消息。
  
  (1).窗口消息
   一般以WM_开头,如WM_CREATE, WM_SIZE, WM_MOUSEMOVE等标准的Windows消息, 用于窗口相关的事件通知,窗口消息将由系统分配到该窗口的窗口过程处理。
  (2).命令消息 (WM_COMMAND)
   一种特殊的窗口消息,它从一个窗口发送到另一个窗口以处理来自用户的请求,通常是从子窗口发送到父窗口,例如,点击按钮时,按钮的父窗口会收到
   WM_COMMAND消息,用以通知父窗口按钮被点击,经测试:子窗口向父窗口发送WM_COMMAND消息,或者称为父窗口会收到WM_COMMAND消息,操作系统并不是
   通过将WM_COMMAND消息放入到父窗口的消息队列中去,而是直接调用了父窗口的窗口过程,以 WM_COMMAND 为消息标识参数(UINT uMsg),实现这个功能的
   API函数正是: LRESULT DispatchMessage(const MSG *lpmsg);
  (3).控件通知消息
   WM_NOTIFY消息,当用户与控件交互(Edit, Button...)时,通知消息会从控件窗口发送到父窗口,这种消息的目的不是为了处理用户命令,而是为了让父窗
   口能够适时的改变控件。


转载自:http://www.cppblog.com/deane/archive/2010/01/07/105099.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值