Skip to content

Instantly share code, notes, and snippets.

@jonatino
Created April 20, 2020 02:07
Show Gist options
  • Save jonatino/f7eda30f94c67d74be4d72590b203a34 to your computer and use it in GitHub Desktop.
Save jonatino/f7eda30f94c67d74be4d72590b203a34 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"syscall"
"unsafe"
)
var (
user32, _ = syscall.LoadLibrary("User32.dll")
dxva2, _ = syscall.LoadLibrary("dxva2.dll")
procEnumDisplayMonitors, _ = syscall.GetProcAddress(user32, "EnumDisplayMonitors")
getPhysicalMonitorsFromHMONITOR, _ = syscall.GetProcAddress(dxva2, "GetPhysicalMonitorsFromHMONITOR")
)
type RECT struct {
Left int32
Top int32
Right int32
Bottom int32
}
type DisplayMonitorInfo struct {
Handle syscall.Handle
DeviceContext syscall.Handle
Rectangle RECT
}
type MONITORENUMPROC func(hmonitor syscall.Handle, hdc syscall.Handle, rect *RECT, lparam uintptr) int32
func EnumDisplayMonitors(hdc syscall.Handle, clip *RECT, fnEnum MONITORENUMPROC, data uintptr) bool {
fnEnumRaw := func(hmonitor uintptr, hdc uintptr, rect uintptr, lparam uintptr) uintptr {
return uintptr(fnEnum(
syscall.Handle(hmonitor),
syscall.Handle(hdc),
(*RECT)(unsafe.Pointer(rect)),
lparam))
}
r1, _, _ := syscall.Syscall6(
procEnumDisplayMonitors,
4,
uintptr(hdc),
uintptr(unsafe.Pointer(clip)),
syscall.NewCallback(fnEnumRaw),
uintptr(data),
0,
0)
return r1 != 0
}
func GetAllDisplayMonitors() []DisplayMonitorInfo {
var result []DisplayMonitorInfo
EnumDisplayMonitors(
syscall.Handle(0),
nil,
func(hmonitor syscall.Handle, hdc syscall.Handle, rect *RECT, lparam uintptr) int32 {
result = append(result, DisplayMonitorInfo{Handle: hmonitor, DeviceContext: hdc, Rectangle: *rect})
return 1
},
uintptr(0),
)
return result
}
type PhysicalMonitor struct {
hPhysicalMonitor syscall.Handle
szPhysicalMonitorDescription string
}
func GetPhysicalMonitorsFromHMONITOR(handle syscall.Handle, monitorArraySize uint, array *[]PhysicalMonitor) (result uintptr) {
ret, _, callErr := syscall.Syscall(
getPhysicalMonitorsFromHMONITOR,
3,
uintptr(handle),
uintptr(monitorArraySize), uintptr(unsafe.Pointer(array)))
if callErr != 0 {
fmt.Println(callErr)
syscall.ExitProcess(13)
}
result = ret
return
}
func main() {
defer syscall.FreeLibrary(user32)
defer syscall.FreeLibrary(dxva2)
monitors := GetAllDisplayMonitors()
for _, monitor := range monitors {
fmt.Println(monitor)
array := make([]PhysicalMonitor, 1)
GetPhysicalMonitorsFromHMONITOR(monitor.Handle, 1, &array)
fmt.Println(len(array))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment