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;
WM_QUERYENDSESSION
当用户选择关闭系统时,Windows发送一个WM_QUERYENDSESSION消息给每个打开的应用程序。如果应用程序可以被关闭,则应在处理完该消息后返回TRUE,否则应返回FALSE。如果每个应用程序都返回TRUE,则Windows进入关闭进程,如果任何一个窗口消息处理程序拦截这个消息后传回FALSE,Windows将停止关闭系统。要在程序结束之前要求使用者的确认,必须处理WM_CLOSE和WM_QUERYENDSESSION这两个消息。
case WM_QUERYENDSESSION:
if(IDYES == AskConfirmation(hwnd))
return 1;
else
return 0;
WM_ENDSESSION
Windows将WM_ENDSESSION消息发送给先前收到WM_QUERYENDSESSION消息的每个窗口消息处理程序。如果由于另一个程序从WM_QUERYENDSESSION传回了0导致Windows不能关闭系统,那么WM_ENDSESSION的wParam参数为0。WM_ENDSESSION消息实际上回答了这个问题:我告诉过Windows可以把我结束掉,但是我真的被结束掉了吗?