MFC应用退出
三个结束消息
WM_CLOSE
选择了“关闭”或者点击了窗口右上角的“X”按钮,窗口过程就会收到WM_CLOSE。DefWindowProc对 WM_CLOSE的处理是调用DestroyWindow。当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改等。如果用户选择“取消”,你忽略此消息,程序照常运行,如果用户确认要退出,你就调用DestroyWindow。
WM_DESTROY
estroyWindow完成窗口的清理工作,最后向窗口过程发送WM_DESTROY。对于 WM_DESTROY,DefWindowProc不会处理。也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。一般处理 WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage。
WM_QUIT
PostQuitMessage会发送WM_QUIT给消息队列。注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,从而结束消息循环,最后进程结束,程序退出。
OnClose和OnDestroy
OnClose
消息响应函数,响应WM_CLOSE消息,当"关闭"按钮被单击的时候(而不是我们眼睛所见的对话框从屏幕上消失时),该函数被调用,用户在响应OnOk()或者OnCancel()函数之后,不会发送WM_CLOSE消息。
OnDestroy
消息响应函数,响应WM_DESTROY消息,当一个窗口即将被销毁时,被发送在单视图程序中。
程序退出时执行的操作顺序为:
(1)用户点击退出按钮,发送了WM_CLOSE消息
(2)在WM_CLOSE消息的处理函数中,调用DestroyWindow()
(3)在DestroyWindow()中发送了WM_DESTROY消息
(4)在WM_DESTROY消息中调用PostQuitMessage(),发送WM_QUIT消息,结束消息循环
综上,程序先调用OnClose()(也可能不调用),然后调用OnDestroy()(必调用),所以,如果要进行程序结束时的清理工作,应该在OnDestroy中,而不是在OnClose,否则就有可能会出现内存泄漏的危险。
SendMessage和PostMessage
PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回。
CallWindowProc和DefWindowProc
// 函数功能:CallWindowProc将指定消息信息传送给指定的窗口过程. lpPrevWndFunc是窗口消息处理函数指针(函数名), hWnd为接受窗体句柄.
LRESULT CallWindowProc(WNDPROC lpPrevWndFunc,HWND hWnd.UINT Msg,WPARAM wParam,LPARAMIParam);
// 函数功能:该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理。该函数确保每一个消息得到处理。调用DefWindowProc函数时使用窗口过程接收的相同参数。
DefWindowProc(HWND hWnd.UINT Msg,WPARAM wParam,LPARAMIParam);
区别
CallWindowProc 是发送某个消息给某个处理函数(包括自定义消息处理函数), 而DefWindowProc 是发送某个消息给Windows缺省(内定)的消息处理函数。
注
在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消息。在API里定义了一个函数为回调函数,当系统需要向窗口发送消息时,就会调用窗口给出的回调函数WindowProc,如果WindowProc函数不处理这个消息,就可以把它转向DefWindowProc函数来处理,这是系统的默认消息处理函数。当你按下菜单,或者点击窗口时,窗口需要运行这个消息处理函数。
DefWindowProc函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理。该函数确保每一个消息得到处理。如果某些消息你不需要做特别的处理,调用DefWindowProc进行处理就可以了,不需要你自己再去些那些windows的"标准动作"。当DefWindowProc处理WM_DESTROY消息时,它不自动调用PostQuitMessage。
退出应用的代码
exit(0);
postquitmessage(0);
onok();
oncancel();
sendmessage(wm_close,0,0);
exitprocess(0);