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

ulydmbyx  于 2023-05-01  发布在  Windows
关注(0)|答案(9)|浏览(231)

有谁知道在Windows(XP/Vista/2000/2003)中是否有一个API可以获取当前的监视器状态(开或关)?
我所有的搜索似乎都表明没有真实的的方法可以做到这一点。
This thread尝试使用GetDevicePowerState,根据微软的文档,GetDevicePowerState不适用于显示设备。
在Vista中,我可以收听X1 E2 F1 X,但当手动关闭显示器时,我似乎没有得到事件。
在XP中,我可以挂接到WM_SYSCOMMANDSC_MONITORPOWER,查找状态2。这仅适用于系统触发电源关闭的情况。
WMI Win32_DesktopMonitor类似乎也没有帮助。

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

还有人有其他想法吗

wpcxdonn

wpcxdonn1#

GetDevicePowerState * 有时 * 适用于显示器。如果存在,则可以打开\\.\LCD设备。用完后立即关上。
从本质上讲,你是不走运的-没有可靠的方法来检测显示器的电源状态,写一个设备驱动程序和过滤所有的电源IRP向上和向下的显示驱动程序链短。这也不是很可靠。

o3imoua4

o3imoua42#

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

bxjv4tth

bxjv4tth3#

在基于监视器状态执行任何操作之前,请记住,用户可以使用具有其他系统的远程桌面的机器,这些系统不需要连接到机器的监视器-因此不要基于监视器状态关闭任何可视化。

e4eetjau

e4eetjau4#

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

q0qdq0h2

q0qdq0h25#

在Windows XP或更高版本中,您可以使用IMSVidDevice接口。
参见http://msdn.microsoft.com/en-us/library/dd376775(VS.85).aspx
(not如果这在Sever 2003中起作用,请确定)

xzabzqsa

xzabzqsa6#

使用 Delphi 代码,您可以在待机过程中检测无效的监视器geomerty:

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
ia2d9nvy

ia2d9nvy7#

这是一个非常古老的帖子,但如果它可以帮助某人,我已经找到了一个解决方案来检测屏幕是否可用:Windows的连接和配置显示器(CCD)API。
它是User32.ddl的一部分,有趣的函数是GetDisplayConfigBufferSizesQueryDisplayConfig。它给予我们所有的信息,可以在窗口的配置面板中查看。
特别地,PathInfo包含具有targetAvailable标志的TargetInfo属性。这个标志似乎在我到目前为止尝试的所有配置上都正确更新了。
这使您可以知道连接到PC的每个屏幕的状态并设置其配置。
Here a CCD wrapper for .Net

knsnq2tg

knsnq2tg8#

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

9fkzdhlc

9fkzdhlc9#

我在窗体中添加了一个vcl计时器来检查监视器状态。
它只是为我的一个监视器系统工作。希望这对某人有帮助。

function GetDevicePowerState(hDevice: DWORD; var pfOn: BOOL): BOOL; stdcall;
external kernel32;

function CheckMonitorState: boolean;
var
Hwnd: THandle;
Stat: LongBool;
begin
Hwnd := CreateFile('\\.\LCD', 0, 0, nil, OPEN_EXISTING, 0, 0);
if Hwnd <> INVALID_HANDLE_VALUE then
  GetDevicePowerState(Hwnd, Stat);
Result := Stat;
CloseHandle(Hwnd);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if CheckMonitorState then
  Memo1.Lines.Append('Monitor ON')
  else
    Memo1.Lines.Append('Monitor OFF');
end;

相关问题