Bernoulli Lizard
Bernoulli Lizard

Reputation: 579

How to get handle of all active monitors

How can I get the handle of each monitor? I'll need to know which monitor handle corresponds to each physical monitor. I can find this if I also have the positions and numbers of each monitor. But I'm unable to even get the handles of the monitors.

I've read the documentation for EnumDisplayMonitors dozens of times, but nothing that I have tried will work.

I tried doing this:

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){
}

But the values for every argument to EnumMonitorsProc are all null.

I have also tried the following, following the example from this post: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4606 However, the script just aborts as soon as it makes the DllCall("EnumDisplayMonitors",...

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
}

I need the handles for ALL monitors, not just for the active monitor or the primary monitor.

Upvotes: 1

Views: 660

Answers (1)

0x464e
0x464e

Reputation: 6489

First we define the callback function that's going to be provided for the EnumDisplayMonitors function.
Callback_Func := RegisterCallback("MONITORENUMPROC")
This could be done in-line without creating an unnecessary variable as well.

Now that we've done that, we also of course need to create the MONITORENUMPROC function we're referring to:

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

We're only interested in the handle, which is the first param. We can ignore everything else in this small example.
And we're returning true to indicate that we want to keep enumerating through the rest of the display monitors, assuming there are any. This was specified in the documentation for the callback function.

Ok, that's our callback function all done, now we want to call the EnumDisplayMonitors function and pass it that callback function so it can do its trick.
DllCall("EnumDisplayMonitors", Ptr, 0, Ptr, 0, Ptr, Callback_Func, Ptr, 0)

We're passing null (pointer 0 in AHK) to the first two parameters, as the documentation suggests if one wants to enumerate through all the available monitors.

For the 3rd parameter we pass our callback function's pointer, that's stored in our Callback_Func variable. (AHK's RegisterCallback function returns a pointer to our function).

And to the 4th parameter we just pass null again because we don't care about it in this small example. You could pass whatever data you wish through there, and it'd appear in the 4th parameter of our user-defined MONITORENUMPROC function (the one I named "data").
In the library you were looking at, they pass in a pointer to their own "Monitors" object. It's just a clever way they have of making the function have a double use.


So that's basically it. We print a messagebox for each monitor's handle.
Minimal example of how it works. Assuming you probably want to know which handle is which monitor, you can pass forward the handle to yet another function.
Such as the GetMonitorInfo function, exactly as they do in that library you were looking at.

And here's the example script I produced for you:

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

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

Upvotes: 5

Related Questions