PostQuitMessage(WM_QUIT) 退不出程序
来源:互联网 发布:蒙语新闻的软件下载 编辑:程序博客网 时间:2024/06/08 07:08
今天写了一个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取得那些属于调用线程的窗口的消息和通过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);
}
}
- PostQuitMessage(WM_QUIT) 退不出程序
- PostQuitMessage
- PostQuitMessage(退出程序的一种方法)
- 三个退出程序消息WM_CLOSE、WM_DESTROY、WM_QUIT
- 三个退出程序消息WM_CLOSE、WM_DESTROY、WM_QUIT
- MFC窗口程序三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT
- PostQuitMessage(0);
- Windows/MFC_三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT
- Windows/MFC_三个退出程序消息:WM_CLOSE、WM_DESTROY、WM_QUIT
- WM_QUIT消息
- (15)PostQuitMessage函数
- 关于PostQuitMessage()的探究
- PostQuitMessage函数用法例解
- PostQuitMessage(0)要慎用,经常会造成MFC程序退出时内存泄露,还是尽量使用MFC基类的退出函数比较好。
- 经常使用现有的程序框架,总会忘记一些不经常入目的细微区别 WM_QUIT WM_CLOSE WM_DESTROY
- WM_ENDSESSION WM_DESTROY WM_QUIT
- WM_QUIT的困扰
- WM_QUIT,WM_CLOSE,WM_DESTROY
- 表约束
- 简单树事件
- 基于.NET平台的分层架构实战(六)——依赖注入机制及IoC的设计与实现
- 关于如何跨越抄袭程序阶段的一些断想
- 基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL
- PostQuitMessage(WM_QUIT) 退不出程序
- 乌合之众(大众心理研究)之二:群体的时代
- 包装模式大PK
- linux目录结构
- 基于.NET平台的分层架构实战(八)——数据访问层的第二种实现:SQLServer+存储过程
- 我的handler
- 基于.NET平台的分层架构实战(九)——数据访问层的第三种实现:基于NBear框架的ORM实现
- VC实现简单Http连接
- 基于.NET平台的分层架构实战(十)——业务逻辑层的实现