有没有办法检测 Windows 中的监视器状态(打开或关闭)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/203355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:34:28  来源:igfitidea点击:

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

windowswinapi

提问by Sam Saffron

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

有谁知道在 Windows (XP/Vista/2000/2003) 中是否有一个 API 来获取当前的监视器状态(打开或关闭)?

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

我所有的搜索似乎都表明没有真正的方法可以做到这一点。

This threadtries to use GetDevicePowerStatewhich according to Microsoft's docs does not work for display devices.

该线程尝试使用GetDevicePowerState,根据 Microsoft 的文档,它不适用于显示设备。

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

在 Vista 中,我可以收听GUID_MONITOR_POWER_ON但在手动关闭监视器时我似乎没有收到事件。

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

在 XP 中,我可以进入WM_SYSCOMMANDSC_MONITORPOWER,寻找状态 2。这仅适用于系统触发电源关闭的情况。

The WMI Win32_DesktopMonitorclass does not seem to help out as well.

WMIWin32_DesktopMonitor类似乎也没有帮助。

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

编辑:这是关于 comp.os.ms-windows.programmer.win32的讨论,表明没有可靠的方法可以做到这一点。

Anyone else have any other ideas?

其他人有任何其他想法吗?

采纳答案by Roger Lipscombe

GetDevicePowerStatesometimesworks for monitors. If it's present, you can open the \\.\LCDdevice. Close it immediately after you've finished with it.

GetDevicePowerState有时适用于监视器。如果存在,您可以打开该\\.\LCD设备。完成后立即关闭它。

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.

从本质上讲,您很不走运——没有可靠的方法来检测显示器电源状态,除非编写设备驱动程序并过滤显示驱动程序链上下的所有电源 IRP。而且这也不是很可靠。

回答by thijs

You could hook up a webcam, point it at your screen and do some analysis on the images you receive ;)

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

回答by Nir

Before doing anything based on the monitor state, just remember that users can use a machine with remote desktop of other systems that don't require a monitor connected to the machine - so don't turn off any visualization based on the monitor state.

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

回答by Avram

You can't.

你不能。

Look like all monitor power capabilities connected to the "power safe mode"
After searching i found herecode that connecting between SC_MONITORPOWERmessage 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.

看起来所有监视器电源功能都连接到“电源安全模式”
搜索后,我在这里找到连接SC_MONITORPOWER消息和系统值(帖子编号 2)
的代码,我使用该代码来测试手动切换时系统值是否发生变化关闭监视器。

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:

无论我关闭显示器多久,代码都不会停止。
有monitorOff函数的代码:

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".

结论:当您手动切换显示器时,您无法通过 windows 捕捉到它(如果没有异常的驱动程序接口),因为所有 windows 功能都连接到“电源安全模式”

回答by Fraser

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

在 Windows XP 或更高版本中,您可以使用 IMSVidDevice 接口。

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

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

(not sure if this works in Sever 2003)

(不确定这是否适用于 Sever 2003)

回答by Angus Johnston

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".

如果您的显示器有某种内置的 USB 集线器,您可以尝试使用它来检测显示器是否关闭/打开。
这当然只有在显示器被认为“关闭”时 USB 集线器没有保持连接的情况下才有效。

回答by Delphi

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

使用 Delphi 代码,您可以在待机期间检测无效的监视器几何体:

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:

在 Deplhi7 中待机时监控几何:

Monitor0: 1637792, 4210405, 31266576, 1637696

Monitor geometry while standby in DeplhiXE:

在 DeplhiXE 中待机时监控几何:

Monitor0: 4211194, 40, 1637668, 1637693

回答by Emrys Myrooin

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.

这是一篇很老的帖子,但如果它可以帮助某人,我找到了一种检测屏幕可用与否的解决方案:Windows 的连接和配置显示器 (CCD) API。

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

它是User32.ddland的一部分,有趣的函数是GetDisplayConfigBufferSizesand QueryDisplayConfig。它为我们提供了可以在窗口的配置面板中查看的所有信息。

In particular the PathInfocontains a TargetInfoproperty that have a targetAvailableflag. This flag seems to be correctly updated on all the configurations I have tried so far.

特别是PathInfo包含一个TargetInfo带有targetAvailable标志的属性。到目前为止,我尝试过的所有配置似乎都正确更新了此标志。

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

这使您可以了解连接到 PC 的每个屏幕的状态并设置其配置。

Here a CCD wrapper for .Net

这是 .Net 的 CCD 包装器