关于PeekMessage和GetMessage

PeekMessage是个带有Window的线程比较常用的等待一段时间的做法。从这个函数的名字来看,很明显,这个线程想歇段时间。最简单的方法当然是Sleep(milliseconds);但是这会阻塞这个Thread的Message Queue的Enque。如果别的程序或者线程向这个Thread发个Message,就死等了。比如一个简单的GetWindowText就不动了,你如果用Task Manager看,这个窗口就会显示(No response - 没有反应),所以歇的时候一定不能堵住SendMessage。

  举个不恰当的例子,你的Thread是收发室老头儿,老头儿的任务就是接受信件(GetMessage),然后立即送出(DispatchMessage)。邮递员不停地来送信(SendMessage)你这个函数,老头决定休息一会儿,不送信了(DispatchMessage),但是不能让邮递员干等,人家还要干别的事情。所以老头还是瞄了一眼有没有邮递员(PeekMessage),有的话就把信拿到收发室里。 这样邮递员就走了,信留在收发室(Message Queue)。这时候因为不想送信(DispatchMessage),所以一定不能把信给扔了(PM_NOREMOVE),否则信就丢了。
  等老头休息完了,就可以把信从收发室拿出来(GetMessage),再Dispatch出去。
  所以PeekMessage如果后面没有紧跟DispatchMessage, 一定得用PM_NOREMOVE(除非老头儿想过滤,比如把骚扰的信扔了)。
GetMessage(LPMSG lpMsg,   HWND hWnd,    UINT wMsgFilterMin,    UINT wMsgFilterMax)
PeekMessage(LPMSG lpMsg,   HWND hWnd,    UINT wMsgFilterMin,    UINT wMsgFilterMax,UINT wRemoveMsg)
参数wRemoveMsg的作用是指定消息获取的方式,如果设为PM_NOREMOVE,那么消息将不会从消息队列中被移出,如果设为PM_REMOVE,那么消息将会从消息队列中被移出;

     两个函数主要有以下两个区别:
     1.GetMessage将等到有合适的消息时才返回,而PeekMessage只是撇一下消息队列。
     2.GetMessage会将消息从队列中删除,而PeekMessage可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中。

在Windows的内部,GetMessage和PeekMessage执行着相同的代码。而两者最大的不同之处则体现在没有任何消息返回到应用程序的情况下。在此种情况下,PeekMessage会返回一个空值到应用程序,GetMessage会在此时让应用程序休眠(释放CPU)。
posted @ 2009-08-16 17:29  芈希有  阅读(1355)  评论(3编辑  收藏  举报