;-- TIME_STAMP   2018-05-26 09:39:23   v 0.1

#Region    ;************ Includes ************
#include-once
#include <WinAPISys.au3>
#include <WinAPIGdi.au3>
#EndRegion ;************ Includes ************

; #FUNCTION# ====================================================================================================================
; Name ..........: _CheckWinPos
; Description ...: Verschiebt ein Fenster, wenn die linke obere Ecke nicht sichtbar ist, entweder auf den primären Monitor,
;                  oder auf den Monitor, der den Koordinaten am nähesten ist, von denen aus verschoben werden soll, wobei
;                  bestimmt werden kann, ob das Fenster sichtbar, minnimiert, maximiert und/oder die Größe angepasst werden soll.
; Syntax ........: _CheckWinPos($hWnd[, $iShow = -1[, $bPrimary = False[, $bReSize = False[, $bPreserveAspectRatio = True]]]])
; Parameters ....: $hWnd                 - a handle value.
;                  $iShow                - [optional] an integer value. Default is -1.
;                  $bPrimary             - [optional] a boolean value. Default is False.
;                  $bReSize              - [optional] a boolean value. Default is False.
;                  $bPreserveAspectRatio - [optional] a boolean value. Default is True.
; Return Value(s): True, wenn erfolgreich, @extended = 0 Fenster wurde nicht verschoben, 1 Fenster wurde verschoben
;                  @error = 1, $hWnd ist kein HWnd
;                  @error = 2, Fehler bei _WinAPI_MonitorFromRect ($hWnd)
;                  @error = 3, Fehler bei _WinAPI_MonitorFromRect (MonitorWorkArea)
; Author ........: Bitnugger
; Modified ......:
; Remarks .......:
; Related .......:
; Requires ......: WinAPISys.au3, WinAPIGdi.au3
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _CheckWinPos($hWnd, $iShow = -1, $bPrimary = False, $bReSize = False, $bPreserveAspectRatio = True)
	ConsoleWrite(StringFormat('> _CheckWinPos: $hWnd = %s $iShow = %-7s, $bPrimary = %-4s, $bReSize = %-4s $bPreserveAspectRatio = %s\n', $hWnd, $iShow, $bPrimary, $bReSize, $bPreserveAspectRatio))
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, False)

	Local $iX, $iY, $iR, $hMonitor, $tWindowPlacement, $tNormalPosition, $tWorkArea, $tPoint, $aClientSize, $aNormalPosition, $aMonitorInfo, $aMonitorWorkArea, $aWinPos

	; WinMove hat keinen Effekt, wenn das Fenster minimiert ist - _WinAPI_SetWindowPlacement aber!
	$tWindowPlacement = _WinAPI_GetWindowPlacement($hWnd)
	$tNormalPosition = DllStructCreate($tagRECT, DllStructGetPtr($tWindowPlacement, 'rcNormalPosition'))
	Switch DllStructGetData($tWindowPlacement, 'showCmd')
		Case @SW_HIDE, @SW_RESTORE, @SW_SHOW, @SW_SHOWNA, @SW_SHOWNOACTIVATE, @SW_SHOWNORMAL ; @SW_MAXIMIZE, @SW_SHOWMAXIMIZED, @SW_MINIMIZE, @SW_SHOWMINIMIZED, @SW_SHOWMINNOACTIVE
			ConsoleWrite('! _CheckWinPos: $tNormalPosition <-- $aWinPos' & @CRLF)
			$aWinPos = WinGetPos($hWnd)
			DllStructSetData($tNormalPosition, 'Left', $aWinPos[0])
			DllStructSetData($tNormalPosition, 'Top', $aWinPos[1])
			DllStructSetData($tNormalPosition, 'Right', $aWinPos[0] + $aWinPos[2])
			DllStructSetData($tNormalPosition, 'Bottom', $aWinPos[1] + $aWinPos[3])
		Case Else
			ConsoleWrite('! _CheckWinPos: $tNormalPosition <-- $tWindowPlacement' & @CRLF)
	EndSwitch
	$aNormalPosition = _WinAPI_GetPosFromRect($tNormalPosition)
	$hMonitor = _WinAPI_MonitorFromRect($tNormalPosition)
	If @error Then Return SetError(2, 0, False)
	$aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
	$tWorkArea = $aMonitorInfo[1]
	$aMonitorWorkArea = _WinAPI_GetPosFromRect($tWorkArea)
	$tPoint = _WinAPI_CreatePoint(DllStructGetData($tNormalPosition, 'Left'), DllStructGetData($tNormalPosition, 'Top'))

	If _WinAPI_PtInRect($tWorkArea, $tPoint) Then Return True

	If $bPrimary Then
		$tWorkArea = _WinAPI_GetWorkArea()
		$hMonitor = _WinAPI_MonitorFromRect($tWorkArea)
		If @error Then Return SetError(3, 0, False)
		$aMonitorInfo = _WinAPI_GetMonitorInfo($hMonitor)
		$tWorkArea = $aMonitorInfo[1]
		$aMonitorWorkArea = _WinAPI_GetPosFromRect($tWorkArea)
	EndIf

	If $aNormalPosition[2] > $aMonitorWorkArea[2] Or $aNormalPosition[3] > $aMonitorWorkArea[3] Then
		Switch $bReSize
			Case True
				; Achtung: Die Fenstergröße ändert sich, wenn in Windows 10 die Multitaking-Einstellung "Beim Andocken eines Fensters Fenstergröße automatisch an den verfügbaren Platz anpassen" aktiviert ist!
				$aClientSize = WinGetClientSize($hWnd)
				$iX = $aNormalPosition[2] - $aMonitorWorkArea[2]
				$iY = $aNormalPosition[3] - $aMonitorWorkArea[3]
				If $bPreserveAspectRatio Then
					ConsoleWrite('! $bPreserveAspectRatio True' & @CRLF)
					$iR = $iX > $iY ? $aMonitorWorkArea[2] / $aNormalPosition[2] : $aMonitorWorkArea[3] / $aNormalPosition[3]
					$aNormalPosition[2] *= $iR
					$aNormalPosition[3] *= $iR
				Else
					ConsoleWrite('! $bPreserveAspectRatio False' & @CRLF)
					$aNormalPosition[2] = $aMonitorWorkArea[2] > $aNormalPosition[2] ? $aNormalPosition[2] : $aMonitorWorkArea[2]
					$aNormalPosition[3] = $aMonitorWorkArea[3] > $aNormalPosition[3] ? $aNormalPosition[3] : $aMonitorWorkArea[3]
				EndIf
			Case Else
;~ 				Return False
		EndSwitch
		$iR = 1
	EndIf
	If $iR Then
		$iX = $aMonitorWorkArea[0]
		$iY = $aMonitorWorkArea[1]
	Else
		$iX = ($aMonitorWorkArea[2] - $aNormalPosition[2]) / 2
		$iX = $aMonitorWorkArea[0] = 0 ? $iX : $aMonitorWorkArea[0] < 0 ? $iX + $aMonitorWorkArea[0] : $aMonitorWorkArea[0] + $iX
		$iY = ($aMonitorWorkArea[3] - $aNormalPosition[3]) / 2
		$iY = $aMonitorWorkArea[1] = 0 ? $iY : $aMonitorWorkArea[1] < 0 ? $iY + $aMonitorWorkArea[1] : $aMonitorWorkArea[1] + $iY
	EndIf
	Switch $iShow
		Case '', -1, Default, ($iShow == False)
			; Do nothing
		Case @SW_HIDE To @SW_RESTORE ; 0 To 9
			DllStructSetData($tWindowPlacement, 'showCmd', $iShow) ; temporärer Wert für das nächste _WinAPI_SetWindowPlacement
	EndSwitch
	DllStructSetData($tNormalPosition, 'Left', $iX)
	DllStructSetData($tNormalPosition, 'Top', $iY )
	DllStructSetData($tNormalPosition, 'Right', $iX + $aNormalPosition[2])
	DllStructSetData($tNormalPosition, 'Bottom', $iY + $aNormalPosition[3])

	Return SetExtended(1, (_WinAPI_SetWindowPlacement($hWnd, $tWindowPlacement) = True))
EndFunc   ;==>_CheckWinPos
