Как получить управление всеми активными мониторами - PullRequest
0 голосов
/ 02 марта 2020

Как я могу получить дескриптор каждого монитора? Мне нужно знать, какая ручка монитора соответствует каждому физическому монитору. Я могу найти это, если у меня также есть позиции и номера каждого монитора. Но я даже не могу получить ручку мониторов.

Я читал документацию для EnumDisplayMonitors десятки раз, но все, что я пробовал, не будет работать.

Я пытался сделать 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){
}

Но значения для каждого аргумента EnumMonitorsPro c все равны нулю.

Я также попробовал следующее, следуя примеру из этого поста: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4606 Однако скрипт просто прерывается, как только он выполняет 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
}

Мне нужны маркеры для ВСЕХ мониторов, а не только для активный монитор или основной монитор.

1 Ответ

2 голосов
/ 04 марта 2020

Сначала мы определим функцию обратного вызова , которая будет предоставлена ​​для функции 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)

Мы передаем нулевой ( указатель 0 в AHK ) первым двум параметрам, как следует из документации, если кто-то хочет перечислить все доступные мониторы.

Для третьего параметра мы передаем указатель нашей функции обратного вызова, который хранится в нашей переменной Callback_Func. (Функция RegisterCallback AHK возвращает указатель на нашу функцию).

И к 4-му параметру мы просто передаем ноль снова, потому что нас это не волнует в этом небольшом примере. Вы можете передать любые данные, через которые вы будете проходить sh, и они появятся в 4-м параметре нашей пользовательской функции MONITORENUMPROC (которую я назвал "data").
В библиотеке, которую вы просматривали, они передают указатель на собственный объект «Мониторы». Это просто умный способ сделать так, чтобы функция имела двойное применение.


Так что это в основном так. Мы печатаем окно сообщения для дескриптора каждого монитора.
Минимальный пример того, как он работает. Предполагая, что вы, вероятно, хотите знать, какой дескриптор является каким монитором, вы можете передать дескриптор еще одной функции.
Например, функции GetMonitorInfo, точно так же, как в той библиотеке, которую вы искали. at.

А вот пример сценария, который я подготовил для вас:

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

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