Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

How to determine a window is in which monitor?


  • Please log in to reply
4 replies to this topic
shinywong
  • Members
  • 6 posts
  • Last active: Apr 05 2012 10:48 AM
  • Joined: 16 Mar 2008
For dual/multi monitors, how to determine a windows is in currently in which monitor?

There is a solution here:

http://www.autohotke...topic21703.html

; Get the index of the monitor containing the specified x and y co-ordinates. 
GetMonitorAt(x, y, default=1) 
{ 
    SysGet, m, MonitorCount 
    ; Iterate through all monitors. 
    Loop, %m% 
    {   ; Check if the window is on this monitor. 
        SysGet, Mon, Monitor, %A_Index% 
        if (x >= MonLeft && x <= MonRight && y >= MonTop && y <= MonBottom) 
            return A_Index 
    } 

    return default 
}

But I think it's not perfect, it only checks a point. It can't be used to check a window is in which monitor. From my understanding, because a window can span two or even more monitors, the question is actually to find out most part of a window is in which monitor. If most part of a window is in monitor 0, then the window in monitor 0; etc.

I think it is very complicated to calculate most part of a window is in which monitor even for dual monitors. Because dual monitors can be following arrangement:

Posted Image

Not to mention multi (2+) monitors.

I want to know if there is some AHK function to check a window is in which monitor? Or can I call some Windows API to achieve this?

Thank you very much.

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Google "MonitorFromWindow Function" :)

shinywong
  • Members
  • 6 posts
  • Last active: Apr 05 2012 10:48 AM
  • Joined: 16 Mar 2008
Thank you, nimda.

This is my code of get the monitor index of a given window:

The DllCall part is from http://www.autohotke...pic.php?t=49115

GetMonitorIndexFromWindow(windowHandle)
{
	; Starts with 1.
	monitorIndex := 1

	VarSetCapacity(monitorInfo, 40)
	NumPut(40, monitorInfo)
	
	if (monitorHandle := DllCall("MonitorFromWindow", "uint", windowHandle, "uint", 0x2)) 
		&& DllCall("GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo) 
	{
		monitorLeft   := NumGet(monitorInfo,  4, "Int")
		monitorTop    := NumGet(monitorInfo,  8, "Int")
		monitorRight  := NumGet(monitorInfo, 12, "Int")
		monitorBottom := NumGet(monitorInfo, 16, "Int")
		workLeft      := NumGet(monitorInfo, 20, "Int")
		workTop       := NumGet(monitorInfo, 24, "Int")
		workRight     := NumGet(monitorInfo, 28, "Int")
		workBottom    := NumGet(monitorInfo, 32, "Int")
		isPrimary     := NumGet(monitorInfo, 36, "Int") & 1

		SysGet, monitorCount, MonitorCount

		Loop, %monitorCount%
		{
			SysGet, tempMon, Monitor, %A_Index%

			; Compare location to determine the monitor index.
			if ((monitorLeft = tempMonLeft) and (monitorTop = tempMonTop)
				and (monitorRight = tempMonRight) and (monitorBottom = tempMonBottom))
			{
				monitorIndex := A_Index
				break
			}
		}
	}
	
	return %monitorIndex%
}


nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
nitpick: remove those %% on the return line - will break in v2 otherwise.

shinywong
  • Members
  • 6 posts
  • Last active: Apr 05 2012 10:48 AM
  • Joined: 16 Mar 2008
Thanks for the suggestion.

I'm always confused by whether or not to enclose variables in %%.