I have an AHK script that will be used in different monitor configurations:
- single monitor, no DPI scaling
- single monitor, with DPI scaling
- multiple monitors, none with DPI scalling
- multiple monitors, one with DPI scalling
It appears that for #2 and #4, MouseGetPos returns the actual X and Y without DPI scaling but gui.move does GPI scaling. So then things go off screen cause the X/Y are being multiplied by DPI scaling.
How can I fix this?
Code: Select all
#Requires AutoHotkey v2.0
#Warn Unreachable, off
#SingleInstance Force
allMonitorDetails := getAllMonitorDetails()
myGUI := Gui()
myGUI.SetFont("s12", "Calibri")
myGUI.Title := "ExquisiteW"
myGUI.Opt("+AlwaysOnTop -MinimizeBox") ; WS_EX_NOACTIVATE
myGUI.OnEvent("Close", CloseIt)
myGUI.OnEvent("Escape", CloseIt) ; allow closing with the escape key
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Text", "", "Some text goes here")
myGUI.add("Button", "", "A Button")
return
^!d::
{
global myGUI
; we want mouse position based on screen, so temporarily set the current coordinate mode
Local CMM := A_CoordModeMouse
A_CoordModeMouse := "Screen"
; get the mouse position
MouseGetPos(&mousePositionLeft, &mousePositionTop)
A_CoordModeMouse := CMM
; get the details of the monitor the mouse is on
monitorDetails := getDetailsOfMonitorMouseIsIn(&mousePositionLeft, &mousePositionTop)
myGUI.show()
myGUI.GetPos(&junk, &junk, &myGUIWidth, &myGUIHeight)
myGUILeft := mousePositionLeft - round(myGUIWidth / 2)
myGUITop := mousePositionTop - round(myGUIHeight / 2)
myGUI.Move(myGUILeft, myGUITop)
return
}
CloseIt(*)
{
global myGUI
myGUI.hide()
return
}
; get details about all the connected monitors
getAllMonitorDetails()
{
allMonitorDetails := []
; loop through the number of monitors
Loop MonitorGetCount()
{
; get details about the monitor
monitorIndex := A_Index
monitorName := MonitorGetName(monitorIndex)
MonitorGet(monitorIndex, &screenLeft, &screenTop, &screenRight, &screenBottom)
MonitorGetWorkArea(monitorIndex, &workAreaLeft, &workAreaTop, &workAreaRight, &workAreaBottom)
; save for later
allMonitorDetails.Push({
index: monitorIndex,
name: monitorName,
screen: {
left: screenLeft,
top: screenTop,
right: screenRight,
bottom: screenBottom,
width: screenRight - screenLeft,
height: screenBottom - screenTop
},
workArea: {
left: workAreaLeft,
top: workAreaTop,
right: workAreaRight,
bottom: workAreaBottom,
width: workAreaRight - workAreaLeft,
height: workAreaBottom - workAreaTop
}
})
}
return allMonitorDetails
}
; get the details of the monitor the mouse is under
getDetailsOfMonitorMouseIsIn(&mousePositionLeft, &mousePositionTop)
{
for arrayIndex, monitorDetails in allMonitorDetails
{
if (mousePositionLeft >= monitorDetails.screen.left) && (mousePositionLeft <= monitorDetails.screen.right) && (mousePositionTop >= monitorDetails.screen.top) && (mousePositionTop <= monitorDetails.screen.bottom)
{
return monitorDetails
}
}
return -1
}