要从消息队列取出消息,我们常常用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上一些细节的地方,否则会产生一些意想不到的错误