关于GetMessage的一个注意点

来源:互联网 发布:联合利华沁园 知乎 编辑:程序博客网 时间:2024/05/16 15:46

  要从消息队列取出消息,我们常常用GetMessage 函数,这个函数的原型声明如下:

BOOL GetMessage(  LPMSG lpMsg,         // message information  HWND hWnd,           // handle to window  UINT wMsgFilterMin,  // first message  UINT wMsgFilterMax   // last message);

我们重点看第二个参数 hwnd ,MSDN原文如下:Handle to the window whose messages are to be retrieved. The window must belong to the calling thread. The following value has a special meaning. Value Meaning NULL GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread using the PostThreadMessage function.

大意是 1、hwnd是接收指定窗口的消息。这个窗口必须属于被调用的线程。  2、当 hwnd等于NULL时,接收属于调用线程所有窗口的窗口消息。

我们先看第一个意思: 假如前面我们只是定义了一个窗口,它的句柄是hwnd, 这样按照第一句话的意思,我们完全可以将 窗口句柄 hwnd 赋值给   GetMessage 的第二个参数。

但是,当我们运行程序后(源代码省略)却发现一个问题:当我们查看任务管理器中的进程时,发现这个程序竟然占据的接近60%的CPU(不同的CPU型号可能会不同),听见及其里面的风扇呼呼的转。这是什么原因造成的呢?

继续查看MSDN,有这样一句话:If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer.    大意就是如果有错误,GetMessage会返回产生返回值-1,比如窗口句柄是一个无效的句柄。

因为我们在WindowsProc中会调用DestroyWindow来销毁窗口,既然窗口销毁了,那么窗口句柄也就无效了,那么GetMessage就会返回-1。

在定义消息循环时,如下:

while(GetMessage(&msg, hwnd, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

因为 只要不是零,if就判定为真,所以GetMessage的返回值是-1,系统仍然认为是真,所以就一直循环执行这条语句,成了死循环,就当然占用CPU 了。

在MSDN上,提供了一个很好的示例:

BOOL bRet;while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0){     if (bRet == -1)    {        // handle the error and possibly exit    }    else    {        TranslateMessage(&msg);         DispatchMessage(&msg);     }}

所以,以后我们要注意MSDN上一些细节的地方,否则会产生一些意想不到的错误

原创粉丝点击