Qt监听Windows锁屏、解锁、休眠、唤醒、登录、注销消息
环境:Windows 11 笔记本,其它环境未测试
根据其它博客的直接在窗口 nativeEvent
中监听 WM_WTSSESSION_CHANGE
会话消息和 WM_POWERBROADCAST
电源消息发现不起作用,查阅尝试后找到可行方法如下:
会话事件和电源消息都需要先用Windows API注册窗口句柄
void MainWindow::registerSysNotification()
{
#ifdef Q_OS_WINDOWS
// 注册指定窗口以接收会话更改通知,获取锁屏,解锁,登录,注销等消息
bool ret = WTSRegisterSessionNotification((HWND)this->winId(), NOTIFY_FOR_THIS_SESSION);
qDebug() << "会话事件通知注册" << (ret ? "成功" : "失败");
// 注册以便在系统暂停或恢复时接收通知,最低支持 win8
HPOWERNOTIFY res = RegisterSuspendResumeNotification((HWND)this->winId(), DEVICE_NOTIFY_WINDOW_HANDLE);
qDebug() << "电源事件通知注册" << (res != NULL ? "成功" : "失败");
#endif
}
注意:根据MSDN文档,WTSRegisterSessionNotification
和 RegisterSuspendResumeNotification
函数都只能用在 win8 及以上桌面系统中,不支持 win7。
然后在 nativeEvent
中处理消息
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
#ifdef Q_OS_WIN32
MSG* msg = (MSG*)message;
switch (msg->message) {
case WM_WTSSESSION_CHANGE://判断登录、注销、锁屏等
{
switch (msg->wParam) {
case WTS_SESSION_LOCK:
qDebug() << "锁屏";
isScreenLock = true;
break;
case WTS_SESSION_UNLOCK:
qDebug() << "解锁";
isScreenLock = false;
break;
case WTS_SESSION_LOGON:
qDebug() << "登录";
break;
case WTS_SESSION_LOGOFF:
qDebug() << "注销";
break;
case WTS_SESSION_REMOTE_CONTROL:
qDebug() << "被远程控制";
break;
default:
break;
}
case WM_POWERBROADCAST:
{
switch (msg->wParam) {
case PBT_APMSUSPEND:
qDebug() << "系统进入休眠状态";
isPowerSleep = true;
break;
case PBT_APMRESUMEAUTOMATIC:
qDebug() << "系统从休眠状态恢复";
isPowerSleep = false;
break;
case PBT_APMPOWERSTATUSCHANGE:
qDebug() << "系统电源状态更改";
break;
default:
break;
}
}
}
default:
break;
}
#endif
return QMainWindow::nativeEvent(eventType, message, result);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!