MFC中应用WM_ENDSESSION,WM_QUERYENDSESSION消息截获系统的关机/注销

目的:当用户注销系统的时候,注销前,让我的程序执行几行代码(释放资源/关闭端口之类的)。

思路:就跟把系统注销、重启和关机的消息都拦截下来,并销毁掉,不让其执行注销、重启和关机等操作原理是一样的。因为Windows在注销、重起、关机之前会向每个当前正在运行的应用程序广播一个消息WM_QUERYENDSESSION, 其lParam参数可以区分是关机还是注销用户(注销用户时lParam是ENDSESSION_LOGOFF)。然后Windows会等到所有的应用程序都对这个消息返回TRUE才会关机,因此,只要我们的应用程序对这个消息的处理返回FALSE,Windows就不会关机了。当系统注销的时候,所有非系统级的程序都会被退出,如果想让自己的程序在注销时仍然可以运行,就将自己的程序做成系统服务程序。

解决途径:拦截系统广播出来的WM_ENDSESSION和WM_QUERYENDSESSION消息。插一句:方法应该不止一种,比如系统钩子,但是参考网友的解决方案,程序一运行系统就奔溃了。没想到在MFC里面非常容易的通过重载WindowProc就可以实现,方法如下。

在MFC中的解决方法:

环境:VS 6.0, XP 32-bit

“查看”-->"建立类向导...",将WindowProc重载。

MFC中应用WM_ENDSESSION,WM_QUERYENDSESSION消息截获系统的关机/注销_第1张图片

其函数体如下:

LRESULT CLabRelayDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class

	// WM_QUERYENDSESSION消息是Windows向你询问Windows能否关闭
	// WM_ENDSESSION消息表示提示你Windows即将关闭。
	switch(message)	{
	case WM_ENDSESSION:	   
	   // 把消息销毁掉,不让其正确转发。
	   //message = WM_USERMESSAGE_NULL;

		//turn off the relay
		if(relayState==RELAY_ON) 
			turnOff();
	   break ;
	case WM_QUERYENDSESSION: //注销/关机
	   
	   //turn off the relay
	   if(relayState==RELAY_ON) 
		turnOff();

	   break ;
	}
	
	return CDialog::WindowProc(message, wParam, lParam);
}

就这样,系统注销的时候我的函数turnOff();被执行了。


关于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


非常有帮助的链接:

http://www.cnblogs.com/likebeta/archive/2012/03/31/2426632.html

http://blog.sina.com.cn/s/blog_7ce2cb410100wydw.html

http://www.cnblogs.com/lidabo/archive/2012/11/29/2795269.html

http://blog.csdn.net/silvervi/article/details/5131299

http://blog.csdn.net/goingup/article/details/457128


你可能感兴趣的:(VC++6.0)