当结束对话或者一个程序调用系统关闭功能的时候,WM_QUERYENDSESSION消息会被发送给尚未终止的所有窗口。当程序在处理这个消息的时候,如果返回了false(0),那么系统将不结束对话或者关机(注销)。
所以在处理这消息的时候,我们要有个好的习惯,就是对数据进行保护操作,以免造成数据的损失。
网摘了一个比较经典的解释:
原理:Windows在关机的时候会想所有顶层窗口广播一个消息WM_QUERYENDSESSION,其lParam参数可以区分是关机还是注销用户(注销用户时lParam是ENDSESSION_LOGOFF)。然后Windows会等到所有的应用程序都对这个消息返回TRUE才会关机,因此,只要我们的应用程序对这个消息的处理返回FALSE,Windows就不会关机了。而且通过这个例子,大家也应该可以区分系统关机和注销用户了吧。
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_DESTROY : PostQuitMessage (0) ; return 0 ; case WM_QUERYENDSESSION: ::MessageBox(hwnd,"未经本程序许可,你不能关机!","禁止关机",MB_OK|MB_SYSTEMMODAL); return 0;//此处返回0则不能关机,返回1就能关机。 } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
或者这样也可以:
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_DESTROY : PostQuitMessage (0) ; return 0 ; case WM_QUERYENDSESSION: //保护数据操作 return 1;//返回1则可以结束程序 } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
关于lParam参数是通知码有一些的值:
ENDSESSION_CLOSEAPP
0x00000001
The application is using a file that must be replaced, the system is being serviced, or system resources are exhausted. For more information, see Guidelines for Applications.
ENDSESSION_LOGOFF
0x80000000
The user is logging off. For more information, see Logging Off.