MFC: 获得关机消息;阻止Windows关机
WM_QUERYENDSESSION消息是Windows向你询问Windows能否关闭,WM_ENDSESSION消息表示提示你Windows即将关闭。故当应用程序退出时, WM_QUERYENDSESSION消息和WM_ENDSESSION消息均不响应。也就是说也就是说,你的程序在运行状态时,而系统由于某种原因需要注销或重启(或关机),此时操作系统会向你询问,但到你的同意(返回TRUE)后,系统才能做进一步的操作。
The framework calls this member function when the user chooses to end the Windows session or when an application calls theExitWindows Windows function. If any application returns 0, the Windows session is not ended. Windows stops callingOnQueryEndSession as soon as one application returns 0 and sends theWM_ENDSESSION message with a parameter value ofFALSE for any application that has already returned nonzero.
当用户选择关闭Windows或者应用程序调用Windows的ExitWindows函数时,框架调用这个成员函数。如果应用程序返回0,则Windows会话不会结束。只要有一个应用程序返回了0,Windows就停止调用OnQueryEndSession,并且向所有已经返回非零值的应用程序发送一个WM_ENDSESSION消息,参数值为FALSE。
目的:当用户注销系统的时候,注销前,让我的程序执行几行代码(释放资源/关闭端口之类的)。
思路:就跟把系统注销、重启和关机的消息都拦截下来,并销毁掉,不让其执行注销、重启和关机等操作原理是一样的。因为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重载。
其函数体如下:
- 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
MFC: 获得关机消息;阻止Windows关机的更多相关文章
- 桌面程序阻止Windows关机(使用Message.Result取得DefWindowProc API函数的返回值,非常重要)
Windows Client 客户端在关机,不外乎两种情况: 1. 没有处理 Windows 关机消息: 2.处理了关机消息,但是超时了: 上面这两种情况,都会让Windows 关不了机.在现实生活中 ...
- Windows关机过程分析与快速关机
原文链接:http://blog.csdn.net/flyoxs/article/details/3710367 Windows开机和关机慢,很多时候慢得令人抓狂.特别是做嵌入式开发时(如XPE和Wi ...
- 深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒) good
之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...
- 深入windows的关机消息截获-从XP到Win7的变化
之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡.之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时 ...
- Windows 7下阻止系统关机
从Vista开始,想阻止系统关机就开始变麻烦了,不能只拦截WM_QUERYENDSESSION了,操作系统只给一个应用程序两秒钟的时间去保存自己的东西,两秒钟之后,不管做完了没有,Game Over! ...
- 编程实现Windows关机、重启、注销
要想编程使Windows关机.重启或者注销,可以使用ExWindowsEx这个API函数,该函数只有两个参数,第一个表示关机动作的标志,也就是你要让该函数关机呢,还是重启,还是注销等.可以使用EWX_ ...
- 再谈Delphi关机消息拦截 -- 之控制台程序 SetConsoleCtrlHandler(控制台使用回调函数拦截,比较有意思)
这里补充一下第一篇文章中提到的拦截关机消息 Delphi消息拦截:http://blog.csdn.net/cwpoint/archive/2011/04/05/6302314.aspx 下面我再介绍 ...
- C/C++控制Windows关机/注销/重启的正确姿势
简介 说到代码控制Windows关机/注销/重启的方式,有很多种,最简单的不过就是控制命令行,使用system("pause")函数执行一个shutdown -s -t 0,关机就 ...
- Ubuntu 拦截并监听 power button 的关机消息
system:ubuntu 18.04 platform:rockchip 3399 board:NanoPi M4 前言 物理上的电源按键短按之后,系统直接硬关机了,导致应用程序无法保护现场,就直接 ...
随机推荐
- APP测试(转载)
(1) 非功能测试 app测试的一个重要方面是app的非功能需求.移动app在推出市场或进行进一步开发前,测试人员有一定的职责做该类需求的跟踪工作. 早期开发阶段要进行的第一个测试应该是实用性测试.通 ...
- bzoj4326 运输计划
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n ...
- JAVA动态代理机制解析
1. 概述 首先,我们来思考如下两个问题: 什么是代理模式?为什么要使用代理模式? 简单总结一下,所谓的代理模式就是在原有的服务上多加一个占位,通过这个占位去控制服务的访问.通过代理模式,一方面可以控 ...
- java中队列Queue的使用
1.在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.Queue接口与List.Set同一级别,都是继承了Collection接口.Queue使用时要尽量避免Colle ...
- MySQL操作的一些优化
1.用于不要使用select * from table xxx. 需要查询哪些列就在语句中指明,一个表结构复杂时,可能会有上百列,使用*来查询时会造成很大的浪费. 2.选择合适的属性及大小 例如 ...
- HDU 5996 dingyeye loves stone [阶梯Nim]
dingyeye喜欢和你玩石子游戏. dingyeye有一棵nn个节点的有根树,节点编号为00到n−1n−1,根为00号节点.游戏开始时,第ii个节点上有a[i]a[i]个石子.两位玩家轮流操作,每次 ...
- POJ 2653 Pick-up sticks [线段相交 迷之暴力]
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 12861 Accepted: 4847 D ...
- WPF中的Command事件绑定
在项目中使用Command绑定能够使我们的代码更加的符合MVVM模式.不了解的同学可能不清楚,只有继承自ButtonBase类的元素才可以直接绑定Command(Button.CheckBox.Rad ...
- 软件开发:网站&视频&书籍推荐(不断更新)
利用书籍进行系统学习,凭借博客/新闻等资料开阔眼界,辅之以代码及项目实战,并勤加以总结,方可进步. 常用网站: Leetcode刷题:https://leetcode.com/ ,练习数据结构和算法必 ...
- IOS使用pods初次加载出现Pods-resources.sh: Permission denied错误的解决方案
在使用了pods之后首次编译加载时会出现错误 你的Pods存放目录/Pods/Target Support Files/Pods/Pods-resources.sh: Permission denie ...
