﻿#cs ----------------------------------------------------------------------------
Author : Melba23
https://www.autoitscript.com/forum/topic/165325-how-to-get-4-screen-coordinates-just-by-dragging-a-rectangle/#elControls_1206830_menu
Modified by...: Musashi, Bitnugger
#ce ----------------------------------------------------------------------------

#include <AutoItConstants.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <Misc.au3>
;~ #include <ScreenCapture.au3>
#include <WinAPISys.au3>
#include <WinAPISysWin.au3>

Global $g_hUserDLL = DllOpen("user32.dll")

HotKeySet("{ESC}", "_Terminate")

Global $g_hMain_GUI, $idRect_Button, $idCancel_Button
Global $g_tPOINT = DllStructCreate($tagPOINT)

Global $g_hRectangle_GUI, $g_iX1, $g_iY1, $g_iX2, $g_iY2

_Main()

Func _Main()
	Local $aMouse_Pos = MouseGetPos(), $aPos
;~ 	DllStructSetData($g_tPOINT, 'X', $aMouse_Pos[0])
;~ 	DllStructSetData($g_tPOINT, 'Y', $aMouse_Pos[1])
	$g_tPOINT.X = $aMouse_Pos[0]
	$g_tPOINT.Y = $aMouse_Pos[1]
	Local $hParent = _WinAPI_GetAncestor(_WinAPI_WindowFromPoint($g_tPOINT), $GA_ROOT)
	$aPos = WinGetPos($hParent)

	; Create GUI
	$g_hMain_GUI = GUICreate("Select Rectangle", 240, 50, ($aPos[2] / 2) - 120, ($aPos[3] / 2) - 25)

	$idRect_Button = GUICtrlCreateButton("Mark Area", 10, 10, 80, 30)
	$idCancel_Button = GUICtrlCreateButton("Cancel", 150, 10, 80, 30)

	GUISetState()

	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE, $idCancel_Button
;~ 				FileDelete(@ScriptDir & "Rect.bmp")
				Exit
			Case $idRect_Button
				GUISetState(@SW_HIDE, $g_hMain_GUI)
				_Mark_Rect()
				; Capture selected area (#include <ScreenCapture.au3>)
				MsgBox($MB_SYSTEMMODAL, "Coords", "Left: " & $g_iX1 & @CRLF & "Top: " & $g_iY1 & @CRLF & "Right: " & $g_iX2 & @CRLF & "Bottom: " & $g_iY2, 5)
				GUISetState(@SW_SHOW, $g_hMain_GUI)
;~ 				WinActivate($g_hMain_GUI) ; Hm, bin sprachlos... funktioniert bei mir nicht - das Fenster kommt nicht nach vorne!
				_WinAPI_SetWindowPos($g_hMain_GUI, $HWND_TOP, 0, 0, 0, 0, BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_SHOWWINDOW)) ; Das aber...
		EndSwitch
	WEnd
EndFunc   ;==>_Main

Func _Mark_Rect()
	Local $aMouse_Pos[2], $aOldMouse_Pos[2], $aPos[4], $hMaster_Rgn, $hRgn, $iRgnType, $iTemp

	#Region Create GUIs for Cross cursor and Rectangle
	; Create transparent GUI with Cross cursor
	Local $w = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), $h = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)  ;  3840, 1080 [Monitor 1|Monitor 2]
	Local $x = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN), $y = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)    ; -1920, 0    [Monitor 1|Monitor 2]
	ConsoleWrite(StringFormat('> $w = %5i, $h = %5i, $x = %5i, $y = %5i\n', $w, $h, $x, $y))
;~ 	$hCross_GUI = GUICreate("Test", @DesktopWidth, @DesktopHeight - 20, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
	$hCross_GUI = GUICreate("Test", $w, $h, $x, $y, $WS_POPUP, $WS_EX_TOPMOST) ; $w =  3840, $h =  1060, $x = -1920, $y =     0

	$aPos = WinGetPos($hCross_GUI)
	ConsoleWrite('> GUI_Pos for Cross cursor and Rectangle: $aPos = ' & _ArrayToString($aPos, ', ') & @CRLF & @CRLF)

;~ 	WinSetTrans($hCross_GUI, "", 8)
	WinSetTrans($hCross_GUI, "", 120)
	GUISetState(@SW_SHOW, $hCross_GUI)
	GUISetCursor($IDC_CROSS, $GUI_CURSOR_OVERRIDE, $hCross_GUI)

;~ 	$g_hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
	$g_hRectangle_GUI = GUICreate("", $w, $h, $x, $y, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
;~ 	GUISetBkColor(0x000000) ; schwarzes Rectangle
	GUISetBkColor(0xFF0000) ; rotes Rectangle
	#EndRegion Create GUIs for Cross cursor and Rectangle

	#Region Wait until mouse button pressed
	While Not _IsPressed("01", $g_hUserDLL)
		Sleep(10)
	WEnd

	Local $iOldMouseCoordMode = Opt('MouseCoordMode', 0) ; get relative coords to the active window!!!

	; Get first mouse position
	$aMouse_Pos = MouseGetPos()
	$g_iX1 = $aMouse_Pos[0]
	$g_iY1 = $aMouse_Pos[1]
	ConsoleWrite('> $aMouse_Pos #1 = ' & _ArrayToString($aMouse_Pos, ', ') & @CRLF)

	Local Static $aRgnType = ['$ERRORREGION', '$NULLREGION', '$SIMPLEREGION', '$COMPLEXREGION']

	$aPos = WinGetPos($g_hRectangle_GUI)
	ConsoleWrite('> $g_hRectangle_GUI: $aPos = ' & _ArrayToString($aPos, ', ') & @CRLF & @CRLF)
	Local $left, $top, $right, $bottom
	$left = $g_iX1 + $aPos[0]
	$top = $g_iY1 + $aPos[0]
	#EndRegion Wait until mouse button pressed

	#Region Draw rectangle while mouse button pressed
	While _IsPressed("01", $g_hUserDLL)
		While 1
			$aMouse_Pos = MouseGetPos()
			If ($aMouse_Pos[0] & $aMouse_Pos[1]) <> ($aOldMouse_Pos[0] & $aOldMouse_Pos[1]) Then
				$aOldMouse_Pos = $aMouse_Pos
				ExitLoop
			EndIf
			If Not _IsPressed("01", $g_hUserDLL) Then ExitLoop
			Sleep(10)
		WEnd

		ToolTip('$aMouse_Pos = ' & $aMouse_Pos[0] & ', ' & $aMouse_Pos[1] & @LF & '$g_iX1 = ' & $g_iX1 & ' $g_iY1 = ' & $g_iY1)

		$hMaster_Rgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)

		$hRgn = _WinAPI_CreateRectRgn($g_iX1, $g_iY1, $g_iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
		If Not $hRgn Then Exit 2
		$iRgnType = _WinAPI_CombineRgn($hMaster_Rgn, $hRgn, $hMaster_Rgn, $RGN_OR)
		ConsoleWrite(">   var: $iRgnType --> " & $aRgnType[$iRgnType] & @LF)
		_WinAPI_DeleteObject($hRgn)

		$hRgn = _WinAPI_CreateRectRgn($g_iX1 + 1, $g_iY1 + 1, $aMouse_Pos[0], $g_iY1) ; Top of rectangle
		If Not $hRgn Then Exit 3
		$iRgnType = _WinAPI_CombineRgn($hMaster_Rgn, $hRgn, $hMaster_Rgn, $RGN_OR)
		ConsoleWrite("+   var: $iRgnType --> " & $aRgnType[$iRgnType] & @LF)
		_WinAPI_DeleteObject($hRgn)

		$hRgn = _WinAPI_CreateRectRgn($aMouse_Pos[0], $g_iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1])  ; Right of rectangle
		If Not $hRgn Then Exit 4
		$iRgnType = _WinAPI_CombineRgn($hMaster_Rgn, $hRgn, $hMaster_Rgn, $RGN_OR)
		ConsoleWrite("-   var: $iRgnType --> " & $aRgnType[$iRgnType] & @LF)
		_WinAPI_DeleteObject($hRgn)

		$hRgn = _WinAPI_CreateRectRgn($g_iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1)   ; Bottom of rectangle
		If Not $hRgn Then Exit 1
		$iRgnType = _WinAPI_CombineRgn($hMaster_Rgn, $hRgn, $hMaster_Rgn, $RGN_OR)
		ConsoleWrite("!   var: $iRgnType --> " & $aRgnType[$iRgnType] & @LF)
		_WinAPI_DeleteObject($hRgn)

		; Set overall region
		If Not _WinAPI_SetWindowRgn($g_hRectangle_GUI, $hMaster_Rgn) Then Exit 5

		If WinGetState($g_hRectangle_GUI) < 15 Then GUISetState()
		Sleep(10)
	WEnd
	#EndRegion Draw rectangle while mouse button pressed

	ToolTip('')

	; Get second mouse position
	$g_iX2 = $aMouse_Pos[0]
	$g_iY2 = $aMouse_Pos[1]
	ConsoleWrite('> $aMouse_Pos #2 = ' & _ArrayToString($aMouse_Pos, ', ') & @CRLF)

	; Set in correct order if required
;~     If $g_iX2 < $g_iX1 Then
;~         $iTemp = $g_iX1
;~         $g_iX1 = $g_iX2
;~         $g_iX2 = $iTemp
;~     EndIf
;~     If $g_iY2 < $g_iY1 Then
;~         $iTemp = $g_iY1
;~         $g_iY1 = $g_iY2
;~         $g_iY2 = $iTemp
;~     EndIf
	_SwitchRect($g_iX1, $g_iX2)
	_SwitchRect($g_iY1, $g_iY2)

	GUIDelete($g_hRectangle_GUI)
	GUIDelete($hCross_GUI)
	Opt('MouseCoordMode', $iOldMouseCoordMode)
	ConsoleWrite('Exit _Mark_Rect' & @CRLF)
EndFunc   ;==>_Mark_Rect

Func _SwitchRect(ByRef $i1, ByRef $i2)
	Local $iTemp
	If $i2 < $i1 Then
		$iTemp = $i1
		$i1 = $i2
		$i2 = $iTemp
	EndIf
EndFunc   ;==>_SwitchRect

; -------------------------------------------
Func _Terminate()
	DllClose($g_hUserDLL)
	Exit ;
EndFunc   ;==>_Terminate
