GetMessage和PeekMessage的应用心得

一、GetMessage和PeekMessage都是从消息队列中取出消息;

GetMessage:从线程的消息队列中取出一个消息并将其放于指定的结构

MSG msg;

GetMessage(&msg, NULL, 0, 0);

1参:指向MSG结构的指针,该结构从线程的消息队列中接受消息信息

2参:消息窗口或其子窗口(IsChild())的句柄,如果为NULL接收属于调用线程的窗口消息;线程消息可以由PostThreadMessage寄出

3参、4参:指定被检索的最小、最大消息值的整数;如果两者都为0,不进行消息过滤,返回所有可得消息;

常数 WM_KEYFIRST和WM_KEYAST可作为过滤值取得与键盘输入相关的所有消息:常数WM_MOUSEFIRST和WM_MOUSELST可用来接收所有的鼠标消息。

返回值:如果函数取得WM_QUIT之外的其他消息,返回非零值.如果函数取得WM_QUIT消息,返回值是零,如果出现了错误,返回值是-1

返回值可以为1、0、-1因此我们要避免使用如下语句:while( GetMessage(&msg, NULL, 0, 0) ) {//......} while(-1)后果不可想像

总结:GetMessage 从消息队列中删除消息,无消息时阻塞线程;也可以说它是同步的;

 

二、PeekMessage简述

总结1:PeekMessage 查询消息队列,有消息就取出,没有消息就返回;也可以说它是异步的;是否从消息队列中删除消息由其最后一个参数决定,如果是 PM_REMOVE 删除,PM_NOREMOVE 则不删除;

总结2:PeekMessage 的性质决定,其需要对 WM_QUIT  消息进行单独检查,如:

while(1)

{

  if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )  //其不能移除 WM_PAINT 消息,但 GetMessage 也不从消息队列中删除这个消息

/*

从消息队列中删除 WM_PAINT 消息的唯一方法是:令窗口显示区域的失效区域变得有效,我们可以使用ValidateRect、ValidateRgn或BeginPaint、EndPaint来完成。

*/

  {

    if( msg.message == WM_QUIT )

      break;

     TranslateMessage(&msg);  
     DispatchMessage(&msg);  

  }

  else

  {

    //干一些其它活

  }

}

总结3:如果你从消息队列中取出 WM_PAINT 消息,常规方法处理它不会有问题,但我们不要:

while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) ;

如果此时消息队列中存在 WM_PAINT 消息,则这个循环就死了!~ 你想删除消息队列中除 WM_PAINT 外的所有消息就不成了;

 

三、TranslateMessage 简述

功能描述:将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列中,当下一次线程调用GetMessage或PeekMessage时被取出;其只能转换GetMessage或PeekMessage得到的消息

仅1个参:一般使用 GetMessage/PeekMessage的1参,如:

 while( GetMessage(&msg, NULL, 0, 0) )
  { 
   TranslateMessage(&msg);   //当然,某些应用可以不执行该语句

   DispatchMessage(&msg);  
  }

四、DispatchMessage 简述

功能描述:调度消息给窗口程序,也即消息分发;

 

你可能感兴趣的:(null)