一、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 简述
功能描述:调度消息给窗口程序,也即消息分发;