check if rectangles (windows) overlap

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

check if rectangles (windows) overlap

20 Apr 2017, 11:43

I didn't find anything on the forums that does this, please provide any links to the contrary.

It all seems to be working fine, and is quite fun to experiment with. I mainly had in mind to check if a window appears on a certain monitor.

Do notify of any errors, this is the sort of script where an error can easily be made.

Btw try to work out how you might write such a script, before you look at the code, the logic is quite interesting. Maybe even take a few hours or a few days.

Code: Select all

q:: ;check if windows overlap
vOpt := ""
;vOpt .= "r" ;XYRB coordinates 'RECT style'
;vOpt .= "c" ;win 1 contains win 2
;vOpt .= "e" ;win 1 = win 2
;vOpt .= "w" ;win 1 is within win 2 (win 2 contains win 1)
WinGetPos, vPosX1, vPosY1, vPosW1, vPosH1, ahk_class Notepad
WinGetPos, vPosX2, vPosY2, vPosW2, vPosH2, ahk_class WordPadClass
MsgBox, % JEE_RectOverlapsRect(vPosX1, vPosY1, vPosW1, vPosH1, vPosX2, vPosY2, vPosW2, vPosH2, vOpt)
return

;==================================================

JEE_RectOverlapsRect(vX1, vY1, vW1, vH1, vX2, vY2, vW2, vH2, vOpt="")
{
	;if (A is left of B) [rightmost A is left of leftmost B]
	;|| (A is right of B) [leftmost A is right of righttmost B]
	;|| (A is is above B) [bottom of A is is above top of B]
	;|| (A is is below B) [top of A is is below bottom of B]
	;then A and B do not overlap

	if InStr(vOpt, "x") ;reduce width and height values by 1
		vW1 -= 1, vH1 -= 1, vW2 -= 1, vH2 -= 1

	if InStr(vOpt, "e") ;(A = B) A equals B
		if !(vX1 = vX2) || !(vY1 = vY2) || !(vW1 = vW2) || !(vH1 = vH2)
			return 0
		else
			return 1

	if InStr(vOpt, "r") ;coordinates are XYRB 'RECT style'
		vR1 := vW1, vB1 := vH1, vR2 := vW2, vB2 := vH2
	else
		vR1 := vX1+vW1, vB1 := vY1+vH1, vR2 := vX2+vW2, vB2 := vY2+vH2

	if InStr(vOpt, "c") ;(A contains B) A contains all of or is equal to B
		if (vX2 < vX1) || (vY2 < vY1) || (vR2 > vR1) || (vH2 > vH1)
			return 0
		else
			return 1

	if InStr(vOpt, "w") ;(A within B) A is within or is equal to B
		if (vX1 < vX2) || (vY1 < vY2) || (vR1 > vR2) || (vH1 > vH2)
			return 0
		else
			return 1

	;(A overlaps B)
	if (vR1 < vX2) || (vX1 > vR2) || (vB1 < vY2) || (vY1 > vB2)
		return 0
	else
		return 1
}
[Interesting link:]
c++ - Determine if two rectangles overlap each other? - Stack Overflow
http://stackoverflow.com/questions/3063 ... each-other

[EDIT:][regarding monitors there are in fact functions such as MonitorFromWindow]
Close all windows/programs except what is on Monitor 2? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 60#p143960
Last edited by jeeswg on 04 Aug 2017, 07:02, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: check if rectangles (windows) overlap

20 Apr 2017, 15:49

Btw try to work out how you might write such a script, before you look at the code, the logic is quite interesting. Maybe even take a few hours or a few days.
Sorry, but I have to say that the logic is absolutely simple.

Also, you might be interested in the good old GDI Rectangle Functions.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if rectangles (windows) overlap

20 Apr 2017, 16:26

Cheers for the Rectangle functions.

Btw the logic is simple *when you know it* (once you've already seen the answer), but if you try to work it out from first principles, without knowing the answer in advance, it may be more difficult!
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if rectangles (windows) overlap

20 Apr 2017, 21:29

@guest3456, cheers for the link. Hmm, I searched for 'AutoHotkey windows overlap', didn't find that one unfortunately. Interesting function, it lists the hWnds for overlapping windows:

GetOverlappingWindows() - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/8047 ... ngwindows/

I just found this about the percentage overlapped:

Find % one window overlaps another - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=15391
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9453
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: check if rectangles (windows) overlap

23 Apr 2017, 03:45

FYI:
By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose coordinates are ( right, bottom ) lies immediately outside of the rectangle.

Source: RECT structure
In other words, the rectangles
  • RECT (left, top, right, bottom)
    (0, 0, 50, 50) - (50, 0, 100, 50)
  • AHK (X, Y, W, H)
    (0, 0, 50, 50) - (50, 0, 50, 50)
do not overlap.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if rectangles (windows) overlap

23 Apr 2017, 08:23

Cheers, just me, I had wanted to investigate this issue of 1-pixel overlap, and if there was a convention for how other functions treated it. It will take some thought over how to rewrite any functions, and I may like to add in an optional parameter in relation to this.

[EDIT:] In other words, I need to make a decision on how to handle border pixels, possibly offering multiple modes, perhaps one mode that includes the border, one mode that excludes the border, a 'standard' mode if it's different, and a further alternative mode if I think it's need.

[EDIT:] To make the my function ignore the rightmost/bottommost pixels, you could either subtract 1 from the width and height values, or include 'x' in the vOpt parameter (I've added 2 lines to the function).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if rectangles (windows) overlap

04 Aug 2017, 07:04

Useful links:

RECT structure (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
By convention, the right and bottom edges of the rectangle are normally considered exclusive. In other words, the pixel whose coordinates are ( right, bottom ) lies immediately outside of the rectangle. For example, when RECT is passed to the FillRect function, the rectangle is filled up to, but not including, the right column and bottom row of pixels. This structure is identical to the RECTL structure.
Rectangle Functions (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

IntersectRect function (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

[GetNextOverlappedWindow function by guest3456]
Switching to the window in behind - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=19921

==================================================

Code: Select all

q:: ;check if 2 windows overlap using IntersectRect
WinGet, hWnd1, ID, ahk_class Notepad
WinGet, hWnd2, ID, ahk_class WordPadClass
VarSetCapacity(RECT1, 16, 0)
VarSetCapacity(RECT2, 16, 0)
VarSetCapacity(RECT3, 16, 0)
DllCall("user32\GetWindowRect", Ptr,hWnd1, Ptr,&RECT1)
DllCall("user32\GetWindowRect", Ptr,hWnd2, Ptr,&RECT2)
vRet := DllCall("user32\IntersectRect", Ptr,&RECT3, Ptr,&RECT1, Ptr,&RECT2)
MsgBox, % "overlap: " (vRet ? "Y" : "N")
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 167 guests