基于Windows API编程关闭所有显示器的C++方案问询
C++实现Windows显示器程序化关闭
需求概述
需要编写C++代码,实现与Windows屏幕超时自动关闭完全一致的效果:关闭所有显示器,且任意用户输入(按键、鼠标移动)可立即唤醒。方案需满足:
- 拒绝投机取巧的实现
- 代码尽可能简洁(参考创建最简窗口的思路)
- 基于C++开发
现有代码问题
你提供的代码并未实现预期功能,反而会触发系统睡眠,尽管SC_MONITORPOWER文档标注lParam=2用于关闭显示器:
#include <windows.h> int main() { SendNotifyMessageW(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2); }
注:你替换为
SendNotifyMessageW是为了解决SendMessage的阻塞问题,但核心问题是广播WM_SYSCOMMAND消息——Raymond Chen明确反对这种做法,因为部分应用会错误拦截并处理该消息,导致系统睡眠而非仅关闭显示器。
正确实现方案
核心思路
避免广播消息,创建一个最简不可见窗口,通过安全的方式发送显示器控制指令,确保系统正确识别为“关闭显示器”而非睡眠。
代码实现
#include <windows.h> // 最简窗口过程,仅处理必要退出逻辑 LRESULT CALLBACK MinimalWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { // 注册临时窗口类 const wchar_t* kWindowClass = L"MonitorPowerController"; WNDCLASS wc = {0}; wc.lpfnWndProc = MinimalWindowProc; wc.hInstance = hInstance; wc.lpszClassName = kWindowClass; RegisterClass(&wc); // 创建不可见的最简窗口 HWND hwnd = CreateWindowEx( 0, kWindowClass, L"", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if (!hwnd) return 1; // 发送关闭显示器指令,使用超时机制避免阻塞 SendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2, SMTO_ABORTIFHUNG | SMTO_BLOCK, 500, NULL ); // 清理窗口并退出 DestroyWindow(hwnd); return 0; }
代码说明
- 最简窗口:创建一个无界面的临时窗口,符合“简洁”要求,同时避免广播消息的副作用
- 安全消息发送:使用
SendMessageTimeoutW,既解决SendMessage的阻塞问题,又通过超时参数防止程序无响应 - 正确参数传递:
lParam=2严格对应“关闭显示器”指令,配合安全调用逻辑,确保系统不会误触发睡眠
关键细节
SC_MONITORPOWER参数说明:0:唤醒显示器1:切换至低功耗模式2:关闭显示器
- 禁止直接广播
WM_SYSCOMMAND:这是导致原代码触发睡眠的核心原因,部分应用会错误处理广播的系统命令
内容的提问来源于stack exchange,提问作者Dr. Gut
相关产品推荐
相关产品推荐

