您的位置:首页 > 产品设计 > UI/UE

PostQuitMessage(WM_QUIT) 退不出程序

2010-05-24 23:37 323 查看
今天写了一个SDK程序,关闭程序时调用PostQuitMessage(WM_QUIT) ,程序没有结束,任务管理器显示其占了90%多的CPU,必须手动结束进程。

下面是退出程序Code:

LRESULT CALLBACK WindowProc (HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

switch (message)

{

case WM_DESTROY:

PostQuitMessage(0);

return 0;

}

return DefWindowProc(hWnd, message, wParam, lParam);

}

完成的程序如下所示:

int WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

static TCHAR szAppName[] = TEXT ("Hello,World!");

HWND hwnd;

MSG msg;

WNDCLASS wndclass;

wndclass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;

wndclass.lpfnWndProc = (WNDPROC)WindowProc;

wndclass.cbClsExtra = 0;//窗口类附加内存

wndclass.cbWndExtra = 0;//窗口附加内存

wndclass.hInstance = hInstance;//实例句柄

wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);

wndclass.lpszMenuName = NULL;

wndclass.lpszClassName = szAppName;

wndclass.hIcon = LoadIcon (NULL,IDI_APPLICATION);

if (!RegisterClass (&wndclass))

{

MessageBox (NULL, "Failed to registerClass!", szAppName, MB_ICONERROR);

return 0;

}

hwnd = CreateWindow (szAppName, TEXT("Hello,World!"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,

CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

ShowWindow(hwnd,nCmdShow);

UpdateWindow(hwnd);

while (GetMessage (&msg, hwnd, 0, 0))


{

TranslateMessage (&msg);

DispatchMessage (&msg);

}

return msg.wParam;

}

经过查看资料,发现问题出在GetMessage的参数上,把 while (GetMessage (&msg,hwnd,0,0))

改成如下:

while (GetMessage (&msg, NULL, 0, 0))


即可。

MSDN

GetMessage

retrieves messages for any window that belongs to the calling thread and
thread messages posted to the calling thread using the PostThreadMessage
function.
中文翻译:GetMessage取得那些属于调用线程的窗口的消息和通过PostThreadMessage函数投递(发送)到调用线程的线程消息.

这样问题就明白了,
GetMessage需要检索到WM_QUIT返回一个FALSE结束消息循环, 而WM_QUIT是通过PostQuitMessage(0)发送, 属于线程消息, 而非普通的窗口消息.
如果在GetMessage中用hWnd而不是NULL, 虽然WM_QUIT 消息仍会出现在程序的消息队列中,但GetMessage却无法检索到,
而且此时窗口已经被销毁了, 如果还想取得hWnd的窗口消息, 只可能发生错误( cpu占用100%, 死循环? ).

也适用于
PeekMessage。

Return Values

If the function retrieves a message other than WM_QUIT
,
the return value is nonzero.

If the function retrieves the WM_QUIT
message, the
return value is zero.

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. To get extended error information, call GetLastError

.

Warning
Because the return value can
be nonzero, zero, or -1, avoid code like this:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...

The possibility of a -1 return value means that such
code can lead to fatal application errors. Instead, use code like this:
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)

{

if (bRet == -1)

{

// handle the error and possibly exit

}

else

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: