I am trying to make a GUI show up centered under a mouse.
I need to know the client area of the monitor the mouse is in because if the mouse is too far to the edge, then I have to offset the GUI coordinates.
How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates? Topic is solved
-
- Posts: 59
- Joined: 01 Mar 2022, 17:07
- Contact:
Re: How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates?
Does this work for you?
Code: Select all
clientArea := GetClientAreaOfMonitor()
ToolTip('Top: ' clientArea.top '`nBottom: ' clientArea.bottom '`nLeft: ' clientArea.left '`nRight: ' clientArea.right)
GetClientAreaOfMonitor()
{
monitor := MonitorFromMouse() ; get monitor mouse is on
MonitorGetWorkArea(monitor, &left, &top, &right, &bottom) ; get edge coordinates of client area
return {left: left, top: top, right: right, bottom: bottom} ; return as object
}
MonitorFromMouse()
{
DllCall('GetCursorPos', 'UInt64*', &point_struct:=0) ; get mouse position struct
monFromMouse := DllCall('MonitorFromPoint', 'Int64', point_struct, 'UInt', 2) ; return monitor handle number mouse is on
return ConvertHandleToNumber(monFromMouse) ; convert handle to monitor number and return it
}
ConvertHandleToNumber(handle)
{
monCallback := CallbackCreate(__EnumMonitors, 'Fast', 4) ; fast-mode, 4 parameters
monHandleList := '' ; initialize monitor handle number list
if EnumerateDisplays(monCallback) ; enumerates all monitors
{
loop parse, monHandleList, '`n' ; loop list of monitor handle numbers
if A_LoopField = handle ; if the handle number matches the monitor the mouse is on
return A_Index ; set monFromMouse to monitor number
}
__EnumMonitors(hMonitor, hDevCon, pRect, args) { ; callback function for enumeration DLL
monHandleList .= hMonitor '`n' ; add monitor handle number to list
return true ; continues enumeration
}
}
EnumerateDisplays(callback) => DllCall('EnumDisplayMonitors', 'Ptr', 0, 'Ptr', 0, 'Ptr', callback, 'UInt', 0)
-
- Posts: 59
- Joined: 01 Mar 2022, 17:07
- Contact:
Re: How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates?
Yes. It does. Thank you. I didn't realize it would be so complex.
One follow up question, where can I read up on this object format?
Code: Select all
{left: left, top: top, right: right, bottom: bottom}
Re: How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates?
It's an object literal and you can read more about it here: Object Literal
You can indeed add arrays and nest other objects if you want/need to.
You can indeed add arrays and nest other objects if you want/need to.
Code: Select all
someObject := {
top: 5,
bottom: 72,
name: 'bob',
petAges: [2, 4],
secondObject: { name: 'george',
age: 34 }
}
MsgBox('top: ' someObject.top
'`nbottom: ' someObject.bottom
'`nname: ' someObject.name
'`nage of pet 1: ' someObject.petAges[1]
'`nage of pet 2: ' someObject.petAges[2]
'`nnested object name: ' someObject.secondObject.name
'`nnested object age: ' someObject.secondObject.age
)
Re: How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates?
I don't think it necessarily has to be. When I was trying to determine what monitor a window (not mouse) was on, I wasn't able to find nor create a completely accurate way without the complication. There were some outlier situations that would come up now and again that wouldn't be 100% accurate. For some reason, I adopted the complicated way for getting the mouse position and took the code from my class to supply to you. So it probably can be made much simpler, this was just what I had at hand.
Re: How can I get the client dimensions of the monitor the mouse is in and the mouse's coordinates? Topic is solved
Using built-in functions:
Another option:
Code: Select all
#Requires AutoHotkey v2.0
clientArea := GetClientAreaOfMonitor()
MsgBox('Number: ' clientArea.Num .
'`nLeft: ' clientArea.Left .
'`nTop: ' clientArea.Top .
'`nRight: ' clientArea.Right .
'`nBottom: ' clientArea.Bottom)
GetClientAreaOfMonitor() {
Local MonitorCount := MonitorGetCount()
If MonitorCount = 1
Return {Num: 1, Left: 0, Top: 0, Right: A_ScreenWidth, Bottom: A_ScreenHeight}
Local X, Y, L, T, R, B
Local CMM := A_CoordModeMouse
A_CoordModeMouse := "Screen"
MouseGetPos(&X, &Y)
A_CoordModeMouse := CMM
Loop MonitorCount {
MonitorGet(A_Index, &L, &T, &R, &B)
If (X >= L) && (X <= R) && (Y >= T) && (Y <= B)
Return {Num: A_Index, Left: L, Top: T, Right: R, Bottom: B}
}
Return False
}
Code: Select all
#Requires AutoHotkey v2.0
#Warn
MonitorGetFromMouse(&N, &L, &T, &R, &B)
MsgBox('Number: ' N '`nLeft: ' L '`nTop: ' T '`nRight: ' R '`nBottom: ' B)
MonitorGetFromMouse(&N?, &L?, &T?, &R?, &B?) {
Local CMM := A_CoordModeMouse, X, Y
A_CoordModeMouse := "Screen"
MouseGetPos(&X, &Y)
A_CoordModeMouse := CMM
Loop MonitorGetCount() {
N := A_Index
MonitorGet(A_Index, &L, &T, &R, &B)
If (X >= L) && (X <= R) && (Y >= T) && (Y <= B)
Return True
}
N := L := T := R := B := 0
Return False
}