http://bbs.ednchina.com/BLOG_ARTICLE_3005455.HTM
VC中WM_CLOSE、WM_DESTROY、WM_QUIT消息出现顺序及调用方式
wxleasyland@sina.com
2012.7
wxleasyland试验:
一、VC建的标准WIN32-HELLO WORLD程序中,
case WM_DESTROY:
// PostQuitMessage(0);将这行屏蔽
则点关闭,窗口关闭了,但是程序进程还在!要在任务管理器中中止。
二、VC建的标准WIN32-HELLO WORLD程序中,
1. 在WndProc()中加上
case WM_CLOSE:
WinExec("cmd /k echo WM_CLOSE: ",SW_SHOW);
break;
2. 按右上角的X、点图标\关闭、或者按ALT+F4,都只出现cmd窗,不会关闭程序。
因为原来是执行
default:
return DefWindowProc(hWnd, message, wParam, lParam);
即DefWindowProc来处理WM_CLOSE消息。现在被case WM_CLOSE:拦截了。
3. 点菜单里的FILE\EXIT,则就是执行case WM_COMMAND: 里的case IDM_EXIT: DestroyWindow(hWnd); 了。
不会执行
case WM_CLOSE:!!!
DestroyWindow(hWnd);
会销毁窗口,同时发送WM_DESTROY消息直接让WndProc()处理(不经过消息队列)。
三、VC建的标准WIN32-HELLO WORLD程序中,
1. 在WndProc()中加上
case WM_CLOSE:
WinExec("cmd /k echo WM_CLOSE: ",SW_SHOW);
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_DESTROY:
WinExec("cmd /k echo WM_DESTROY: ",SW_SHOW);
PostQuitMessage(0);
break;
2. 按右上角的X、点图标\关闭、或者按ALT+F4,会先出现WM_CLOSE,再出现WM_DESTROY。
3. 点菜单里的FILE\EXIT,则只出现WM_DESTROY。
四、VC建的标准WIN32-HELLO WORLD程序中,
如果用PostQuitMessage(0); 则不出现WM_CLOSE。
也不会出现WM_DESTROY!!!!!!! 窗口会关闭,程序退出。
这应该是正常的,WM_QUIT让GetMessage()为0,从而WinMain()退出,然后操作系统会自动去销毁窗口。
主程序已经没了,所以即使WM_DESTROY出现了也没用。
经试,在PostQuitMessage(0);后面的语句会继续执行到完。
PostQuitMessage只是产生一个WM_QUIT消息到消息队列中并马上返回。
所以标准WIN32程序是:
按右上角的X->出现 WM_CLOSE 销毁窗口->产生WM_DESTROY->运行PostQuitMessage->WinMain退出
菜单点EXIT->出现WM_COMMAND 运行 PostQuitMessage
五、在MFC对话框程序中,试验,是:
1. 先WM_CLOSE(这时窗口仍在显示)->再WM_DESTROY(窗口已经消失)->OnDestroy() 执行完后,程序完全退出
2. WM_CLOSE不一定会出现。WM_CLOSE 点右上角的X,点图标\关闭,或者按ALT+F4,会出现。 点OK按钮、或者Cancle按钮,或者用任务管理器强行中止,都不会出现。
3. WM_DESTROY 点右上角的X,点OK按钮、或者Cancle按钮,都会出现。而且晚于WM_CLOSE 出现。 用任务管理器强行中止,则不会出现。
4. 如果在程序中按一个按钮,里有PostQuitMessage(0); 则不出现WM_CLOSE,但会出现WM_DESTROY,窗口会关闭,程序退出。
经试,按钮函数里,在PostQuitMessage(0);后面的语句会继续执行到完。PostQuitMessage只是产生一个WM_QUIT消息到消息队列中并马上返回。
5. 如果在程序中按一个按钮,里有PostMessage(WM_DESTROY); 则不出现WM_CLOSE,但会出现WM_DESTROY。窗口不会关闭,还能正常用。
所以MFC对话框程序是:
按右上角的X->出现WM_CLOSE 销毁窗口->产生WM_DESTROY -> OnDestroy()执行完后程序退出
点确认或取消按钮 运行PostQuitMessage
==================================
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617(v=vs.85).aspx
WM_CLOSE message
Sent as a signal that a window or an application should terminate.
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
An application can prompt the user for confirmation, prior to destroying a window,
by processing the WM_CLOSE message and calling theDestroyWindow function only if the user confirms the choice.
程序中可以让用户确认是否真的要退出。
By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.
WM_DESTROY message
Sent when a window is being destroyed.
It is sent to the window procedure of the window being destroyed after the window is removed from the screen.
当窗口被从屏幕上删除掉之后,这个消息才被发送给窗口程序。
This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed.
During the processing of the message, it can be assumed that all child windows still exist.
在处理消息的过程中,所有子窗仍然存在。
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
If the window being destroyed is part of the clipboard viewer chain (set by calling the SetClipboardViewer function),
the window must remove itself from the chain by processing the ChangeClipboardChain function
before returning from the WM_DESTROY message.
WM_NCDESTROY message
Notifies a window that its nonclient area is being destroyed.
The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message.
WM_NCDESTROY是在WM_DESTROY消息之后。
WM_DESTROY is used to free the allocated memory object associated with the window.
The WM_NCDESTROY message is sent after the child windows have been destroyed. I
n contrast, WM_DESTROY is sent before the child windows are destroyed.
A window receives this message through its WindowProc function.
窗口通过WindowProc函数来接收这个消息!
This message frees any memory internally allocated for the window.
WM_QUIT message
Indicates a request to terminate an application, and is generated when the application calls the PostQuitMessage function.
This message causes the GetMessage function to return zero.
The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure.
WM_QUIT消息与窗口没有关联,所以窗口处理程序收不到这个消息。
It is retrieved only by the GetMessage or PeekMessage functions.
Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.
PostQuitMessage function
Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.
The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately;
PostQuitMessage只是产生一个WM_QUIT消息到线程的消息队列中并马上返回。
the function simply indicates to the system that the thread is requesting to quit at some time in the future.
When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system.
The exit value returned to the system must be the wParam parameter of the WM_QUIT message.
DestroyWindow function
Destroys the specified window.
The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it.
The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership,
and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows
when it destroys the parent or owner window.
The function first destroys child or owned windows, and then it destroys the parent or owner window.
会先销毁子窗,再销毁自身。
DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
A thread cannot use DestroyWindow to destroy a window created by a different thread.
If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style,
a WM_PARENTNOTIFY message is sent to the parent.
====================================
引用网络上的:
====================================
WM_QUIT,WM_CLOSE,WM_DESTROY
2010-05-27 10:35:20| 分类: 编程天地|字号 订阅
WM_DESTROY 是关闭程序
WM_CLOSE 是关闭窗口
WM_QUIT 是关闭消息环
WM_CLOSE和WM_DESTROY同属窗口消息,WM_QUIT则不在窗口消息之列。
三者先后执行顺序是WM_CLOSE、WM_DESTROY、WM_QUIT,
但需要注意的是MFC窗口默认取消按钮函数OnCancel()是不会触发WM_CLOSE消息,只触发WM_DESTROY。
WM_CLOSE:
在系统菜单里选择了“关闭”或者点击了窗口右上角的“X”按钮,你的窗口过程就会收到WM_CLOSE。
DefWindowProc对WM_CLOSE的处理是调用DestroyWindow。
当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改等。
如果用户选择“取消”,你忽略此消息,那么程序照常运行;如果用户确认要退出,你就调用DestroyWindow。
WM_DESTROY:
接下来,DestroyWindow完成窗口的清理工作,最后像窗口过程发送WM_DESTROY。
对于WM_DESTROY,DefWindowProc不会处理。
也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。
一般处理WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage。
WM_QUIT:
PostQuitMessage会发送WM_QUIT给消息队列。
注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,
从而结束消息循环,最后进程结束,程序退出。
假设使用者执行HELLOWIN,并且使用者最终单击了 Close按钮,或者假设用键盘或鼠标从系统菜单中选择了 Close,
DefWindowProc处理这一键盘或者鼠标输入,在检测到使用者选择了Close选项之后,它给窗口消息处理程序发送一条WM_SYSCOMMAND消息。
WndProc将这个消息传给DefWindowProc。
DefWindowProc给窗口消息处理程序发送一条WM_CLOSE消息来响应之。
WndProc再次将它传给DefWindowProc。
DestroyWindow呼叫DestroyWindow来响应这条WM_CLOSE消息。
DestroyWindow导致Windows给窗口消息处理程序发送一条WM_DESTROY消息。
WndProc再呼叫PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此消息。
这个消息导致WinMain中的消息循环终止,然后程序结束。
==========================================================================
WM_DESTROY, WM_CLOSE, WM_QUIT 区别 (2009-01-19 18:46:37)转载▼
标签: 预处理程序 close of message box it 分类: Win32API
开始我也很迷糊,后来看了相关的资料,现在明白了,我这里就转一些相关的文章吧.
WM_DESTROY, WM_CLOSE, WM_QUIT
WM_DESTROY 是关闭程序的
WM_CLOSE 是关闭窗口的
WM_QUIT 是关闭消息环的
以下是程序结束的过程:
1、使用者按[File/Close],系统发出WM_CLOSE消息
2、Frame把这条消息直接发给预处理程序
3、预处理程序发出WM_DESTROY消息
4、预处理程序收到WM_DESTROY后执行PostQuitMessage,发出WM_QUIT.
5、GetMessage收到这条消息后就推出消息循环,程序结束。
有三个消息看起来差不多,都是处理关闭的事情的。
它们是WM_DESTROY,WM_CLOSE,和WM_QUIT。
它们的确很相似,但你需要知道它们之间的不同!
一个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出。
你知道让用户作确认或有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框。
插播:
消息框
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
* 当收到WM_CLOSE消息,你可以做两件事儿。
一件是你接受默认的处理返回一个值,你若这样做了,应用程序或窗口按照计划关闭;
再者,你返回0,应用程序或窗口将保持原样。以下是代码的基本部分:
if (msg == WM_CLOSE)
{
if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
return(0);
// otherwise, let the default handler take care of it
}
* WM_DESTROY消息有点儿不同。它是窗口正在关闭时发出的。
当得到WM_DESTROY消息的时候,窗口已经从视觉上被删除。
一个主窗口被关闭,并不意味着应用程序结束了,它将在没有窗口的条件下继续运行。
* 然而,当一个用户关闭了主窗口,也就意味着他要结束应用程序,
所以如果你希望应用程序结束,在收到WM_DESTROY消息的时候,你必须发出一个WM_QUIT消息。
WM_QUIT是应用程序结束发出的消息,一般可以看成进程被kill掉的情况.
=================================
参考网上的:
WM_DESTROY 是关闭程序的
WM_CLOSE 是关闭窗口的
WM_QUIT 是关闭消息环的
以下说明程序是如何退出的: