在跨平台桌面应用开发中,获取系统锁屏状态是一个常见需求,比如当系统锁屏时暂停资源占用较高的后台任务,或者保存当前操作进度。不同操作系统的锁屏机制完全不同,Windows平台可以通过监听系统会话切换事件实现,Linux和macOS则需要使用各自系统的桌面环境接口,无法用统一的API实现,需要分平台编写适配代码。

Windows平台实现方案
Windows系统中,用户触发锁屏操作时会调用LockWorkStation函数,同时系统会发送WM_WTSSESSION_CHANGE消息通知会话状态变化,我们可以通过注册会话通知来监听锁屏事件。
核心实现步骤
- 调用
WTSRegisterSessionNotification函数注册会话通知,指定接收会话变化消息的窗口句柄 - 在窗口消息处理函数中监听
WM_WTSSESSION_CHANGE消息,当参数wParam为WTS_SESSION_LOCK时表示系统锁屏,为WTS_SESSION_UNLOCK时表示系统解锁 - 程序退出时调用
WTSUnRegisterSessionNotification取消注册,避免资源泄漏
Windows平台示例代码
#include <windows.h>
#include <wtsapi32.h>
#include <iostream>
#pragma comment(lib, "wtsapi32.lib")
// 窗口消息处理函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_WTSSESSION_CHANGE:
// 会话状态变化事件
if (wParam == WTS_SESSION_LOCK) {
std::cout << "Windows系统已锁屏" << std::endl;
} else if (wParam == WTS_SESSION_UNLOCK) {
std::cout << "Windows系统已解锁" << std::endl;
}
break;
case WM_DESTROY:
// 取消会话通知注册
WTSUnRegisterSessionNotification(hwnd);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int main() {
HINSTANCE hInstance = GetModuleHandle(NULL);
// 注册窗口类
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"LockScreenListener";
RegisterClassEx(&wc);
// 创建隐藏窗口用于接收消息
HWND hwnd = CreateWindowEx(
0, L"LockScreenListener", L"LockScreenListener",
0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL
);
// 注册会话通知
if (!WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION)) {
std::cerr << "注册会话通知失败" << std::endl;
return 1;
}
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Linux平台实现方案
Linux系统的锁屏状态通常由桌面环境管理,主流的GNOME、KDE等桌面环境都提供了基于D-Bus的接口来查询和监听锁屏状态,我们可以通过调用D-Bus接口实现监听。
核心实现步骤
- 连接到系统D-Bus会话总线
- 监听
org.gnome.ScreenSaver服务的ActiveChanged信号,或者org.freedesktop.ScreenSaver的对应信号 - 信号触发时根据参数判断锁屏状态,参数为true表示锁屏,false表示解锁
Linux平台示例代码
#include <dbus/dbus.h>
#include <iostream>
#include <cstring>
// D-Bus消息过滤函数
DBusHandlerResult message_filter(DBusConnection* connection, DBusMessage* message, void* user_data) {
// 匹配ScreenSaver的ActiveChanged信号
if (dbus_message_is_signal(message, "org.gnome.ScreenSaver", "ActiveChanged")) {
DBusError error;
dbus_error_init(&error);
dbus_bool_t locked;
// 获取信号参数
if (dbus_message_get_args(message, &error, DBUS_TYPE_BOOLEAN, &locked, DBUS_TYPE_INVALID)) {
if (locked) {
std::cout << "Linux系统已锁屏" << std::endl;
} else {
std::cout << "Linux系统已解锁" << std::endl;
}
}
dbus_error_free(&error);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int main() {
DBusError error;
dbus_error_init(&error);
// 连接到会话总线
DBusConnection* connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
if (dbus_error_is_set(&error)) {
std::cerr << "连接D-Bus失败: " << error.message << std::endl;
dbus_error_free(&error);
return 1;
}
// 添加消息过滤
dbus_bus_add_match(connection, "type='signal',interface='org.gnome.ScreenSaver'", &error);
if (dbus_error_is_set(&error)) {
std::cerr << "添加D-Bus匹配失败: " << error.message << std::endl;
dbus_error_free(&error);
return 1;
}
dbus_connection_add_filter(connection, message_filter, NULL, NULL);
// 进入D-Bus消息循环
while (dbus_connection_read_write_dispatch(connection, -1)) {
// 循环处理消息
}
return 0;
}
macOS平台实现方案
macOS系统可以通过监听com.apple.screenIsLocked分布式通知来获取锁屏状态,使用CoreFoundation框架的分布式通知中心实现监听。
核心实现步骤
- 获取分布式通知中心实例
- 注册监听
com.apple.screenIsLocked和com.apple.screenIsUnlocked两个通知 - 在回调函数中处理锁屏和解锁事件
macOS平台示例代码
#include <CoreFoundation/CoreFoundation.h>
#include <iostream>
// 通知回调函数
void notification_callback(CFNotificationCenterRef center, void* observer, CFStringRef name, const void* object, CFDictionaryRef userInfo) {
if (CFStringCompare(name, CFSTR("com.apple.screenIsLocked"), 0) == kCFCompareEqualTo) {
std::cout << "macOS系统已锁屏" << std::endl;
} else if (CFStringCompare(name, CFSTR("com.apple.screenIsUnlocked"), 0) == kCFCompareEqualTo) {
std::cout << "macOS系统已解锁" << std::endl;
}
}
int main() {
// 获取分布式通知中心
CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
// 注册锁屏通知
CFNotificationCenterAddObserver(
center, NULL, notification_callback,
CFSTR("com.apple.screenIsLocked"),
NULL, CFNotificationSuspensionBehaviorDeliverImmediately
);
// 注册解锁通知
CFNotificationCenterAddObserver(
center, NULL, notification_callback,
CFSTR("com.apple.screenIsUnlocked"),
NULL, CFNotificationSuspensionBehaviorDeliverImmediately
);
// 运行当前线程的RunLoop
CFRunLoopRun();
return 0;
}
跨平台适配封装建议
为了让代码更易于维护,可以使用条件编译的方式将三个平台的实现封装到统一的接口中,对外提供统一的锁屏状态监听函数,内部根据编译平台自动选择对应的实现逻辑。
// 统一接口头文件 #pragma once #include <functional> // 锁屏状态回调类型,参数为true表示锁屏,false表示解锁 using LockScreenCallback = std::function<void(bool)>; // 启动锁屏状态监听 void start_lock_screen_listener(LockScreenCallback callback); // 停止锁屏状态监听 void stop_lock_screen_listener();
不同平台分别实现上述接口,在编译时通过_WIN32、__linux__、__APPLE__等宏判断当前平台,编译对应平台的实现代码即可。需要注意的是,不同平台的依赖库不同,Windows平台需要链接wtsapi32.lib,Linux平台需要安装dbus-devel库,macOS平台需要链接CoreFoundation.framework。
C++跨平台系统锁屏状态LockWorkStationWindows监听修改时间:2026-07-16 17:42:49