Win32 响应windows系统睡眠/休眠和重启/关机/注销的消息

xingyun86 2022-10-12 1160

Win32 响应windows系统睡眠/休眠和重启/关机/注销的消息

(这里以win7为例,xp、win8/win10类似)

1.睡眠/休眠

windows系统默认显示睡眠,休眠是不显示的,如下图所示:

如果要调出休眠选项,可在控制面板中选择电源选项->更改计划设置->更改高级电源选项,到下图

关闭混合睡眠,设置休眠时间,保存后即可显示休眠,如下图,

所谓的混合睡眠,就是睡眠和休眠混合在一起,如果想感受其中的差别,可以自己点击分别感受下:

睡眠:关闭混合睡眠和休眠,点击睡眠按钮,即可进入睡眠模式,多次点击鼠标或键盘即可恢复

休眠:关闭混合睡眠,点击休眠按钮,即可进入休眠模式,只能通过按压开机按钮才能恢复

混合睡眠:打开混合睡眠,点击睡眠,即可进入混合睡眠模式,多次点击鼠标或键盘即可恢复

注意:xp系统显示的是待机/休眠,win7/win8/win10则显示的是睡眠/休眠

2.消息响应

(WindowProc与DefWindowProc的区别是前面用来处理自定义的窗口的消息,而后面是windows系统默认处理的消息,所以应该重载WindowProc

通过MFC查看WindowProc源码,可看到函数里面未处理的消息会调用DefWindowProc)

1)睡眠/休眠

睡眠/休眠响应的消息是一样的,都是PBT_APMSUSPEND,恢复的时候是PBT_APMRESUMEAUTOMATIC,而对于PBT_APMQUERYSUSPEND这个消息测试的时候发现收不到,所以程序中没有用

LRESULT CDlg***::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	switch (message)
	{
	case WM_POWERBROADCAST:
		{
			switch(wParam)
			{
			case PBT_APMSUSPEND:         //睡眠、休眠
				{
					....
				}
				break;
			case PBT_APMRESUMEAUTOMATIC: //睡眠、休眠恢复
				{
					....
				}
				break;
			}
		}
		break;
	}	  
	return CDialogEx::WindowProc(message, wParam, lParam);
}

经验证从xp到win10所有系统,都能响应到消息


如何像暴风影音那样,播放视频的时候禁止系统自动睡眠,播放完了再恢复呢?

利用SetThreadExecutionState这个api函数即可

播放视频时:

::SetThreadExecutionState( ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED );

停止播放时:

::SetThreadExecutionState( ES_CONTINUOUS );

2.重启/关机/注销

重启/关机/注销都是系统向应用程序发送一个消息WM_QUERYENDSESSION,确定关闭时再发送一个WM_ENDSESSION,其中通过lParam可以区分是注销(ENDSESSION_LOGOFF),还是重启/关机(注意:无法区分是重启还是关机)

原理:

LRESULT CDlg****::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	switch (message)
	{
	case WM_QUERYENDSESSION:            //关机、重启、注销
		{ 
			if (lParam == ENDSESSION_LOGOFF)//注销
			{
				....
			}
			else   //重启/关机
			{
				....
			}
		}
		break;
	}	  
	return CDialogEx::WindowProc(message, wParam, lParam);
}

说明:

(1)经验证DefWindowProc中响应不到该消息WM_QUERYENDSESSION的,只有WindowProc中才能响应到

(2)下面是从xp到win10系统响应消息时的wParam,lParam值,仅供参考,

xp:重启、管家,wpara、lpawa都是0,    注销:lParam:-2147483648,wpara:0
win7:重启、管家,wpara、lpawa都是0,  注销:lParam:-2147483648,wpara:0
win8:重启、管家,wpara、lpawa都是0,  注销:lParam:-2147483648,wpara:0
 
win10有的与上面一样,有的则是下面的值
 
部分win10:
重启:lParam:1073741824,wpara:0
管家:lParam:1073741824,wpara:0
注销:lParam:-2147483648,wpara:0

可以看出注销时lParam都是一样的,而重启/关机时值有些不同

(3)能阻止系统重启或关机吗?

网上有说在响应WM_QUERYENDSESSION中通过返回FALSE来禁止系统重启/关机,经验证从xp到win10,有的系统可以,而有的系统不管返回值是TRUE还是FALSE,WM_ENDSESSION接受到的关机参数都是TRUE,即会直接重启/关机,所以是无法兼容所有系统做到阻止系统重启或关机的

(4)设置重启/关机/注销时程序退出顺序

当系统发生上述行为时,可以设置程序不是最先被退出的,防止用户点击取消重启/关机/注销

//设置系统重启、关闭、注销时程序关闭顺序
SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);

可自行网上搜索这个api,注意第一个参数如果设置为0,会导致系统在重启/关机/注销的画面已经出来后应用程序仍然显示的情况,参考第一个参数的范围合理设置值即可

注意(纯属个人理解):应用程序一般通过WM_QUERYENDSESSION和SetProcessShutdownParameters来处理程序防止假重启/关机/注销的情况,而不是直接响应WM_ENDSESSION进行处理,个人感觉响应WM_QUERYENDSESSION留给程序处理的时间更多一些。


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回