You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows中如何检测显示器是否已断开连接(C++开发场景)

解决方案

你之前的方法无法正确检测断开状态的核心原因是:DISPLAY_DEVICE_ACTIVE标记仅表示设备已被系统识别并加载驱动,即使你在显示设置中“断开”显示器,设备本身仍处于激活状态,因此这个标记无法区分显示器当前是否在输出画面。

要准确检测系统显示设置中处于断开状态的显示器,应该使用QueryDisplayConfig API获取当前活跃的显示路径,再结合EnumDisplayDevices枚举的所有设备进行对比,不在活跃路径中的设备就是断开状态的。

实现代码

1. 获取活跃显示器列表

#include <Windows.h>
#include <vector>
#include <string>
#include <iostream>
#pragma comment(lib, "user32.lib")

// 获取当前活跃(正在显示)的显示器设备路径
std::vector<std::wstring> GetActiveMonitorDeviceNames() {
    std::vector<std::wstring> activeDevices;

    UINT32 pathCount = 0;
    UINT32 modeCount = 0;
    // 先查询所需缓冲区大小
    if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount) != ERROR_SUCCESS) {
        return activeDevices;
    }

    std::vector<DISPLAYCONFIG_PATH_INFO> paths(pathCount);
    std::vector<DISPLAYCONFIG_MODE_INFO> modes(modeCount);
    if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.data(), &modeCount, modes.data(), nullptr) != ERROR_SUCCESS) {
        return activeDevices;
    }

    for (const auto& path : paths) {
        DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
        targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
        targetName.header.size = sizeof(targetName);
        targetName.header.adapterId = path.targetInfo.adapterId;
        targetName.header.id = path.targetInfo.id;

        if (DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) {
            activeDevices.push_back(targetName.monitorDevicePath);
        }
    }

    return activeDevices;
}

2. 完整的显示器信息枚举(含断开状态检测)

struct MonitorInfo {
    std::wstring name;          // 设备名称(如\\.\DISPLAY1)
    std::wstring deviceString;  // 显示器型号名称
    int width;                  // 当前分辨率宽度
    int height;                 // 当前分辨率高度
    int refreshRate;            // 当前刷新率
    bool isActive;              // 是否处于活跃(连接显示)状态
};

std::vector<MonitorInfo> GetMonitorInfo() {
    std::vector<MonitorInfo> monitors;
    auto activeDevices = GetActiveMonitorDeviceNames();

    DISPLAY_DEVICE displayDevice = {};
    displayDevice.cb = sizeof(DISPLAY_DEVICE);
    int deviceIndex = 0;

    while (EnumDisplayDevicesW(NULL, deviceIndex, &displayDevice, 0)) {
        MonitorInfo info;
        info.name = displayDevice.DeviceName;
        info.deviceString = displayDevice.DeviceString;
        info.isActive = false;

        // 对比活跃列表,标记当前设备是否在显示中
        for (const auto& activeDev : activeDevices) {
            if (info.name == activeDev) {
                info.isActive = true;
                break;
            }
        }

        DEVMODEW devMode = {};
        devMode.dmSize = sizeof(DEVMODEW);
        devMode.dmDriverExtra = 0;
        if (EnumDisplaySettingsExW(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode, 0)) {
            info.width = devMode.dmPelsWidth;
            info.height = devMode.dmPelsHeight;
            info.refreshRate = devMode.dmDisplayFrequency;
        } else {
            // 无法获取当前设置,说明显示器未激活
            info.width = 0;
            info.height = 0;
            info.refreshRate = 0;
        }

        monitors.push_back(info);
        deviceIndex++;
    }

    return monitors;
}

int main() {
    std::vector<MonitorInfo> monitors = GetMonitorInfo();
    for (const auto& monitor : monitors) {
        std::wcout << L"Monitor Name: " << monitor.name << std::endl;
        std::wcout << L"Monitor String: " << monitor.deviceString << std::endl;
        std::wcout << L"Resolution: " << monitor.width << L"x" << monitor.height << std::endl;
        std::wcout << L"Refresh Rate: " << monitor.refreshRate << L" Hz" << std::endl;
        std::wcout << L"Is Connected: " << (monitor.isActive ? L"Yes" : L"No") << std::endl;
        std::wcout << std::endl;
    }
    return 0;
}

原理说明

  • QueryDisplayConfig配合QDC_ONLY_ACTIVE_PATHS参数,仅返回当前正在输出画面的显示路径,对应系统显示设置中“连接”状态的显示器。
  • 通过对比EnumDisplayDevices枚举的所有设备,就能筛选出不在活跃路径中的、处于“断开”状态的显示器。
  • 该方法对物理显示器和虚拟显示器均有效。

内容的提问来源于stack exchange,提问作者forDream

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:34:59