﻿; Version: 1.1.0.0
; Date: 13-04-2018
#include-once
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WinAPISys.au3>

;===============================================================================
; Function Name:   _LoadWindowPlacement($hWnd, $sFile[, $iBlock])
; Description:     Laedt die Positionsdaten aus einer Datei und setzt
;                  diese fuer das angegebene Fenster
; Parameter(s):    $hWnd = das Handle des Fensters
;                  $sFile = die Datei, aus der die Daten geladen werden
;                  $iBlock = welcher 44-Byte-Block geladen werden soll
;                            (Standard = 0 / erster Block)
; Requirement(s):  #include <WinAPI.au3>
; Return Value(s): True, wenn erfolgreich, ansonsten False und
;                  @error = 1, wenn $hWnd kein Handle ist
;                  @error = 2, wenn die Datei nicht geoeffnet werden konnte
;                  @error = 3, wenn FilePointer nicht gesetzt werden konnte
;                  @error = 4, wenn die Daten fehlerhaft geladen wurden
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _LoadWindowPlacement($hWnd, $sFile, $iBlock = 0)
	Local $tWindowPlacement, $hFile, $iSize, $iFilePtr, $iBytes
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, False)
	$hFile = _WinAPI_CreateFile($sFile, 2, 2) ; 2 = Open a file (fail, if not exists), 2 = Read-Mode
	If @error Then Return SetError(2, 0, False)
	$tWindowPlacement = DllStructCreate($tagWINDOWPLACEMENT)
	$iSize = DllStructGetSize($tWindowPlacement) ; Structsize = 44 Bytes
	$iFilePtr = _WinAPI_SetFilePointer($hFile, $iBlock * $iSize)
	If $iFilePtr = -1 Then Return SetError(3, 0, False)
	_WinAPI_ReadFile($hFile, DllStructGetPtr($tWindowPlacement), $iSize, $iBytes)
	_WinAPI_CloseHandle($hFile)
	If $iBytes <> $iSize Then Return SetError(4, 0, False)
	_WinAPI_SetWindowPlacement($hWnd, $tWindowPlacement)
	Return SetError(0, 0, True)
EndFunc

;===============================================================================
; Function Name:   _SaveWindowPlacement($hWnd, $sFile[, $iBlock])
; Description:     Speichert die Positionsdaten eines Fensters in einer Datei
; Parameter(s):    $hWnd = das Handle des Fensters
;                  $sFile = die Datei, in der die Daten gespeichert werden
;                  $iBlock = welcher 44-Byte-Block gespeichert werden soll
;                            (Standard = 0 / erster Block)
; Requirement(s):  #include <WinAPI.au3>
; Return Value(s): True, wenn erfolgreich, ansonsten False und
;                  @error = 1, wenn Fehler bei _WinAPI_GetWindowPlacement()
;                  @error = 2, wenn die Datei nicht geoeffnet werden konnte
;                  @error = 3, wenn FilePointer nicht gesetzt werden konnte
;                  @error = 4, wenn die Daten fehlerhaft gespeichert wurden
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _SaveWindowPlacement($hWnd, $sFile, $iBlock = 0)
	Local $tWindowPlacement, $hFile, $iSize, $iFilePtr, $iBytes
	$tWindowPlacement = _WinAPI_GetWindowPlacement($hWnd)
	If @error Then Return SetError(1, 0, False)
	$hFile = _WinAPI_CreateFile($sFile, 3, 4) ; 3 = Open a file (create, if not exists), 4 = Write-Mode
	If $hFile = 0 Then Return SetError(2, 0, False)
	$iSize = DllStructGetSize($tWindowPlacement)
	$iFilePtr = _WinAPI_SetFilePointer($hFile, $iBlock * $iSize)
	If $iFilePtr = -1 Then Return SetError(3, 0, False)
	_WinAPI_WriteFile($hFile, DllStructGetPtr($tWindowPlacement), $iSize, $iBytes)
	_WinAPI_CloseHandle($hFile)
	If $iBytes <> $iSize Then Return SetError(4, 0, False)
	Return SetError(0, 0, True)
EndFunc

;===============================================================================
; Function Name:   _WindowOnDesktop($hWnd)
; Description:     Prueft, ob sich das Fenster auf dem Desktop befindet und
;                  zentriert es auf diesen, wenn es nicht so ist
; Parameter(s):    $hWnd = das Handle des Fensters
; Requirement(s):  #include <WinAPI.au3>
; Return Value(s): True, wenn erfolgreich, ansonsten False und
;                  @error = 1, wenn $hWnd kein Handle ist
;                  @error = 2, wenn Fehler bei _WinAPI_GetWindowInfo()
; Author(s):       Oscar + Bitnugger (www.autoit.de)
;===============================================================================
Func _WindowOnDesktop($hWnd)
	Local $tDesktopInfo, $tDesktopRect, $tWindowPlacement, $tWindowPoint, $iWidth, $iHeight, $tRECT, $iLeft, $iTop
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, False)
	$tDesktopInfo = _WinAPI_GetWindowInfo(WinGetHandle('[CLASS:Progman]'))
	If @error Then Return SetError(2, 0, False)
	$tDesktopRect = DllStructCreate($tagRECT, DllStructGetPtr($tDesktopInfo, 'rWindow'))
	$tWindowPlacement = _WinAPI_GetWindowPlacement($hWnd)
	$tWindowPoint = DllStructCreate($tagPOINT, DllStructGetPtr($tWindowPlacement, 'rcNormalPosition'))
	If Not _WinAPI_PtInRect($tDesktopRect, $tWindowPoint) Then ; wenn das Fenster sich nicht auf dem Desktop befindet, dann...
		$iWidth = DllStructGetData($tWindowPlacement, 'rcNormalPosition', 3) - DllStructGetData($tWindowPlacement, 'rcNormalPosition', 1)
		$iHeight = DllStructGetData($tWindowPlacement, 'rcNormalPosition', 4) - DllStructGetData($tWindowPlacement, 'rcNormalPosition', 2)
		$tRECT = _WinAPI_GetWorkArea() ; hole die Desktop-WorkArea (ohne Taskleiste)
		$iLeft = (DllStructGetData($tRECT, 'Right') - DllStructGetData($tRECT, 'Left')) / 2 - $iWidth / 2 ; Left neu berechnen
		$iTop = (DllStructGetData($tRECT, 'Bottom') - DllStructGetData($tRECT, 'Top')) / 2 - $iHeight / 2 ; Top neu berechnen
		DllStructSetData($tWindowPlacement, 'rcNormalPosition', $iLeft, 1) ; Setze das neue Left
		DllStructSetData($tWindowPlacement, 'rcNormalPosition', $iTop, 2) ; Setze das neue Top
		DllStructSetData($tWindowPlacement, 'rcNormalPosition', $iLeft + $iWidth, 3) ; Setze das neue Right
		DllStructSetData($tWindowPlacement, 'rcNormalPosition', $iTop + $iHeight, 4) ; Setze das neue Bottom
		_WinAPI_SetWindowPlacement($hWnd, $tWindowPlacement)
		Return SetError(0, 0, False)
	EndIf
	Return SetError(0, 0, True)
EndFunc
