#include-once
; --- diese Includes werden benötigt ---
#include <Array.au3>
#include <File.au3>
#include <GDIPlus.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#include <WinAPI.au3>
#include <WinAPIMisc.au3>
#include <WindowsConstants.au3>
; --------------------------------------
;===============================================================================
;
; Function Name:   _FileCopyEx($aSourceFiles, $aDestDir[, $iFlag][, $sTitle][, $hParent])
; Description:     Kopiert alle Dateien aus dem Quelldateien-Array in das entsprechende Zielverzeichnis (Array) (mit Fortschrittsanzeige)
; Parameter(s):    $aSourceFiles = ein Array mit den Quelldateien (relative Pfade erlaubt)
;                  $aDestDir = ein Array mit den Zielverzeichnissen (für jede Quelldatei das entsprechende Zielverzeichnis)
;                  $iFlag = kann folgende Werte enthalten (auch kombiniert):
;                         0 = kein überschreiben einer existierenden Zieldatei (Standardwert)
;                         1 = überschreiben einer existierenden Zieldatei
;                         2 = die Datums- und Zeitinformationen der Quelldateien werden auf die Zieldateien kopiert
;                         4 = wenn Kopiervorgang beendet, warten bis der Anwender auf [Ok] klickt
;                         8 = erstelle Zielverzeichnis, wenn es noch nicht existiert
;                        16 = erstelle ein Log-String
;                  $sTitle = ein Text für die Titelzeile der Gui
;                  $hParent = das Handle zur "Eltern"-Gui (falls vorhanden); das Kopierfenster wird dann ein "Kind" davon
; Requirement(s):  oben stehende Includes und die unten stehende Funktion "_GuiCtrlSetPath" von funkey (www.autoit.de)
;
; Return Value(s): zurückgegeben wird ein Log-String (wenn Flag 16 gesetzt ist) mit Informationen zum Kopiervorgang jeder Datei
;                  und wenn ein Fehler aufgetreten ist, dann mit Hinweis auf den Fehler
;
;                  @error kann folgende Werte annehmen (Kombinationen möglich, BitOr):
;                         0 = kein Fehler aufgetreten, alle Dateien wurden korrekt kopiert
;                         1 = das Array mit den Quelldateien ist gar kein Array
;                         2 = das Zielverzeichnis enthält einen Leerstring oder existiert nicht (Flag 8 nicht gesetzt)
;                         3 = das Zielverzeichnis konnte nicht erstellt werden (Flag 8 gesetzt)
;                         4 = das angegebene Zielverzeichnis ist gar kein Verzeichnis
;                         8 = Quelldatei existiert nicht (Hinweis zum Fehler im Log-String)
;                        16 = Fehler beim kopieren (Hinweis zum Fehler im Log-String)
;                        32 = Abbruch durch den Anwender (Hinweis zum Fehler im Log-String)
;                        64 = die Dateigröße von Quell- und Zieldatei unterscheiden sich (Hinweis zum Fehler im Log-String)
; Author(s):       "_FileCopyEx" von Oscar (www.autoit.de)
;                  "_GuiCtrlSetPath" von funkey (www.autoit.de)
;                  "_GDIPlus_StripProgressbar" von UEZ (www.autoit.de)
; Modified:
; Remarks:
;===============================================================================
;
Func _FileCopyEx($aSourceFiles, $aDestDir, $iFlag = 0, $sTitle = 'FileCopy', $hParent = 0)
	; Fehlerbehandlung Quelldateien-Array
	If Not IsArray($aSourceFiles) Then Return SetError(1, 0, '') ; wenn $aSourceFiles kein Array ist, dann Fehlercode = 1
	If IsNumber($aSourceFiles[0]) Then _ArrayDelete($aSourceFiles, 0) ; wenn das Array 1-basiert ist, dann den "Zähler" entfernen

	; Fehlerbehandlung Zielverzeichnis-Array
	If Not IsArray($aDestDir) Then Return SetError(2, 0, '') ; wenn $aDestDir kein Array ist, dann Fehlercode = 2
	If IsNumber($aDestDir[0]) Then _ArrayDelete($aDestDir, 0) ; wenn das Array 1-basiert ist, dann den "Zähler" entfernen

	If UBound($aSourceFiles) <> UBound($aDestDir) Then Return SetError(3, 0, 0) ; wenn die beiden Arrays nicht gleich groß sind, dann Fehlercode = 3

	Local $iOnEventMode = Opt('GUIOnEventMode', 0) ; umschalten auf den MessageLoopMode und alten Modus merken
	If IsHWnd($hParent) Then
		GUISetState(@SW_DISABLE, $hParent) ; evtl. Parent-Gui deaktivieren
	Else
		TraySetState(2) ; TrayIcon verstecken, wenn kein Parent angegeben wurde
	EndIf
	Local $fLogString = BitAND($iFlag, 16) = 16 ; Log-String erstellen, wenn Flag 16 gesetzt ist
	; Gui erstellen
	_GDIPlus_Startup()
	Local $iFilePercent, $iPercent
	Local $hGui = GUICreate($sTitle, 640, 340, -1, -1, BitOR($WS_POPUP, $WS_CAPTION), Default, $hParent)
	GUISetBkColor(0xDDDDDD, $hGui)
	GUISetFont(10, 400, 0, 'Arial', $hGui, 5)
	GUISetIcon('shell32.dll', 7, $hGui)

	GUICtrlCreateGroup('Kopiere:', 10, 10, 620, 275)
	GUICtrlCreateGroup('Datei:', 20, 40, 600, 50)
	Global $idSourceFile = GUICtrlCreateLabel('', 30, 62, 580, 20)
	GUICtrlSetFont(-1, 12, 400, 0, 'Arial', 5)
	GUICtrlCreateGroup('', -99, -99, 1, 1)

	GUICtrlCreateGroup('Nach:', 20, 100, 600, 50)
	Global $idDestDir = GUICtrlCreateLabel('', 30, 122, 580, 20)
	GUICtrlSetFont(-1, 12, 400, 0, 'Arial', 5)
	GUICtrlCreateGroup('', -99, -99, 1, 1)

	Local $idLabelFile = GUICtrlCreateLabel('Datei: 0 Bytes / 0 Bytes', 25, 165, 590, 20)
	Local $idProgressFile = GUICtrlCreatePic('', 20, 185, 600, 20)
	_SetProgressbar($idProgressFile, 0, 600, 24)

	Local $idLabelAll = GUICtrlCreateLabel('', 25, 220, 590, 20)
	Local $idProgressAll = GUICtrlCreatePic('', 20, 240, 600, 30)
	_SetProgressbar($idProgressAll, 0, 600, 32)

	Local $idCancel = GUICtrlCreateButton('Abbrechen', 240, 295, 160, 30)
	GUICtrlSetFont(-1, 12, 400, 0, 'Arial', 5)
	GUICtrlCreateGroup('', -99, -99, 1, 1)

	; Dateigrößen ermitteln
	Local $aSourceFileSize[UBound($aSourceFiles)], $iAllSize = 0, $iAllCopySize = 0
	For $i = 0 To UBound($aSourceFiles) - 1 ; alle Einträge des Quelldateien-Arrays durchgehen
		$aSourceFileSize[$i] = FileGetSize($aSourceFiles[$i]) ; Dateigröße in Bytes
		$iAllSize += $aSourceFileSize[$i] ; Gesamtgröße berechnen
	Next

	; Kopiervorgang vorbereiten
	GUICtrlSetData($idLabelFile, StringFormat('Datei: %i Bytes / %i Bytes', 0, 0)) ; Bytes für den Dateifortschritt anzeigen
	GUICtrlSetData($idLabelAll, StringFormat('Gesamt: 0 Bytes / %s', _WinAPI_StrFormatByteSize($iAllSize))) ; Bytes für den Gesamtfortschritt anzeigen
	GUISetState(@SW_SHOW, $hGui) ; Kopierfenster anzeigen

	Local $sSourceFile = '', $sDestFile = '', $sLog = '', $iRet = 0, $iError = 0, $iBufferSize = 0
	Local $hSource, $hDest, $iCopySize = 0, $aInfo, $iCopySpeed = 0, $aFileTime[3]

	Local $iSpeedTimer = TimerInit(), $iTimer1 = TimerInit(), $iTimer2 = TimerInit() ; die Timer initialisieren
	Local $iCount = UBound($aSourceFiles) - 1, $sTmpDir = ''
	For $i = 0 To $iCount ; alle Einträge des Quelldateien-Arrays durchgehen
		; --- Vorbereitung für die Quelldatei ---
		If $aSourceFiles[$i] = '' Then ; wenn Quelldatei ein Leerstring ist, dann...
			$iError = BitOR($iError, 8) ; Fehlercode 8 setzen
			If $fLogString Then $sLog &= StringFormat('"" = Sourcefile not exists\r\n') ; ins Log eintragen
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		$sSourceFile = FileGetLongName($aSourceFiles[$i], 1) ; evtl. relativen Pfad umwandeln
		If Not FileExists($sSourceFile) Then ; wenn die Quelldatei nicht existiert, dann...
			$iError = BitOR($iError, 8) ; Fehlercode 8 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = Sourcefile not exists\r\n', $sSourceFile) ; ins Log eintragen
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		If BitAND($iFlag, 2) Then ; wenn das Flag 2 gesetzt ist, dann...
			For $j = 0 To 2 ; 0 = zuletzt geändert, 1 = erstellt, 2 = letzter Zugriff
				$aFileTime[$j] = FileGetTime($sSourceFile, $j, 1) ; die Datums-/Zeitinformationen der Quelldatei auslesen
			Next
		EndIf
		$hSource = FileOpen($sSourceFile, $FO_BINARY) ; Quelldatei zum lesen im Binärmodus öffnen
		If $hSource = -1 Then ; wenn die Quelldatei nicht geöffnet werden konnte, dann...
			$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Sourcefile open error)\r\n', $sSourceFile) ; ins Log eintragen
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		; --- ab hier ist die Quelldatei geöffnet (muss bei Abbruch geschlossen werden!) ---
		; --- Vorbereitung für das Zielverzeichnis ---
		If StringRight($aDestDir[$i], 1) <> '\' Then $aDestDir[$i] &= '\' ; wenn beim Zielverzeichnis der hintere Backslash fehlt, dann hinzufügen
		If Not BitAND($iFlag, 8) And Not FileExists($aDestDir[$i]) Then ; wenn Flag 8 nicht gesetzt wurde und das Zielverzeichnis nicht existiert, dann...
			$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Targetdir not exists)\r\n', $aDestDir[$i]) ; ins Log eintragen
			FileClose($hSource) ; Quelldatei schließen, damit kein Lock zurückbleibt
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		If Not FileExists($aDestDir[$i]) Then ; wenn das Zielverzeichnis nicht existiert, dann das Verzeichnis erstellen
			If Not DirCreate($aDestDir[$i]) Then ; wenn das Zielverzeichnis nicht erstellt werden konnte, dann...
				$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
				If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Cannot create Targetdir)\r\n', $aDestDir[$i]) ; ins Log eintragen
				FileClose($hSource) ; Quelldatei schließen, damit kein Lock zurückbleibt
				ContinueLoop ; und mit der nächsten Datei weitermachen
			EndIf
		EndIf
		If Not StringInStr(FileGetAttrib($aDestDir[$i]), 'D') Then ; wenn das Zielverzeichnis kein Verzeichnis ist, dann...
			$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Targetdir is not a Directory)\r\n', $aDestDir[$i]) ; ins Log eintragen
			FileClose($hSource) ; Quelldatei schließen, damit kein Lock zurückbleibt
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		; --- Vorbereitung für die Zieldatei ---
		$sDestFile = $aDestDir[$i] & StringRegExpReplace($sSourceFile, '.+\\(.+)', '$1') ; Zieldateinamen erstellen (Zielverzeichnis & Quelldateiname)
		If Not BitAND($iFlag, 1) And FileExists($sDestFile) Then ; wenn $iFlag = 0 (nicht überschreiben) und die Zieldatei bereits existiert, dann...
			$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Targetfile exists)\r\n', $sSourceFile) ; ins Log eintragen
			FileClose($hSource) ; Quelldatei schließen, damit kein Lock zurückbleibt
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		$hDest = FileOpen($sDestFile, $FO_BINARY + $FO_OVERWRITE) ; Zieldatei zum schreiben im Binärmodus öffnen
		If $hDest = -1 Then ; wenn die Zieldatei nicht geöffnet werden konnte, dann...
			$iError = BitOR($iError, 16) ; Fehlercode 16 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy failed (Targetfile open error)\r\n', $sDestFile) ; ins Log eintragen
			FileClose($hSource) ; Quelldatei schließen, damit kein Lock zurückbleibt
			ContinueLoop ; und mit der nächsten Datei weitermachen
		EndIf
		; --- ab hier sind Quell- und Zieldatei geöffnet (müssen bei Abbruch geschlossen werden!) ---
		_GuiCtrlSetPath($idSourceFile, '"' & $sSourceFile & '"') ; Quelldateiname anzeigen
		If $aDestDir[$i] <> $sTmpDir Then ; wenn sich das Zielverzeichnis geändert hat, dann...
			$sTmpDir = $aDestDir[$i] ; neues Zielverzeichnis merken
			_GuiCtrlSetPath($idDestDir, '"' & $aDestDir[$i] & '"') ; neues Zielverzeichnis anzeigen
		EndIf
		; --- Vorbereitung für den Kopiervorgang ---
		If $aSourceFileSize[$i] < 16777216 Then ; bei Dateien kleiner als 16 MByte
			$iBufferSize = 524288 ; 512 KByte Buffer verwenden
		Else ; sonst (> 16 MByte)
			$iBufferSize = 8388608 ; 8192 KByte Buffer verwenden
		EndIf
		$iCopySize = 0 ; die gelesenen Bytes zum Dateifortschritt auf null setzen
		; --- hier beginnt der eigentliche Kopiervorgang (Quell- und Zieldatei sind geöffnet) ---
		$iTimer1 = TimerInit() ; den Anzeige-Timer für den Dateifortschritt initialisieren
		Do
			$aInfo = GUIGetCursorInfo($hGui) ; Gui-Information auslesen (nicht GuiGetMsg verwenden, weil dort die Durchlaufgeschwindigkeit gedrosselt wird)
			If $aInfo[2] And $aInfo[4] = $idCancel Then ; wenn Mausklick auf "Cancel"-Button, dann...
				$iError = BitOR($iError, 32) ; Fehlercode 32 setzen
				FileClose($hSource) ; Quelldatei schließen
				FileClose($hDest) ; Zieldatei schließen
				FileDelete($sDestFile) ; Zieldatei löschen, da unvollständig
				If $fLogString Then $sLog &= StringFormat('"%s" = FileCopy cancelled by User\r\n', $sDestFile) ; ins Log eintragen
				ExitLoop 2 ; und die äußere Schleife verlassen (Funktion abbrechen)
			EndIf
			$sBuffer = FileRead($hSource, $iBufferSize) ; einen Teil der Quelldatei in den Speicher lesen
			If @error Then ExitLoop ; wenn das Dateiende erreicht wurde, dann die Schleife verlassen
			$iCopySize += @extended ; die gelesenen Bytes zum Dateifortschritt addieren
			$iAllCopySize += @extended ; die gelesenen Bytes zum Gesamtfortschritt addieren
			If TimerDiff($iTimer1) > 100 Then ; die Anzeige nur aktualisieren, wenn das kopieren der Datei länger als 100 ms dauert
				GUICtrlSetData($idLabelFile, StringFormat('Datei: %s / %s', _WinAPI_StrFormatByteSize($iCopySize), _WinAPI_StrFormatByteSize($aSourceFileSize[$i]))) ; Bytes für den Dateifortschritt anzeigen
				$iFilePercent = Int(100 / $aSourceFileSize[$i] * $iCopySize) ; Prozentwert ausrechnen
				_SetProgressbar($idProgressFile, $iFilePercent, 600, 24) ; die Progressbar entsprechend füllen
				$iTimer1 = TimerInit() ; den Anzeige-Timer initialisieren
			EndIf
			If TimerDiff($iTimer2) > 100 Then ; die Anzeige für den Gesamtfortschritt auch nur alle 100 ms aktualisieren
				$iCopySpeed = Int($iAllCopySize / (TimerDiff($iSpeedTimer) / 1000)) ; <- Kopiergeschwindigkeit berechnen (Bytes / Sekunde)
				GUICtrlSetData($idLabelAll, StringFormat('Gesamt: %i / %i   %s / %s   (%s/s)', $i + 1, $iCount, _WinAPI_StrFormatByteSize($iAllCopySize), _WinAPI_StrFormatByteSize($iAllSize), _WinAPI_StrFormatByteSize($iCopySpeed))) ; Bytes für den Gesamtfortschritt und Kopiergeschwindigkeit anzeigen
				$iPercent = Int(100 / $iAllSize * $iAllCopySize) ; Prozentwert ausrechnen
				_SetProgressbar($idProgressAll, $iPercent, 600, 32) ; die Progressbar entsprechend füllen
				$iTimer2 = TimerInit() ; den Anzeige-Timer initialisieren
			EndIf
			$iRet = FileWrite($hDest, $sBuffer) ; den Teil der Quelldatei aus dem Speicher in die Zieldatei schreiben
		Until $iRet = 0 ; weitermachen mit dem kopieren, wenn beim schreiben kein Fehler aufgetreten ist
		FileClose($hSource) ; Quelldatei schließen
		FileClose($hDest) ; Zieldatei schließen
		If $iFilePercent > 0 Then ;
			$iFilePercent = 0 ; Prozentwert auf 0 setzen
			_SetProgressbar($idProgressFile, $iFilePercent, 600, 24); die Progressbar als leer anzeigen
			GUICtrlSetData($idLabelFile, StringFormat('Datei: %s / %s', _WinAPI_StrFormatByteSize(0), _WinAPI_StrFormatByteSize(0))) ; Bytes für den Dateifortschritt auf 0 setzen
		EndIf
		; Kopiervorgang beendet

		; überprüfen, ob Quell- und Zieldatei gleich groß sind
		If FileGetSize($sDestFile) = $aSourceFileSize[$i] Then ; wenn das kopieren erfolgreich war, dann...
			If BitAND($iFlag, 2) Then ; wenn das Flag 2 gesetzt ist, dann...
				For $j = 0 To 2 ; 0 = zuletzt geändert, 1 = erstellt, 2 = letzter Zugriff
					FileSetTime($sDestFile, $aFileTime[$j], $j) ; die Datums-/Zeitinformationen der Quelldatei auf die Zieldatei übertragen
				Next
			EndIf
			If $fLogString Then $sLog &= StringFormat('"%s" -> "%s" = FileCopy successful\r\n', $sSourceFile, $sDestFile) ; ins Log eintragen
		Else ; wenn das kopieren nicht erfolgreich war, dann...
			$iError = BitOR($iError, 64) ; Fehlercode 64 setzen
			If $fLogString Then $sLog &= StringFormat('"%s" <-> "%s" = FileCopy failed (different FileSize)\r\n', $sSourceFile, $sDestFile) ; ins Log eintragen
		EndIf
	Next ; mit der nächsten Datei weitermachen
	; --- alle Einträge im Array sind durchlaufen ---
	If BitAND($iFlag, 4) Then ; wenn Flag 4 gesetzt, dann...
		_GuiCtrlSetPath($idSourceFile, '"' & $sSourceFile & '"') ; den letzten Quelldateinamen anzeigen
		_GuiCtrlSetPath($idDestDir, '"' & $aDestDir[$iCount] & '"') ; das zuletzt benutzte Zielverzeichnis anzeigen
		$iCopySpeed = Int($iAllCopySize / (TimerDiff($iSpeedTimer) / 1000)) ; <- Kopiergeschwindigkeit berechnen (Bytes / Sekunde)
		GUICtrlSetData($idLabelAll, StringFormat('Gesamt: %i / %i   %s / %s   (%s/s)', $i, $i, _WinAPI_StrFormatByteSize($iAllCopySize), _WinAPI_StrFormatByteSize($iAllSize), _WinAPI_StrFormatByteSize($iCopySpeed))) ; Bytes für den Gesamtfortschritt und Kopiergeschwindigkeit anzeigen
		_SetProgressbar($idProgressAll, 100, 600, 32)
		GUICtrlSetData($idCancel, 'Ok') ; den Button in "Ok" umbenennen
		Do
		Until GUIGetMsg() = $idCancel ; und auf die Bestätigung durch den Anwender warten
	EndIf
	If IsHWnd($hParent) Then GUISetState(@SW_ENABLE, $hParent) ; evtl. Parent-Gui wieder aktivieren
	GUIDelete($hGui) ; das Kopierfenster löschen
	Opt('GUIOnEventMode', $iOnEventMode) ; und wieder umschalten auf den gemerkten Modus
	_GDIPlus_Shutdown()
	Return SetError($iError, 0, $sLog) ; evtl. Errorcodes setzen und den Log-String zurückgeben
EndFunc   ;==>_FileCopyEx

Func _SetProgressbar($idProgress, $iPercent, $iW, $iH)
	Local $aColors[7][2] = [[0xFFEE5F5B, 0xFFF07673], [0xFFABCC04, 0xFFBBD636], [0xFF78CCEE, 0xFF93D6F1], [0xFFFFBB58, 0xFFFFC97A], [0xFFFF6677, 0xFFFF8795], [0xFF78CCEE, 0xFFFFC97A], [0xFF78CCEE, 0xFFE8E5D9]]
	Local $iBGColor = 0xFEFEFE
	Local $hHBmp_BG = _GDIPlus_StripProgressbar($iPercent, $iW, $iH, 0xFF000000 + $iBGColor, $aColors[1][0], $aColors[1][1], $iPercent & '%')
	Local $hB = GUICtrlSendMsg($idProgress, 0x0172, $IMAGE_BITMAP, $hHBmp_BG)
	If $hB Then _WinAPI_DeleteObject($hB)
	_WinAPI_DeleteObject($hHBmp_BG)
EndFunc

;===============================================================================
; Function Name:   _FileCopyEx_CreateArrays($aSourceFiles, $sDestDir)
; Description:     Diese Funktion dient dazu, die Arrays für "_FileCopyEx" zu erstellen.
; Parameter(s):    $sSourceDir = das Quellverzeichnis, mit den zu kopierenden Dateien
;                  $sDestDir = das Zielverzeichnis, wohin die Quelldateien kopiert werden sollen
;                  $aSourceFiles = das Array für die Quelldateien
;                  $aDestDir = das Array für die Zielverzeichnisse
;                  $sMask = Filter für "_FileListToArrayRec" (siehe dort)
;                  $iRecur = Rekursiv (1) oder nicht (0) bzw. Rekursionstiefe (negative Werte)
; Return Value(s): @error = 0 Die Arrays wurden erfolgreich erstellt
;                  @error = 1 Im Quellverzeichnis befinden sich keine Dateien
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
;
Func _FileCopyEx_CreateArrays($sSourceDir, $sDestDir, ByRef $aSourceFiles, ByRef $aDestDir, $sMask = '*', $iRecur = $FLTAR_RECUR)
	$aSourceFiles = _FileListToArrayRec($sSourceDir, $sMask, $FLTAR_FILES, $iRecur, $FLTAR_SORT)
	If @error Then Return SetError(1, 0, 0) ; wenn sich im Quellverzeichnis keine Dateien befinden, dann Fehlercode = 1
	If IsNumber($aSourceFiles[0]) Then _ArrayDelete($aSourceFiles, 0) ; wenn das Array 1-basiert ist, dann den "Zähler" entfernen
	ReDim $aDestDir[UBound($aSourceFiles)]
	Local $sTmp = ''
	If StringRight($sSourceDir, 1) <> '\' Then $sSourceDir &= '\' ; wenn beim Quellverzeichnis der hintere Backslash fehlt, dann hinzufügen
	If StringRight($sDestDir, 1) <> '\' Then $sDestDir &= '\' ; wenn beim Zielverzeichnis der hintere Backslash fehlt, dann hinzufügen
	For $i = 0 To UBound($aSourceFiles) - 1
		$sTmp = StringRegExpReplace($aSourceFiles[$i], '(.+\\).*', '$1') ; Verzeichnis aus der Quelldatei extrahieren
		If $sTmp = $aSourceFiles[$i] Then $sTmp = '' ; wenn kein Verzeichnis vorhanden, dann einen Leerstring benutzen
		$aDestDir[$i] = $sDestDir & $sTmp ; Zielverzeichnis anhand der Quelldatei erstellen
		$aSourceFiles[$i] = $sSourceDir & $aSourceFiles[$i] ; der Quelldatei das Quellverzeichnis voranstellen
	Next
	Return SetError(0, 0, 1)
EndFunc   ;==>_FileCopyEx_CreateArrays

Func _GuiCtrlSetPath($nID, $sPath, $iFit = 0)
	;coded by funkey
	;2011, Nov 24th
	Local $hCtrl = GUICtrlGetHandle($nID)
	Local $hDC = _WinAPI_GetDC($hCtrl)
	Local $tPath = DllStructCreate("char[260]")
	Local $pPath = DllStructGetPtr($tPath)
	DllStructSetData($tPath, 1, $sPath)
	Local $hFont = _SendMessage($hCtrl, 49, 0, 0, 0, "wparam", "lparam", "hwnd") ;WM_GETFONT
	Local $hFont_old = _WinAPI_SelectObject($hDC, $hFont)
	Local $aPos = ControlGetPos($hCtrl, "", "")
	DllCall("Shlwapi.dll", "BOOL", "PathCompactPath", "handle", $hDC, "ptr", $pPath, "int", $aPos[2] - $iFit)
	_WinAPI_SelectObject($hDC, $hFont_old)
	_WinAPI_DeleteDC($hDC)
	GUICtrlSetData($nID, DllStructGetData($tPath, 1))
	Return DllStructGetData($tPath, 1)
EndFunc   ;==>_GuiCtrlSetPath

Func _GDIPlus_StripProgressbar($fPerc, $iW, $iH, $iBgColorGui = 0xFFF0F0F0, $iFgColor = 0xFFEE5F5B, $iBGColor = 0xFFF07673, $sText = 'Loading...', $iTextColor = 0x000000, $iDir = -1, $iSpeed = 1, $sFont = 'Arial', $bFlip = False, $bHBitmap = True)
	$fPerc = $fPerc < 0 ? 0 : $fPerc
	$fPerc = $fPerc > 100 ? 100 : $fPerc

	Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
	Local Const $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
	_GDIPlus_GraphicsSetPixelOffsetMode($hCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
	_GDIPlus_GraphicsClear($hCtxt, $iBgColorGui)

	Local $iWidth = $iH * 2, $iLen = $iWidth / 2, $iY
	Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iWidth, $iH)
	Local Const $hCtxt_Bmp = _GDIPlus_ImageGetGraphicsContext($hBmp)
	_GDIPlus_GraphicsSetPixelOffsetMode($hCtxt_Bmp, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
	Local $hPen = _GDIPlus_PenCreate($iFgColor), $iPenSize = Int($iH / 12)
	Local $hPen2 = _GDIPlus_PenCreate(0x50000000, $iPenSize)

	_GDIPlus_GraphicsClear($hCtxt_Bmp, $iBGColor)
	Local Static $iX = 0
	For $iY = 0 To $iH - 1
		Switch $iDir
			Case 1
				_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, $iX + $iY, $iY, $iX + $iY + $iLen, $iY, $hPen)
				_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, $iX + $iY - 2 * $iLen, $iY, $iX + $iY - 1 * $iLen, $iY, $hPen)
			Case Else
				_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, -$iX + $iY, $iY, -$iX + $iY + $iLen, $iY, $hPen)
				_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, -$iX + $iY + 2 * $iLen, $iY, -$iX + $iY + 3 * $iLen, $iY, $hPen)
		EndSwitch
	Next
	Local $tPoint1 = DllStructCreate('float;float')
	Local $tPoint2 = DllStructCreate('float;float')
	DllStructSetData($tPoint1, 1, $iW / 2) ;x1
	DllStructSetData($tPoint2, 1, $iW / 2) ;x2
	Local $hLineBrush

	If $bFlip Then
		_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, 0, 0, $iWidth, 0, $hPen2)
		DllStructSetData($tPoint1, 2, $iH / 3) ;y1
		DllStructSetData($tPoint2, 2, $iH * 2 / 3) ;y2
		$hLineBrush = DllCall($__g_hGDIPDll, 'uint', 'GdipCreateLineBrush', 'struct*', $tPoint1, 'struct*', $tPoint2, 'uint', 0x00FFFFFF, 'uint', 0xB0FFFFFF, 'int', 0, 'int*', 0)
		$hLineBrush = $hLineBrush[6]
		_GDIPlus_GraphicsFillRect($hCtxt_Bmp, 0, $iH * 2 / 3 + 1, $iW, $iH / 3, $hLineBrush)
	Else
		_GDIPlus_GraphicsDrawLine($hCtxt_Bmp, 0, $iH - $iPenSize / 2, $iWidth, $iH - $iPenSize / 2, $hPen2)
		DllStructSetData($tPoint1, 2, 0) ;y1
		DllStructSetData($tPoint2, 2, $iH / 3) ;y2
		$hLineBrush = DllCall($__g_hGDIPDll, 'uint', 'GdipCreateLineBrush', 'struct*', $tPoint1, 'struct*', $tPoint2, 'uint', 0xB0FFFFFF, 'uint', 0x00FFFFFF, 'int', 0, 'int*', 0)
		$hLineBrush = $hLineBrush[6]
		_GDIPlus_GraphicsFillRect($hCtxt_Bmp, 0, 0, $iW, $iH / 3, $hLineBrush)
	EndIf
	$iX = Mod($iX + $iSpeed, $iWidth)

	Local $hTextureBrush = _GDIPlus_TextureCreate($hBmp)

	_GDIPlus_GraphicsFillRect($hCtxt, 0, 0, $fPerc / 100 * $iW, $iH, $hTextureBrush)
	If $bFlip Then _GDIPlus_ImageRotateFlip($hBitmap, 6)
	_GDIPlus_GraphicsSetTextRenderingHint($hCtxt, 4)

	Local $hBrush = _GDIPlus_BrushCreateSolid(0xE0000000 + $iTextColor)
	Local $hFormat = _GDIPlus_StringFormatCreate()
	Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
	Local $hFont = _GDIPlus_FontCreate($hFamily, $iH * 3 / 7)
	Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
	_GDIPlus_StringFormatSetAlign($hFormat, 1)
	_GDIPlus_StringFormatSetLineAlign($hFormat, 1)
	_GDIPlus_GraphicsDrawStringEx($hCtxt, $sText, $hFont, $tLayout, $hFormat, $hBrush)

	_GDIPlus_FontDispose($hFont)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_PenDispose($hPen)
	_GDIPlus_PenDispose($hPen2)
	_GDIPlus_GraphicsDispose($hCtxt)
	_GDIPlus_GraphicsDispose($hCtxt_Bmp)
	_GDIPlus_BitmapDispose($hBmp)
	_GDIPlus_BrushDispose($hTextureBrush)
	_GDIPlus_BrushDispose($hLineBrush)
	If $bHBitmap Then
		Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
		_GDIPlus_BitmapDispose($hBitmap)
		Return $hHBITMAP
	EndIf
	Return $hBitmap
EndFunc   ;==>_GDIPlus_StripProgressbar
