【问题标题】:Is there any way to detect the monitor state in Windows (on or off)?有什么方法可以检测 Windows 中的监视器状态(打开或关闭)?
【发布时间】:2010-09-17 05:31:58
【问题描述】:

有谁知道是否有 API 可以在 Windows (XP/Vista/2000/2003) 中获取当前显示器状态(打开或关闭)?

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

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,表明没有可靠的方法可以做到这一点。

还有人有其他想法吗?

【问题讨论】:

  • 你想用这些信息做什么?也许我们可以帮助解决真正的问题。问候。
  • 粗略估计与计算机物理连接的显示器的功耗

标签: windows winapi


【解决方案1】:

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

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

【讨论】:

  • 我认为这是最接近问题的答案。这是硬件制造商的真正失败,因为它没有在 DVI 标准中为我们提供那种级别的通信。
  • 说真的,完成后立即关闭它。我曾经因为未能做到这一点而打破了迈克尔戴尔笔记本电脑上的演示模式:)
  • GetDevicePowerState 的文档说“此函数不能用于查询显示设备的电源状态。”
  • 除非他们在 Windows Vista 和现在之间进行了更改(这是可能的),否则文档是错误的。该功能不能用于可靠地查询显示设备的电源状态,但它确实在我们试用过的大多数(数千)台计算机上工作。
【解决方案2】:

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

【讨论】:

  • 但是您可能会将反射误认为是屏幕操作。我认为您正在将设备驱动程序问题转变为图像处理问题。我喜欢它:)
  • 该技术已被用于监控远程位置的设备架。将相机对准机架,观察指示灯的“异常”变化。它的蛮力,但在某些情况下,这是唯一合理的答案。
【解决方案3】:

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

【讨论】:

  • Windows API 允许您确定监视器是否“真实”。请参阅:DISPLAY_DEVICE_MIRRORING_DRIVER。
  • 远程桌面应用程序仍然会影响屏幕保护程序,不是吗? (至少 RealVNC 是这样。)我知道 Windows 自己的远程桌面会话使用另一个系统,所以那里的情况可能会有所不同。
【解决方案4】:

你不能。

看起来所有显示器电源功能都连接到“电源安全模式”
搜索后,我发现 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功能已连接到“电源安全模式”

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

    • 有什么例子可以使用这个接口吗?
    • 有,但仅适用于 Windows XP,它是 directx sdk 的一部分。
    • @Fraser 你确定吗?我似乎无法在 2010 年 6 月的 SDK 中找到它:i.imgur.com/NPK0jjw.png
    • @kayleeFrye_onDeck - 是的,它是/曾经是 Directx9 SDK 的一部分
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

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

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

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

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

        Here a CCD wrapper for .Net

        【讨论】:

        • 这不适用于通过 DisplayPort 连接到 Windows 10 PC 的单个戴尔显示器。无论显示器电源状态如何,targetAvailable 始终为 1。感谢您分享您的结果。
        猜你喜欢
        • 2010-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多