当结束对话或者一个程序调用系统关闭功能的时候,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.