11

I have a custom application written in C++ that controls the resolution and other settings on a monitor connected to an embedded system. Sometimes the system is booted headless and run via VNC, but can have a monitor plugged in later (post boot). If that happens he monitor is fed no video until the monitor is enabled. I have found calling "displayswitch /clone" brings the monitor up, but I need to know when the monitor is connected. I have a timer that runs every 5 seconds and looks for the monitor, but I need some API call that can tell me if the monitor is connected.

Here is a bit of psudocode to describe what I'm after (what is executed when the timer expires every 5 seconds).

if(If monitor connected) 
{
   ShellExecute("displayswitch.exe /clone);
}else
{
   //Do Nothing
}

I have tried GetSystemMetrics(SM_CMONITORS) to return the number of monitors, but it returns 1 if the monitor is connected or not. Any other ideas?

Thanks!

martinarcher
  • 137
  • 2
  • 9
  • also there is this : http://stackoverflow.com/questions/181064/enumdisplaydevices-vs-wmi-win32-desktopmonitor-how-to-detect-active-monitors but I'm afraid this is beyond me - good luck – Caribou Jan 11 '13 at 22:08
  • XP Embedded? Windows Embedded Compact 7? – Sheng Jiang 蒋晟 Jan 11 '13 at 23:49
  • Monitors are platform dependent. I am currently working on an embedded project that doesn't have a monitor. – Thomas Matthews Jan 12 '13 at 01:20
  • Although not C++, there's a python script [On this SO question](http://stackoverflow.com/questions/10400236/how-to-observe-changes-in-connected-monitors-via-xlib) which could easily be ported – Barton Feb 01 '14 at 21:49

2 Answers2

3

Try the following code

BOOL IsDisplayConnected(int displayIndex = 0)
{
    DISPLAY_DEVICE device;
    device.cb = sizeof(DISPLAY_DEVICE);
    return EnumDisplayDevices(NULL, displayIndex, &device, 0);
}

This will return true if Windows identifies a display device with index (AKA identity) 0 (this is what the display control panel uses internally). Otherwise, it will return false false. So by checking the first possible index (which I marked as the default argument), you can find out whether any display device is connected (or at least identified by Windows, which is essentially what you're looking for).

Yam Marcovic
  • 7,953
  • 1
  • 28
  • 38
0

Seems that there is some kind of "default monitor" even if no real monitor is connected. The function below works for me (tested on a Intel NUC and a Surface 5 tablet).

The idea is to get the device id and check if it contains the string "default_monitor".

bool hasMonitor()
{
    // Check if we have a monitor
    bool has = false;

    // Iterate over all displays and check if we have a valid one.
    //  If the device ID contains the string default_monitor no monitor is attached.
    DISPLAY_DEVICE dd;
    dd.cb = sizeof(dd);
    int deviceIndex = 0;
    while (EnumDisplayDevices(0, deviceIndex, &dd, 0))
    {
        std::wstring deviceName = dd.DeviceName;
        int monitorIndex = 0;
        while (EnumDisplayDevices(deviceName.c_str(), monitorIndex, &dd, 0))
        {   
            size_t len = _tcslen(dd.DeviceID);
            for (size_t i = 0; i < len; ++i)
                dd.DeviceID[i] = _totlower(dd.DeviceID[i]);

            has = has || (len > 10 && _tcsstr(dd.DeviceID, L"default_monitor") == nullptr);

            ++monitorIndex;
        }
        ++deviceIndex;
    }

    return has;
}