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文档,WTSRegisterSessionNotificationRegisterSuspendResumeNotification 函数都只能用在 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);
}
posted @ 2024-10-12 09:39  jixhua  阅读(156)  评论(0编辑  收藏  举报