简体   繁体   中英

Is there any way to detect the monitor state in Windows (on or off)?

Does anyone know if there is an API to get the current monitor state (on or off) in Windows (XP/Vista/2000/2003)?

All of my searches seem to indicate there is no real way of doing this.

This thread tries to use GetDevicePowerState which according to Microsoft's docs does not work for display devices.

In Vista I can listen to GUID_MONITOR_POWER_ON but I do not seem to get events when the monitor is turned off manually.

In XP I can hook into WM_SYSCOMMAND SC_MONITORPOWER , looking for status 2. This only works for situations where the system triggers the power off.

The WMI Win32_DesktopMonitor class does not seem to help out as well.

Edit : Here is a discussion on comp.os.ms-windows.programmer.win32 indicating there is no reliable way of doing this.

Anyone else have any other ideas?

GetDevicePowerState sometimes works for monitors. If it's present, you can open the \\\\.\\LCD device. Close it immediately after you've finished with it.

Essentially, you're out of luck—there is no reliable way to detect the monitor power state, short of writing a device driver and filtering all of the power IRPs up and down the display driver chain. And that's not very reliable either.

您可以连接网络摄像头,将其对准屏幕并对收到的图像进行一些分析;)

在根据监视器状态做任何事情之前,请记住,用户可以使用具有其他系统远程桌面的机器,不需要将监视器连接到机器 - 所以不要关闭任何基于监视器状态的可视化。

You can't.

Look like all monitor power capabilities connected to the "power safe mode"
After searching i found here code that connecting between SC_MONITORPOWER message and system values (post number 2)
I use the code to testing if the system values is changing when i am manually switch off the monitor.

int main()
{
    for(;monitorOff()!=1;)
        Sleep(500);
    return 0;
}//main

And the code is never stopped, no matter how long i am switch off my monitor.
There the code of monitorOff function:

int monitorOff()
{
    const GUID MonitorClassGuid =
        {0x4d36e96e, 0xe325, 0x11ce, 
            {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};

    list<DevData> monitors;
    ListDeviceClassData(&MonitorClassGuid, monitors);

    list<DevData>::iterator it = monitors.begin(),
                            it_end = monitors.end();
    for (; it != it_end; ++it)
    {
        const char *off_msg = "";

        //it->PowerData.PD_PowerStateMapping
        if (it->PowerData.PD_MostRecentPowerState != PowerDeviceD0)
        {
            return 1;
        }
    }//for

    return 0;
}//monitorOff

Conclusion : when you manually switch of the the monitor, you cant catch it by windows (if there is no unusual driver interface for this), because all windows capabilities is connected to "power safe mode" .

In Windows XP or later you can use the IMSVidDevice Interface.

See http://msdn.microsoft.com/en-us/library/dd376775(VS.85).aspx

(not sure if this works in Sever 2003)

If your monitor has some sort of built-in USB hub, you could try and use that to detect if the monitor is off/on.
This will of course only work if the USB hub doesn't stay connected when the monitor is consider "off".

With Delphi code, you can detect invalid monitor geomerty while standby in progress:

i := 0
('Monitor'+IntToStr(i)+': '+IntToStr(Screen.Monitors[i].BoundsRect.Left)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Top)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Right)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Bottom))

Results:

Monitor geometry before standby:

Monitor0: 0, 0, 1600, 900

Monitor geometry while standby in Deplhi7:

Monitor0: 1637792, 4210405, 31266576, 1637696

Monitor geometry while standby in DeplhiXE:

Monitor0: 4211194, 40, 1637668, 1637693

This is a really old post but if it can help someone, I have found a solution to detect a screen being available or not : the Connecting and Configuring Displays (CCD) API of Windows.

It's part of User32.ddl and the interesting functions are GetDisplayConfigBufferSizes and QueryDisplayConfig . It give us all informations that can be viewed in the Configuration Panel of windows.

In particular the PathInfo contains a TargetInfo property that have a targetAvailable flag. This flag seems to be correctly updated on all the configurations I have tried so far.

This allow you to know the state of every screens connected to the PC and set their configurations.

Here a CCD wrapper for .Net

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM