在Windows编程中经常使用这两个函数来处理消息,它们之间的区别就是GetMessage是阻塞的,PeekMessage是非阻塞的。

GetMessage原型如下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
PeekMessage原型如下:BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
前面4个参数都是一样的,第一个是消息结构指针;第二个是窗口句柄,标识要接收的消息的窗口,如果为NULL,则表示接收属于该应用程序的所有窗口的消息;第三个、第四个分别指定了接收的消息的范围,如果都为0,则接收所有消息,WM_KEYFIRST 和 WM_KEYLAST 常量用于接受所有的键盘消息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用于接受所有的鼠标消息。PeekMessage函数的第五个参数指示了PeekMeesage接收过消息之后是否将该消息删除,PM_REMOVE表示删除,PM_NONREMOVE表示不删除。
 
该函数用于查看应用程序的消息队列,如果其中有消息就将其放入lpMsg所指的结构中,不过,与GetMessage不同的是, PeekMessage函数不会等到有消息放入队列时才返回。同样,如果hWnd为NULL,则PeekMessage获取属于调用该函数应用程序的任一窗口的消息,如果hWnd=-1,那么函数只返回把hWnd参数为NULL的PostAppMessage函数送去的消息。如果 wMsgFilterMin和wMsgFilterMax都是0,则PeekMessage就返回所有可得到的消息。函数获取之后将删除消息队列中的除 WM_PAINT消息之外的其他消息,至于WM_PAINT则只有在其处理之后才被删除。
 
Windows编程中常用的消息处理函数如下:
 while(GetMessage(&msg, NULL, , ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

首先,GetMessage从进程的主线程的消息队列中获取一个消息并将它复制到MSG结构,如果队列中没有消息,则GetMessage函数将等待一个消息的到来以后才返回。如果你将一个窗口句柄作为第二个参数传入GetMessage,那么只有指定窗口的的消息可以从队列中获得。GetMessage也可以从消息队列中过滤消息只接受消息队列中落在范围内的消息。这时候就要利用GetMessage/PeekMessage指定一个消息过滤器。这个过滤器是一个消息标识符的范围或者是一个窗体句柄,或者两者同时指定。当应用程序要查找一个后入消息队列的消息是很有用。WM_KEYFIRST 和 WM_KEYLAST 常量用于接受所有的键盘消息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用于接受所有的鼠标消息。

TranslateMessage将把两个按键消息WM_KEYDOWN和WM_KEYUP 转换成一个WM_CHAR,不过需要注意的是,消息WM_KEYDOWN,WM_KEYUP仍然将传递给窗口的回调函数。
处理完之后,DispatchMessage函数将把此消息发送给该消息指定的窗口中已设定的回调函数。如果消息是WM_QUIT,则 GetMessage返回0,从而退出循环体。应用程序可以使用PostQuitMessage来结束自己的消息循环。通常在主窗口的 WM_DESTROY消息中调用。
 
使用PeekMessage函数的消息循环如下:
 while(true)
{
if(PeekMessage(&msg, m_hWnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
if(msg.message == WM_KEYDWON && msg.wParam == VK_ESCAPE)
{
...
}
}
else
{
// no message
}
}
这里我们接受所有的键盘消息,所以就用WM_KEYFIRST 和 WM_KEYLAST作为参数。最后一个参数可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否应该从消息队列中删除。
所以这段小代码就是判断是否按下了Esc键,如果是就进行处理。
 
注意:
while (PeekMessage (&msg, NULL, , , PM_REMOVE)) ;

这行叙述从消息伫列中删除WM_PAINT之外的所有消息。如果伫列中有一个WM_PAINT消息,程式就会永远地陷在while循环中。

PeekMessage、GetMessage的区别的更多相关文章

  1. 实例说明 PeekMessage与GetMessage的区别

    PeekMessage与GetMessage的对比相同点:PeekMessage函数与GetMessage函数都用于查看应用程序消息队列,有消息时将队列中 的消息派发出去. 不同点:无论应用程序消息队 ...

  2. 如何区别PeekMessage&GetMessage SendMessage&PostMessage

    转自http://blog.csdn.net/young0325/article/details/6430664 Peekmessage和Getmessage都是向系统的消息队列中取得消息,不过性质不 ...

  3. PeekMessage&GetMessage

    原文:http://www.cnblogs.com/faceang/archive/2010/05/25/1743757.html PeekMessage与GetMessage的对比相同点:PeekM ...

  4. 2017.4.7 e.toString() 与 e.getMessage()的区别

    我使用的时候,抛出了空指针异常,本来是想将异常信息显示在errorInfo里,却发现没有拿到错误信息. 原因:我用的是getMessage(). 用e.getMessage() 时,返回的是null. ...

  5. VC++中PostMessage、SendMessage和PeekMessage之间的区别

    1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数.而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息 ...

  6. Java中printStackTrace()、toString()、getMessage()的区别

    一.三者之间的关系图: 二.演示 1.printStackTrace()演示: public class Test {     public int div(int a, int b)     {   ...

  7. PreTranslateMessage和TranslateMessage区别(转)

    PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当需要在MFC之前处理某些消息时,常常要在这里添加代码. ...

  8. PreTranslateMessage和TranslateMessage区别

    PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当需要在MFC之前处理某些消息时,常常要在这里添加代码. ...

  9. PeekMessage究竟做了什么?

    1.UI线程 2.工作线程 把Delphi里TThread的WaitFor函数转化成C++代码,就会是下面这个样子. BOOL TThread::WaitFor(HANDLE hThread) { M ...

随机推荐

  1. FIS3常用配置

    FIS3常用配置: //作用:启用 fis-spriter-csssprites 插件,便于对png图片进行雪碧图合并 fis.match('::package', { spriter: fis.pl ...

  2. maven 将jar包添加到本地仓库

      maven  如何将jar包添加到本地仓库 CreateTime--2018年4月19日12:50:50 Author:Marydon 情景描述:当项目所需的jar包,maven中央仓库中没有该j ...

  3. HDU 5358 First One(枚举)

    这道题假设依照表达式一个个来算肯定超时,下午时候想了一个O(nlogn*logn)的算法.可是t了.由于这道题卡的很紧几百个例子,必须nlogn的算法才干够ac 回到这道题,考虑log(sum(i,j ...

  4. 查询SQL存储过程创建时间

    select  [name] ,create_date ,modify_date FROM  sys.all_objects where  type_desc = N'SQL_STORED_PROCE ...

  5. 变量名解析:LEGB原则

    # -*- coding: cp936 -*- #python 27 #xiaodeng #变量名解析:LEGB原则 ''' L-----local 局部名字空间 E-----enclosing 直接 ...

  6. Tomcat 配置加密的服务器连接器

    先查询API,找到Configuration里面的Connector的HTTP中的SSL(加密连接器) SSL abbr. Security Socket Layer 加密套接字协议层   利用已生成 ...

  7. 执行存储过程报错——ora-01031:权限不足

    1. 执行DDL报错 在oracle存储过程中,默认是可以直接执行DML和DQL的,但是执行CREATE这种的DDL则需要借助EXECUTE IMMEDIATE ···了,如下备份表语句 --抄表表备 ...

  8. Microsoft Office2003打开office2007文件的补丁

    Microsoft  office2003打开office2007,不需要安装2007,只需要装一个补丁即可 搜索:office2003打开office2007文件的补丁

  9. capacity <<= 1

    import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.prefs.B ...

  10. RMAN性能监控

    RMAN性能调优相关视图 视图名 说明 v$rman_backup_job_details 备份job信息 v$backup_async_io 当前正在运行的.最近完成的备份和restore操作的rm ...