bug.n/src/MonitorManager.ahk

80 lines
2.9 KiB
AutoHotkey

/*
:title: bug.n/monitormanager
:copyright: (c) 2019 by joten <https://github.com/joten>
:license: GNU General Public License version 3
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
*/
class MonitorManager {
__New() {
;; enum _PROCESS_DPI_AWARENESS
PROCESS_DPI_UNAWARE := 0
PROCESS_SYSTEM_DPI_AWARE := 1
PROCESS_PER_MONITOR_DPI_AWARE := 2
; DllCall("SHcore\SetProcessDpiAwareness", "UInt", PROCESS_PER_MONITOR_DPI_AWARE)
;; InnI: Get per-monitor DPI scaling factor (https://www.autoitscript.com/forum/topic/189341-get-per-monitor-dpi-scaling-factor/?tab=comments#comment-1359832)
DPI_AWARENESS_CONTEXT_UNAWARE := -1
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE := -2
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE := -3
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 := -4
DllCall("User32\SetProcessDpiAwarenessContext", "UInt" , DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
;; pneumatic: -DPIScale not working properly (https://www.autohotkey.com/boards/viewtopic.php?p=241869&sid=abb2db983d2b3966bc040c3614c0971e#p241869)
ptr := A_PtrSize ? "Ptr" : "UInt"
this.monitors := []
DllCall("EnumDisplayMonitors", ptr, 0, ptr, 0, ptr, RegisterCallback("MonitorEnumProc", "", 4, &this), "UInt", 0)
;; Solar: SysGet incorrectly identifies monitors (https://autohotkey.com/board/topic/66536-sysget-incorrectly-identifies-monitors/)
}
}
MonitorEnumProc(hMonitor, hdcMonitor, lprcMonitor, dwData) {
l := NumGet(lprcMonitor + 0, 0, "UInt")
t := NumGet(lprcMonitor + 0, 4, "UInt")
r := NumGet(lprcMonitor + 0, 8, "UInt")
b := NumGet(lprcMonitor + 0, 12, "UInt")
this := Object(A_EventInfo)
;; Helgef: Allow RegisterCallback with BoundFunc objects (https://www.autohotkey.com/boards/viewtopic.php?p=235243#p235243)
this.monitors.push(New Monitor(hMonitor, l, t, r, b))
Return, 1
}
class Monitor {
__New(handle, left, top, right, bottom) {
this.handle := handle
this.left := left
this.top := top
this.right := right
this.bottom := bottom
this.x := left
this.y := top
this.width := right - left
this.height := bottom - top
dpi := this.getDpiForMonitor()
this.dpiX := dpi.x
this.dpiY := dpi.y
this.scaleX := this.dpiX / 96
this.scaleY := this.dpiY / 96
}
getDpiForMonitor() {
;; enum _MONITOR_DPI_TYPE
MDT_EFFECTIVE_DPI := 0
MDT_ANGULAR_DPI := 1
MDT_RAW_DPI := 2
MDT_DEFAULT := MDT_EFFECTIVE_DPI
ptr := A_PtrSize ? "Ptr" : "UInt"
dpiX := dpiY := 0
DllCall("SHcore\GetDpiForMonitor", ptr, this.handle, "Int", MDT_DEFAULT, "UInt*", dpiX, "UInt*", dpiY)
Return, {x: dpiX, y: dpiY}
}
;; InnI: Get per-monitor DPI scaling factor (https://www.autoitscript.com/forum/topic/189341-get-per-monitor-dpi-scaling-factor/?tab=comments#comment-1359832)
}