代码改变世界

win32关于WM_QUERYENDSESSION消息

2011-10-12 18:08  捣乱小子  阅读(2845)  评论(0编辑  收藏  举报

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