admin管理员组

文章数量:1295117

I'm working on a Win32 desktop application in C++ and testing what happens when I retrieve display information using DISPLAY_DEVICE after disconnecting all physical displays. Surprisingly, the API still reports an active display even when no monitors are physically connected.

Sample code

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

    while (EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0)) {

        if (!(displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
            deviceIndex++;
            continue;  // Skip displays that are not part of the desktop
        }

        std::wstringstream debugMessage;
        debugMessage << L"Display Device " << deviceIndex << L": " << displayDevice.DeviceName << L" - " << displayDevice.DeviceString << L"\n";

        // Check if the display is active
        if (displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) {
            debugMessage << L"  Status: Active\n";
        }
        else {
            debugMessage << L"  Status: Inactive\n";
        }

        // Check if it's the primary display
        if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
            debugMessage << L"  Primary Display: Yes\n";
        }
        else {
            debugMessage << L"  Primary Display: No\n";
        }

        // Now, enumerate the monitor attached to this display device
        DISPLAY_DEVICE monitorDevice;
        monitorDevice.cb = sizeof(DISPLAY_DEVICE);
        int monitorIndex = 0;

        while (EnumDisplayDevices(displayDevice.DeviceName, monitorIndex, &monitorDevice, 0)) {
            debugMessage << L"    Monitor " << monitorIndex << L": " << monitorDevice.DeviceName << L" - " << monitorDevice.DeviceString << L"\n";
            monitorIndex++;
        }

        // Retrieve screen resolution using DEVMODE
        DEVMODE devMode;
        devMode.dmSize = sizeof(DEVMODE);
        if (EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) {
            debugMessage << L"  Screen Resolution: " << devMode.dmPelsWidth << L" x " << devMode.dmPelsHeight << L" pixels\n";
            debugMessage << L"  Refresh Rate: " << devMode.dmDisplayFrequency << L" Hz\n";
        }
        else {
            debugMessage << L"  Could not retrieve display settings.\n";
        }

        debugMessage << L"---------------------------------\n";

        // Send output to Visual Studio Debug window
        LogToDebugWindow(debugMessage.str());

        deviceIndex++;
    }
}

This is the output when I used DISPLAY_DEVICE with EnumDisplayDevices(), where I have 1 physical monitor connected

Display Device 1: \\.\DISPLAY2 - Intel(R) UHD Graphics 770
Status: Active
Primary Display: Yes
Monitor 0: \\.\DISPLAY2\Monitor0 - Generic PnP Monitor
Screen Resolution: 1920 x 1080 pixels
Refresh Rate: 60 Hz

When I removed all the physical monitors, This API is still telling me that I have an active Display connected

 Display Device 0: \\.\DISPLAY1 - Intel(R) UHD Graphics 770
 Status: Active
 Primary Display: Yes
 Monitor 0: \\.\DISPLAY1\Monitor0 - Digital Flat Panel (640x480 60Hz)
 Screen Resolution: 1920 x 1080 pixels
 Refresh Rate: 60 Hz

Why is this so? Does windows keep any "virtual display" active even when all monitor is physically disconnected?

I'm working on a Win32 desktop application in C++ and testing what happens when I retrieve display information using DISPLAY_DEVICE after disconnecting all physical displays. Surprisingly, the API still reports an active display even when no monitors are physically connected.

Sample code

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

    while (EnumDisplayDevices(NULL, deviceIndex, &displayDevice, 0)) {

        if (!(displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
            deviceIndex++;
            continue;  // Skip displays that are not part of the desktop
        }

        std::wstringstream debugMessage;
        debugMessage << L"Display Device " << deviceIndex << L": " << displayDevice.DeviceName << L" - " << displayDevice.DeviceString << L"\n";

        // Check if the display is active
        if (displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) {
            debugMessage << L"  Status: Active\n";
        }
        else {
            debugMessage << L"  Status: Inactive\n";
        }

        // Check if it's the primary display
        if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
            debugMessage << L"  Primary Display: Yes\n";
        }
        else {
            debugMessage << L"  Primary Display: No\n";
        }

        // Now, enumerate the monitor attached to this display device
        DISPLAY_DEVICE monitorDevice;
        monitorDevice.cb = sizeof(DISPLAY_DEVICE);
        int monitorIndex = 0;

        while (EnumDisplayDevices(displayDevice.DeviceName, monitorIndex, &monitorDevice, 0)) {
            debugMessage << L"    Monitor " << monitorIndex << L": " << monitorDevice.DeviceName << L" - " << monitorDevice.DeviceString << L"\n";
            monitorIndex++;
        }

        // Retrieve screen resolution using DEVMODE
        DEVMODE devMode;
        devMode.dmSize = sizeof(DEVMODE);
        if (EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) {
            debugMessage << L"  Screen Resolution: " << devMode.dmPelsWidth << L" x " << devMode.dmPelsHeight << L" pixels\n";
            debugMessage << L"  Refresh Rate: " << devMode.dmDisplayFrequency << L" Hz\n";
        }
        else {
            debugMessage << L"  Could not retrieve display settings.\n";
        }

        debugMessage << L"---------------------------------\n";

        // Send output to Visual Studio Debug window
        LogToDebugWindow(debugMessage.str());

        deviceIndex++;
    }
}

This is the output when I used DISPLAY_DEVICE with EnumDisplayDevices(), where I have 1 physical monitor connected

Display Device 1: \\.\DISPLAY2 - Intel(R) UHD Graphics 770
Status: Active
Primary Display: Yes
Monitor 0: \\.\DISPLAY2\Monitor0 - Generic PnP Monitor
Screen Resolution: 1920 x 1080 pixels
Refresh Rate: 60 Hz

When I removed all the physical monitors, This API is still telling me that I have an active Display connected

 Display Device 0: \\.\DISPLAY1 - Intel(R) UHD Graphics 770
 Status: Active
 Primary Display: Yes
 Monitor 0: \\.\DISPLAY1\Monitor0 - Digital Flat Panel (640x480 60Hz)
 Screen Resolution: 1920 x 1080 pixels
 Refresh Rate: 60 Hz

Why is this so? Does windows keep any "virtual display" active even when all monitor is physically disconnected?

Share Improve this question edited Feb 12 at 9:36 Thomas Weller 59.6k23 gold badges137 silver badges253 bronze badges asked Feb 12 at 9:20 HarshithHarshith 3203 silver badges12 bronze badges 6
  • 2 You are switching between two api's in your question: EnumDisplayMonitors and EnumDisplayDevices. Which one is your question about? Your mention of DISPLAY_DEVICE suggests the latter. – Mark Jansen Commented Feb 12 at 9:30
  • StateFlags can contain a flag DISPLAY_DEVICE_MIRRORING_DRIVER, you did not check this flag. Windows can return devices that are virtual. – Mark Jansen Commented Feb 12 at 9:59
  • @MarkJansen i tried with DISPLAY_DEVICE_MIRRORING_DRIVER, still I'm getting the same output as above, the value of state flag when no physical monitors are connected is 5 – Harshith Commented Feb 12 at 10:43
  • If you inspect the displayDevice.DeviceKey field, that will point you to a registry key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video` followed by a guid. Inspecting that key might yield some information about the type of device it is. For example, my system has {67D6A1EB-FBC2-11EE-A045-DC46286180E5}\Video` that contains a DeviceDesc that says: @rdpidd.inf,%rdpidd.devicedesc%;Microsoft Remote Display Adapter, indicating this is a display adapter for remote desktop. – Mark Jansen Commented Feb 12 at 14:34
  • Could you please tell us when you connect two physical monitors and then unplug one, is the enumeration skipped? – Jeaninez - MSFT Commented Feb 24 at 9:22
 |  Show 1 more comment

1 Answer 1

Reset to default 1

You might want to test DISPLAY_DEVICE_ATTACHED_TO_DESKTOP and/or DISPLAY_DEVICE_ACTIVE on the DISPLAY_DEVICE of the monitor, not the graphics device as you're currently doing (i.e. with monitorDevice)

本文标签: