首页 > 解决方案 > 如何处理所有活动监视器

问题描述

如何获取每台显示器的句柄?我需要知道哪个监视器句柄对应于每个物理监视器。如果我也有每台显示器的位置和编号,我可以找到它。但我什至无法拿到显示器的把手。

我已阅读 EnumDisplayMonitors 的文档数十次,但我尝试过的任何方法都不起作用。

我试过这样做:

oEnumDisplayMonitors := RegisterCallback("EnumMonitorsProc")
DllCall("EnumDisplayMonitors", "Ptr", 0, "Ptr", 0, "Ptr", oEnumDisplayMonitors, "Ptr", 0)
omh := oEnumDisplayMonitors.monitorHandle
h := oEnumDisplayMonitors.hdc
olpr := oEnumDisplayMonitors.lpRect

EnumMonitorsProc(monitorHandle, hdc, lpRect, lParam){
}

但是 EnumMonitorsProc 的每个参数的值都是空的。

按照这篇文章中的示例,我还尝试了以下操作:https : //www.autohotkey.com/boards/viewtopic.php?f=6&t=4606 但是,脚本一发出 DllCall("枚举显示监视器",...

Monitors := MDMF_Enum("")
    For HMON, M In Monitors {
        l := M.Left
        t := M.Top
        h := HMON
    }

MDMF_Enum(HMON := "") {
   Static EnumProc := RegisterCallback("MDMF_EnumProc")
   Static Monitors := {}
   If (HMON = "") ; new enumeration
      Monitors := {}
   If (Monitors.MaxIndex() = "") ; enumerate
    DllCall("EnumDisplayMonitors", "Ptr", 0, "Ptr", 0, "Ptr", EnumProc, "Ptr", &Monitors, "UInt")
   Return (HMON = "") ? Monitors : Monitors.HasKey(HMON) ? Monitors[HMON] : False
}

我需要所有监视器的句柄,而不仅仅是活动监视器或监视器。

标签: autohotkey

解决方案


首先,我们定义将为EnumDisplayMonitors函数提供的回调函数。
Callback_Func := RegisterCallback("MONITORENUMPROC")
这也可以在不创建不必要的变量的情况下在线完成。

现在我们已经完成了,我们当然还需要创建MONITORENUMPROC我们所指的函数:

MONITORENUMPROC(hMonitor, hDC, pRECT, data)
{
   MsgBox, % hMonitor
   return true
}

我们只对句柄感兴趣,它是第一个参数。在这个小例子中,我们可以忽略其他所有内容。
我们返回 true 表示我们想要继续枚举其余的显示监视器,假设有的话。这是在回调函数的文档中指定的。

好的,我们的回调函数全部完成,现在我们要调用 EnumDisplayMonitors 函数并将该回调函数传递给它,这样它就可以完成任务了。
DllCall("EnumDisplayMonitors", Ptr, 0, Ptr, 0, Ptr, Callback_Func, Ptr, 0)

我们将 null (AHK 中的指针 0)传递给前两个参数,正如文档建议的那样,如果一个人想要枚举所有可用的监视器。

对于第三个参数,我们传递回调函数的指针,该指针存储在我们的Callback_Func变量中。(AHK 的 RegisterCallback 函数返回一个指向我们函数的指针)。

对于第 4 个参数,我们只是再次传递 null,因为在这个小示例中我们不关心它。你可以通过那里传递任何你想要的数据,它会出现在我们用户定义MONITORENUMPROC函数的第四个参数中(我命名为“数据”的那个)。
在您正在查看的库中,它们传递了一个指向它们自己的“监视器”对象的指针。这只是他们使该功能具有双重用途的一种聪明方法。


所以基本上就是这样。我们为每个监视器的句柄打印一个消息框。
它如何工作的最小示例。假设您可能想知道哪个句柄是哪个监视器,您可以将句柄传递给另一个函数。
例如GetMonitorInfo函数,就像他们在您正在查看的那个库中所做的那样。

这是我为您制作的示例脚本:

Callback_Func := RegisterCallback("MONITORENUMPROC")
DllCall("EnumDisplayMonitors", Ptr, 0, Ptr, 0, Ptr, Callback_Func, Ptr, 0)

MONITORENUMPROC(hMonitor, hDC, pRECT, data)
{
   MsgBox, % hMonitor
   return true
}

推荐阅读