WM_CLOSE、WM_QUIT、WM_DESTROY区别

WM_DESTROY 是关闭程序的
WM_CLOSE 是关闭窗口的
WM_QUIT 是关闭消息环的

    以下说明程序是如何退出的:
    使用者选按【File/Close】,于是发出 WM_CLOSE。
CMyFrameWnd 并没有设置WM_CLOSE 处理常式,于是交给预设之处理常式。
预设函数对于WM_CLOSE 的处理方式是呼叫 ::DestroyWindow, 并因而发出WM_DESTROY。
预设之WM_DESTROY 处理方式是呼叫::PostQuitMessage,因此发出WM_QUIT。
CWinApp::Run 收到WM_QUIT 后会结束其内部之讯息回路, 然后呼叫
ExitInstance,这是CWinApp 的㆒个虚拟函数。
如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所呼叫的就是CMyWinApp::ExitInstance,否则就是 CWinApp::ExitInstance。
最后回到 AfxWinMain,执行 AfxWinTerm,结束程序。

WM_CLOSE,调用DestroyWindow()
DestroyWindow()又发送WM_DESTROY
响应WM_DESTROY,调用WM_QUIT
GetMessage()发现WM_QUIT,退出程序

特别注意:如果想手动发送WM_QUIT只能使用postmessage函数,而不能使用sendmessage函数

---

//主函数中进入消息循环的代码片断
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); //将消息进行处理一下
DispatchMessage(&msg); //再将消息变量msg传给windows,让windows来调用消息处理函数
}

//消息处理函数
LRESULT CALLBACK MyProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{

      case WM_CLOSE:

                if(IDOK==MessageBox(hwnd,"真的想退出程序吗?","退出程序就没机会了",MB_YESNO))

                {

                        DestroyWindow(hwnd); //WM_CLOSE默认是调用这个处理函数

                }

                break;

               case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

---


WM_CLOSE消息:在系统菜单里选择了“关闭”或者点击了窗口右上角的“X”按钮时产生,它的默认响应函数是直接调用DestroyWindow(hwnd);
DestroyWindow(hwnd); 是销毁窗口(但没有不是退出消息循环),然后销毁过程中会产生WM_DESTROY消息放入消息队列,

(当调用DestroyWindow函数后,操作系统就会进行一系列的删除动作,先发送WM_DESTROY消息,接着发送WM_NCDESTROY消息。如果这个窗口还有子窗口或者是其它窗口的所有者,就需要给所有子窗口发送删除消息。)

 

WM_DESTROY消息:默认是调用PostQuitMessage(0),ostQuitMessage(0)作用是产生WM_QUIT并放入消息队列,

WM_QUIT消息:GetMessage(&msg,NULL,0,0)拿到WM_QUIT后返回假,导致消息循环退出.WM_QUIT是唯一可以使GetMessage(&msg,NULL,0,0)返回假值的消息.

 

 

 

-------------------------------------------------------------------------------------------------------

 

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中的消息循环终止,然后程序结束。

转载地址:http://appdev.189works.com/?action-viewnews-itemid-2590

***********************************************

WM_CLOSE消息与DefWindowProc收到WM_SYSCOMMAND消息,且wParam等于SC_COLSE时发送给窗口过程的消息相同。

  如果在一个Windows程序的系统菜单图标上双击一下,那么程序将会终止。双击产生一系列的WM_NCHITTEST消息。由于鼠标定位在系统菜单图标上,因此DefWindowProc将返回HTSYSMENU的值,并且Windows把wParam等于HTSYSMENU的WM_NCLBUTTONDBLCLK消息放在消息队列中。

  当DefWindowProc接收到wParam参数等于HTSYSMENU的WM_NCLBUTTONDBLCLK消息时,它就把wParam参数等于SC_CLOSE的WM_SYSCOMMAND消息放入消息队列中(这个WM_SYSCOMMAND消息是在用户从系统菜单中选择Close时产生的)。同样,窗口过程也把这个消息传给DefWindowProc。DefWindowProc通过给窗口过程发送WM_CLOSE消息来处理该消息。

  如果一个程序在终止之前要求来自用户的确认,那么窗口过程就需要捕获WM_CLOSE,否则DefWindowProc调用DestroyWindow函数来处理WM_CLOSE。除了其他处理,DestroyWindow还给窗口过程发送一个WM_DESTROY消息。窗口过程通常用下列代码来处理WM_DESTROY消息:

  case WM_DESTROY:

    PostQuitMessage(0);

    return 0;

  PostQuitMessage使Windows把WM_QUIT消息放入消息队列中,此消息永远不会到达窗口过程,因为它使GetMessage返回0,终止消息循环,从而也终止了程序。

  AskConfirmation(HWND hwnd)

  {

    return MessageBox(hwnd, TEXT("Really want to close PopPad2?"), szAppName, MB_YESNO | MB_ICONQUESTION);

  }

  case WM_CLOSE:

    if(IDYES == AskConfirmation(hwnd))

      DestroyWindow(hwnd);

    return 0;

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tg5156/archive/2010/07/07/5719795.aspx

你可能感兴趣的:(WM_CLOSE、WM_QUIT、WM_DESTROY区别)