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

时间:2008-10-15 00:42:49

标签: windows winapi

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

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

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

在Vista中,我可以收听GUID_MONITOR_POWER_ON,但是当手动关闭显示器时,我似乎无法获取事件。

在XP中,我可以挂钩WM_SYSCOMMAND SC_MONITORPOWER,查找状态2.这仅适用于系统触发电源的情况。

WMI Win32_DesktopMonitor类似乎也没有帮助。

编辑:comp.os.ms-windows.programmer.win32上的a discussion表示没有可行的方法。

其他人还有其他想法吗?

8 个答案:

答案 0 :(得分:12)

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

基本上,你运气不好 - 没有可靠的方法来检测显示器电源状态,缺少编写设备驱动程序并过滤显示驱动链中上下的所有电源IRP。这也不是很可靠。

答案 1 :(得分:12)

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

答案 2 :(得分:7)

在根据显示器状态执行任何操作之前,请记住,用户可以使用不需要连接到计算机的显示器的其他系统的远程桌面的计算机 - 因此请勿关闭基于显示器的任何可视化状态。

答案 3 :(得分:6)

你不能。

看起来所有显示器电源功能都连接到“电源安全模式”
搜索后,我找到 here 代码,用于连接 SC_MONITORPOWER 消息和系统值(帖子编号2)
当我手动关闭显示器时,我使用代码来测试系统值是否正在改变。

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

无论我关闭显示器多长时间,代码都不会停止 有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

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

答案 4 :(得分:2)

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

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

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

答案 5 :(得分:0)

如果您的显示器有某种内置USB集线器,您可以尝试使用它来检测显示器是否开启。
当然,只有当显示器被认为是关闭时,USB集线器才能保持连接,这才会起作用。

答案 6 :(得分:0)

使用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))

结果:

待机前监控几何图形:

Monitor0: 0, 0, 1600, 900

在Deplhi7中待机时监控几何图形:

Monitor0: 1637792, 4210405, 31266576, 1637696

在DeplhiXE中待机时监控几何图形:

Monitor0: 4211194, 40, 1637668, 1637693

答案 7 :(得分:0)

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

它是User32.ddl的一部分,有趣的功能是GetDisplayConfigBufferSizesQueryDisplayConfig。它为我们提供了可以在Windows配置面板中查看的所有信息。

特别是PathInfo包含TargetInfo标记的targetAvailable属性。这个标志似乎在我到目前为止尝试的所有配置上都已正确更新。

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

Here a CCD wrapper for .Net