是否有任何方法可以检测Windows中的监视器状态(打开或关闭)?

是否有任何方法可以检测Windows中的监视器状态(打开或关闭)?,windows,winapi,Windows,Winapi,是否有人知道在Windows(XP/Vista/2000/2003)中是否存在获取当前监视器状态(打开或关闭)的API 我所有的搜索似乎都表明没有真正的方法可以做到这一点 根据微软的文档,尝试使用不适用于显示设备的 在Vista中,我可以收听,但在手动关闭显示器时,我似乎无法获取事件 在XP中,我可以挂接到WM\u SYSCOMMANDSC\u MONITORPOWER,查找状态2。这仅适用于系统触发断电的情况 WMIWin32\u DesktopMonitor类似乎也没有帮助 编辑:在comp

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

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

根据微软的文档,尝试使用不适用于显示设备的

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

在XP中,我可以挂接到
WM\u SYSCOMMAND
SC\u MONITORPOWER
,查找状态2。这仅适用于系统触发断电的情况

WMI
Win32\u DesktopMonitor
类似乎也没有帮助

编辑:在comp.os.ms-windows.programmer.win32上显示,没有可靠的方法来执行此操作

还有人有其他想法吗

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


从本质上说,你运气不好,没有可靠的方法来检测显示器电源状态,除了编写设备驱动程序和过滤显示器驱动程序链上下的所有电源IRP。这也不是很可靠。

在根据监视器状态执行任何操作之前,请记住,用户可以使用带有其他系统远程桌面的计算机,而不需要将监视器连接到该计算机-因此,不要根据监视器状态关闭任何可视化功能。

您不能。

看起来所有监视器电源功能都连接到了“电源安全模式”
搜索后,我发现代码连接了SC\U MONITORPOWER消息和系统值(帖子编号2)
当我手动关闭显示器时,我使用代码来测试系统值是否发生变化

int main()
{
    for(;monitorOff()!=1;)
        Sleep(500);
    return 0;
}//main
无论我关闭显示器多长时间,代码都不会停止。
监视器关闭功能的代码如下:

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
int-monitorOff()
{
常量GUID监视器类GUID=
{0x4d36e96e,0xe325,0x11ce,
{0xbf,0xc1,0x08,0x00,0x2b,0xe1,0x03,0x18};
列出监测者名单;
ListDeviceClassData(&MonitorClassGuid,监视器);
list::iterator it=monitors.begin(),
it_end=monitors.end();
for(;it!=it_end;++it)
{
const char*off_msg=“”;
//it->PowerData.PD\u PowerStateMapping
如果(it->PowerData.PD_MostRecentPowerState!=PowerDeviceD0)
{
返回1;
}
}//为了
返回0;
}//监视器

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

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

在Windows XP或更高版本中,您可以使用IMSVidDevice界面


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

如果您的显示器具有某种内置USB集线器,您可以尝试使用它来检测显示器是否关闭/打开。

当然,当监视器考虑“关闭”时,USB集线器不会保持连接。

用Delphi代码,可以在待机状态下检测无效监视器GeMyTy:

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

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

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

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

这使您能够了解连接到电脑的每个屏幕的状态并设置其配置


相关问题:您想用这些信息实现什么目的?也许我们可以帮助解决真正的问题。注意:要粗略估计物理连接到计算机的监视器所消耗的电量,windows API允许您确定监视器是否“真实”。请参阅:显示\设备\镜像\驱动程序。远程桌面应用程序仍然会影响屏幕保护程序,不是吗?(至少RealVNC是这样。)我知道windows自己的远程桌面会话使用另一个系统,所以这里的情况可能有所不同。我认为这是最接近这个问题的答案。硬件制造商在DVI标准中没有给我们提供那么高级别的通信,这是一个真正的失败。不过,说真的,在完成后立即关闭它。有一次,我在迈克尔·戴尔的笔记本电脑上打破了演示模式,但没能做到这一点:)但你可能会把反射误认为是屏幕动作。。我认为您正在将设备驱动程序问题转化为图像处理问题。。我喜欢:)这项技术已被用于监控远程位置装满设备的机架。将摄像机对准机架,观察指示灯是否有“异常”变化。它的蛮力,但在某些情况下,它是唯一合理的答案。有没有关于如何使用此接口的示例?有,但它仅限于Windows XP,它是directx sdk的一部分。@Fraser你确定吗?我似乎在2010年6月的SDK中找不到它:@kayleeFrye_onDeck-是的,它是/曾经是Directx9 SDK的一部分。对于我来说,通过DisplayPort连接到Windows 10 PC的单个Dell监视器不起作用。targetAvailable始终为1