#NoTrayIcon
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=prog.ico
#AutoIt3Wrapper_outfile=MSP.exe
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Description=MSP Mini-Sync-Programm
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Oscar (www.autoit.de)
#AutoIt3Wrapper_Res_Language=1031
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <ButtonConstants.au3>
#include <Crypt.au3>
#include <Date.au3>
#include <EditConstants.au3>
#include <FileConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiStatusBar.au3>
#include <ListViewConstants.au3>
#include <Memory.au3>
#include <MemoryConstants.au3>
#include <Misc.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Opt('GUIOnEventMode', 1)
Opt('GUICloseOnESC', 0)

Global $sTitle = 'MSP - Mini-Sync-Programm'
Global $sVersion = '1.0.0.0'
Global $sDate = '13.12.2011'
Global $sAppDir = @AppDataDir & '\MSP\'
If Not FileExists($sAppDir) Then DirCreate($sAppDir)
Global $sInifile = $sAppDir & 'MSP.ini'
Global $sProfileNames, $aProfileNames = IniReadSectionNames($sInifile)
If Not @error Then
	For $i = 1 To $aProfileNames[0]
		$sProfileNames &= $aProfileNames[$i] & '|'
	Next
	$sProfileNames = StringTrimRight($sProfileNames, 1)
EndIf

Global $sSourcePath, $sDestPath, $iCopyCount, $iFileCount, $iDelCount, $sCreateDirList
Global $iCopyTimer, $aMSPCopyGui, $sStopBackup, $iCopyTransferred, $iCopySize
Global $hKernel32Dll = DllOpen('kernel32.dll')
Global $hUser32Dll = DllOpen('user32.dll')

Global $hGui = GUICreate(StringFormat('%s (Version %s)', $sTitle, StringLeft($sVersion, 3)), 650, 420)
GUISetOnEvent($GUI_EVENT_CLOSE, '_Close')
GUISetBkColor(0xBBBBBB)
GUISetIcon(@ScriptDir & '\MSP.exe', -1, 0)
GUISetFont(9, 400, 0, 'Arial')

GUICtrlCreateGroup('Quellverzeichnis (Alle enthaltenen Dateien/Verzeichnisse inkl. Unterverzeichnisse werden kopiert.)', 10, 10, 630, 56)
Global $idSourcePath = GUICtrlCreateInput($sSourcePath, 20, 32, 560, 22, BitOR($ES_READONLY, $ES_LEFT, $ES_AUTOHSCROLL))
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlCreateGroup('', -99, -99, 1, 1)
Global $idSourceSel = GUICtrlCreateButton('', 590, 22, 40, 40, $BS_BITMAP)
Global $hSelFolderIcon = _Load_BMP_From_Mem(_SelFolderpng(), True)
_SendMessage(GUICtrlGetHandle($idSourceSel), $BM_SETIMAGE, 0, $hSelFolderIcon)
GUICtrlSetTip(-1, 'Quellverzeichnis auswählen...')
GUICtrlSetOnEvent(-1, '_SelFolder')

Global $hArrow = _Load_BMP_From_Mem(_Arrow(), True)
Global $idStart = GUICtrlCreateButton('', 20, 80, 80, 122, $BS_BITMAP)
GUICtrlSetTip(-1, 'Synchronisierung starten...')
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, '_Start')
_SendMessage(GUICtrlGetHandle($idStart), $BM_SETIMAGE, 0, $hArrow)

GUICtrlCreateGroup('Wichtiger Hinweis!', 110, 80, 530, 120)
Global $sMsg = 'Alle Dateien/Verzeichnisse, die im Zielverzeichnis vorhanden sind,\rim Quellverzeichnis aber nicht (mehr), werden im Zielverzeichnis gelöscht!\r\r'
$sMsg &= 'Das Zielverzeichnis sollte also bei der ersten Benutzung leer sein!\rBei der Verzeichnisauswahl kann ein leeres Verzeichnis erstellt werden.'
$idMsg = GUICtrlCreateLabel(StringFormat($sMsg), 120, 100, 510, 90)
GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
GUICtrlCreateGroup('', -99, -99, 1, 1)

GUICtrlCreateGroup('Zielverzeichnis (Achtung! Dieses Verzeichnis wird an das Quellverzeichnis angepasst.)', 10, 210, 630, 56)
Global $idDestPath = GUICtrlCreateInput($sDestPath, 20, 232, 560, 22, BitOR($ES_READONLY, $ES_LEFT, $ES_AUTOHSCROLL))
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlCreateGroup('', -99, -99, 1, 1)
Global $idDestSel = GUICtrlCreateButton('', 590, 222, 40, 40, $BS_BITMAP)
_SendMessage(GUICtrlGetHandle($idDestSel), $BM_SETIMAGE, 0, $hSelFolderIcon)
GUICtrlSetTip(-1, 'Zielverzeichnis auswählen...')
GUICtrlSetOnEvent(-1, '_SelFolder')
GUICtrlCreateGroup('Option beim Test auf Dateigleichheit', 10, 274, 630, 46)
Global $idChecksum = GUICtrlCreateCheckbox('Datei-Inhalt berücksichtigen (dauert wesentlich länger beim erstellen der Kopierliste!)', 25, 290, 600, 25)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup('Profil-Auswahl', 10, 340, 630, 52)
Global $idProfile = GUICtrlCreateCombo('', 20, 359, 530, 20)
GUICtrlSetTip(-1, 'Um ein neues Profil anzulegen, einfach einen noch nicht existierenden Namen eintragen und speichern anklicken.')
GUICtrlSetOnEvent(-1, '_LoadProfile')
GUICtrlCreateButton('', 566, 358, 32, 26, $BS_ICON)
GUICtrlSetImage(-1, 'shell32.dll', -6, 0)
GUICtrlSetTip(-1, 'Profil speichern')
GUICtrlSetOnEvent(-1, '_SaveProfile')
GUICtrlCreateButton('', 600, 358, 32, 26, $BS_ICON)
GUICtrlSetImage(-1, 'shell32.dll', -132, 0)
GUICtrlSetTip(-1, 'Profil löschen')
GUICtrlSetOnEvent(-1, '_DelProfile')
GUICtrlCreateGroup('', -99, -99, 1, 1)

GUICtrlSetData($idProfile, $sProfileNames)

Global $hStatus = _GUICtrlStatusBar_Create($hGui)
Global $hCopyIcon = _WinAPI_LoadShell32Icon(137)
Global $hStopIcon = _WinAPI_LoadShell32Icon(237)
Global $hInfoIcon = _WinAPI_LoadShell32Icon(221)
_GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon)
_GUICtrlStatusBar_SetText($hStatus, 'Quellverzeichnis auswählen!')

Global $hCopyGui = GUICreate('Kopier- und Löschliste', 700, 285, -1, -1, $WS_CAPTION, Default, $hGui)
GUISetFont(9, 400, 2, 'Verdana')
GUISetBkColor(0xFF9966)
GUICtrlCreateGroup('Kopierliste (Quelle -> Ziel)', 5, 10, 340, 240)
Global $idCopyList = GUICtrlCreateListView('Pfad', 15, 30, 320, 210)
GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
Global $hCopyList = GUICtrlGetHandle($idCopyList)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup('Löschliste (Zielverzeichnis)', 355, 10, 340, 240)
Global $idDelList = GUICtrlCreateListView('Pfad', 365, 30, 320, 210)
GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
Global $hDelList = GUICtrlGetHandle($idDelList)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateLabel('Soll der Vorgang, wie oben aufgelistet, ausgeführt werden?', 10, 260, 450, 24)
GUICtrlSetFont(-1, 10, 400, 2, 'Verdana')
Global $idContinue = GUICtrlCreateButton('Ausführen', 480, 256, 110, 24)
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
Global $idCancel = GUICtrlCreateButton('Abbrechen', 600, 256, 90, 24)
GUICtrlSetFont(-1, 10, 400, 0, 'Arial')

_Crypt_Startup()
GUISetState(@SW_SHOW, $hGui)
WinWaitClose($hGui)
Exit

Func _Close()
	_Crypt_Shutdown()
	_WinAPI_DeleteObject($hArrow)
	_WinAPI_DeleteObject($hSelFolderIcon)
	_WinAPI_DestroyIcon($hCopyIcon)
	_WinAPI_DestroyIcon($hStopIcon)
	_WinAPI_DestroyIcon($hInfoIcon)
	DllClose($hKernel32Dll)
	DllClose($hUser32Dll)
	GUIDelete($hGui)
EndFunc   ;==>_Close

Func _SaveProfile()
	Local $sSection
	$sSection = GUICtrlRead($idProfile)
	If $sSection = '' Then Return
	IniWriteSection($sInifile, $sSection, StringFormat('Source=%s\nDest=%s', $sSourcePath, $sDestPath))
	GUICtrlSetData($idProfile, $sSection)
EndFunc

Func _LoadProfile()
	Local $sSection, $aPath
	$sSection = GUICtrlRead($idProfile)
	$aPath = IniReadSection($sInifile, $sSection)
	If @error Then Return
	$sSourcePath = $aPath[1][1]
	$sDestPath = $aPath[2][1]
	GUICtrlSetData($idSourcePath, $sSourcePath)
	GUICtrlSetData($idDestPath, $sDestPath)
	_CheckFolder()
EndFunc

Func _DelProfile()
	Local $sSection, $iOccurrence
	$sSection = GUICtrlRead($idProfile)
	If $sSection = '' Then Return
	IniDelete($sInifile, $sSection)
	$iOccurrence = ControlCommand($hGui, '', $idProfile, 'FindString', $sSection)
	ControlCommand($hGui, '', $idProfile, 'DelString', $iOccurrence)
EndFunc

Func _Start()
	GUICtrlSetState($idStart, $GUI_DISABLE)
	Sleep(200)
	Local $sMsg, $sSourceList, $aSourceList, $sDestList, $aDestList, $aDirList, $aFileTime[3], $sTmp
	$sMsg = 'Das Zielverzeichnis ist das Hauptverzeichnis einer Festplatte!\rSoll wirklich das Hauptverzeichnis angepasst werden?'
	If StringRegExp($sDestPath, '(?i)[a-z]:\\\z|\\.+\\[a-z]\\\z') Then
		If MsgBox(4 + 48 + 256, $sTitle, StringFormat($sMsg), 0, $hGui) = 7 Then Return GUICtrlSetState($idStart, $GUI_ENABLE)
	EndIf
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
	_GUICtrlStatusBar_SetText($hStatus, 'Schritt 1: Datei- und Verzeichnisliste werden erstellt. Bitte warten!')
	$iCopyCount = 0
	$iFileCount = 0
	$sCreateDirList = ''
	$sSourceList = _GetCopyList($sSourcePath)
	Switch @error
		Case 1
			_SetError('Fehler! Das Quellverzeichnis ist leer.', 0)
			GUICtrlSetState($idStart, $GUI_ENABLE)
			Return
		Case 2
			_SetError('Fehler! Das erstellen der Dateiliste wurde abgebrochen.', 0)
			GUICtrlSetState($idStart, $GUI_ENABLE)
			Return
	EndSwitch
	$aSourceList = StringSplit(StringTrimRight($sSourceList, 1), @CR)
	_GUICtrlListView_DeleteAllItems($hCopyList)
	_GUICtrlListView_DeleteAllItems($hDelList)
	_GUICtrlListView_BeginUpdate($hCopyList)
	For $i = 1 To $aSourceList[0]
		GUICtrlCreateListViewItem($aSourceList[$i], $idCopyList)
	Next
	_GUICtrlListView_EndUpdate($hCopyList)
	If $iCopyCount > 0 Then
		_GUICtrlListView_SetColumnWidth($hCopyList, 0, $LVSCW_AUTOSIZE)
	Else
		_GUICtrlListView_SetColumnWidth($hCopyList, 0, $LVSCW_AUTOSIZE_USEHEADER)
	EndIf
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
	_GUICtrlStatusBar_SetText($hStatus, 'Schritt 2: Löschliste wird erstellt. Bitte warten!')
	$iDelCount = 0
	$sDestList = _GetDelList($sDestPath)
	If @error = 2 Then
		_SetError('Fehler! Das erstellen der Löschliste wurde abgebrochen.', 0)
		GUICtrlSetState($idStart, $GUI_ENABLE)
		Return
	EndIf
	$aDestList = StringSplit(StringTrimRight($sDestList, 1), @CR)
	_GUICtrlListView_BeginUpdate($hDelList)
	For $i = 1 To $aDestList[0]
		GUICtrlCreateListViewItem($aDestList[$i], $idDelList)
	Next
	_GUICtrlListView_EndUpdate($hDelList)
	If $iDelCount > 0 Then
		_GUICtrlListView_SetColumnWidth($hDelList, 0, $LVSCW_AUTOSIZE)
	Else
		_GUICtrlListView_SetColumnWidth($hDelList, 0, $LVSCW_AUTOSIZE_USEHEADER)
	EndIf
	If $iCopyCount = 0 And $iDelCount = 0 And $sCreateDirList = '' Then
		_PlayDefaultSystemSound('SystemExclamation')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
		_GUICtrlStatusBar_SetText($hStatus, 'Quell- und Zielverzeichnis sind identisch!')
		GUICtrlSetState($idStart, $GUI_ENABLE)
		Return
	EndIf
	GUICtrlSetState($idCancel, $GUI_FOCUS)
	GUISetState(@SW_SHOW, $hCopyGui)
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
	_GUICtrlStatusBar_SetText($hStatus, 'Schritt 2: Listen wurden erstellt! Warte auf Bestätigung...')
	_PlayDefaultSystemSound('SystemExclamation')
	Opt('GUIOnEventMode', 0)
	Do
		$sMsg = GUIGetMsg()
	Until $sMsg = $idContinue Or $sMsg = $idCancel
	GUISetState(@SW_HIDE, $hCopyGui)
	Opt('GUIOnEventMode', 1)
	If $sMsg = $idContinue Then
		If $iCopyCount > 0 Then
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
			_GUICtrlStatusBar_SetText($hStatus, 'Schritt 3: Kopiervorgang läuft...Bitte warten!')
			_MFC_CopyFileArray($aSourceList, $sDestPath, $sSourcePath, 'Kopiervorgang...', $hGui)
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
		EndIf
		If $iDelCount > 0 Then
			_GUICtrlStatusBar_SetText($hStatus, 'Schritt 4: Löschvorgang läuft...Bitte warten!')
			For $i = 1 To $aDestList[0]
				$sMsg = FileGetAttrib($aDestList[$i])
				If StringInStr($sMsg, 'D') Then
					If Not DirRemove($aDestList[$i], 1) Then
						_SetError(StringFormat('Fehler! Verzeichnis "%s" konnte nicht gelöscht werden', $aDestList[$i]), 0)
						GUICtrlSetState($idStart, $GUI_ENABLE)
						Return
					EndIf
				Else
					If Not FileDelete($aDestList[$i]) Then
						_SetError(StringFormat('Fehler! Datei "%s" konnte nicht gelöscht werden', $aDestList[$i]), 0)
						GUICtrlSetState($idStart, $GUI_ENABLE)
						Return
					EndIf
				EndIf
			Next
		EndIf
		If $sCreateDirList <> '' Then
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
			_GUICtrlStatusBar_SetText($hStatus, 'Schritt 5: Verzeichnisse werden erstellt...Bitte warten!')
			$aDirList = StringSplit(StringTrimRight($sCreateDirList, 1), @CR)
			For $i = 1 To $aDirList[0]
				$sTmp = StringReplace($aDirList[$i], $sDestPath, $sSourcePath)
				For $j = 0 To 2
					$aFileTime[$j] = FileGetTime(StringTrimRight($sTmp, 1), $j, 1)
				Next
				If Not FileExists($aDirList[$i]) Then
					If Not DirCreate($aDirList[$i]) Then
						_SetError('Fehler! Verzeichnis konnte nicht erstellt werden.', 0)
						GUICtrlSetState($idStart, $GUI_ENABLE)
						Return
					EndIf
				EndIf
				For $j = 0 To 2
					FileSetTime(StringTrimRight($aDirList[$i], 1), $aFileTime[$j], $j)
				Next
			Next
		EndIf
		_PlayDefaultSystemSound('SystemExclamation')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
		_GUICtrlStatusBar_SetText($hStatus, 'Vorgang erfolgreich beendet!')
	Else
		_SetError('Kopiervorgang abgebrochen!', 0)
	EndIf
	GUICtrlSetState($idStart, $GUI_ENABLE)
EndFunc   ;==>_Start

Func _MFC_CopyFileArray(ByRef $aCopyFiles, $sDestDir, $sSourceDir = '', $sTitle = 'MultiFileCopy', $hParent = '')
	If Not IsArray($aCopyFiles) Then Return SetError(1, 0, 0)
	If Not IsNumber($aCopyFiles[0]) Or $aCopyFiles[0] < 1 Then Return SetError(2, 0, 0)
	If StringRight($sDestDir, 1) <> '\' Then $sDestDir &= '\'
	If Not FileExists($sDestDir) Then Return SetError(3, 0, 0)
	If $sSourceDir <> '' Then
		If StringRight($sSourceDir, 1) <> '\' Then $sSourceDir &= '\'
		If Not FileExists($sSourceDir) Then Return SetError(4, 0, 0)
	EndIf
	Local $aMFCGui = _MFC_GuiCreate($sTitle, $hParent), $iCopySize = 0, $sDestFile = '', $sRet = '', $aInfo
	_GUICtrlStatusBar_SetText($aMFCGui[8], 'Bereit.')
	For $i = 1 To $aCopyFiles[0]
		$iCopySize += FileGetSize($aCopyFiles[$i])
	Next
	Local $iCopyTimer = TimerInit()
	For $i = 1 To $aCopyFiles[0]
		If $sSourceDir <> '' Then
			$sDestFile = StringReplace($aCopyFiles[$i], $sSourceDir, $sDestDir)
		Else
			$sDestFile = $sDestDir
		EndIf
		GUICtrlSetTip($aMFCGui[1], $aCopyFiles[$i])
		_GuiCtrlSetPath($aMFCGui[1], $aCopyFiles[$i])
		GUICtrlSetTip($aMFCGui[2], $sDestFile)
		_GuiCtrlSetPath($aMFCGui[2], $sDestFile)
		$sRet = _MFC_FileProgressCopy($aMFCGui, $aCopyFiles[$i], $sDestFile, $iCopySize, $iCopyTimer)
		If $sRet <> '' Then
			_GUICtrlStatusBar_SetText($aMFCGui[8], $sRet)
			Do
				$aInfo = GUIGetCursorInfo($aMFCGui[0])
			Until Not $aInfo[2]
			GUICtrlSetData($aMFCGui[7], 'Schliessen')
			Do
				$aInfo = GUIGetCursorInfo($aMFCGui[0])
			Until $aInfo[2] And $aInfo[4] = $aMFCGui[7]
			ExitLoop
		EndIf
	Next
	GUIDelete($aMFCGui[0])
EndFunc   ;==>_MFC_CopyFileArray

Func _MFC_FileProgressCopy(ByRef $aMFCGui, $sSourceFile, $sDestFile, $iCopySize, $iCopyTimer)
	If $sSourceFile = $sDestFile Then Return SetError(1, 0, 'Quelle und Ziel gleich!')
	Local $hSource, $hDest, $sBuffer, $iBufferSize, $iRet, $aInfo, $iTimer
	Local $iFileSize = FileGetSize($sSourceFile), $iBytesTransferred = 0, $aFileTime[3]
	Static Local $iCopyTransferred = 0
	For $i = 0 To 2
		$aFileTime[$i] = FileGetTime($sSourceFile, $i, 1)
	Next
	If $iFileSize < 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
	$hSource = FileOpen($sSourceFile, 16)
	If $hSource = -1 Then Return SetError(2, 0, 'Datei konnte nicht gelesen werden!')
	$hDest = FileOpen($sDestFile, 26)
	If $hDest = -1 Then Return SetError(3, FileClose($hSource), 'Datei konnte nicht erstellt werden!')
	$iTimer = TimerInit()
	Do
		$aInfo = GUIGetCursorInfo($aMFCGui[0])
		If $aInfo[2] And $aInfo[4] = $aMFCGui[7] Then
			FileClose($hSource)
			FileClose($hDest)
			FileDelete($sDestFile)
			Return SetError(4, 0, 'Kopiervorgang abgebrochen!')
		EndIf
		$sBuffer = FileRead($hSource, $iBufferSize)
		$iBytesTransferred += @extended
		$iCopyTransferred += @extended
		If @error Then ExitLoop
		$iRet = FileWrite($hDest, $sBuffer)
		If TimerDiff($iTimer) > 100 Then
			$iTimer = TimerInit()
			_MFC_ShowProgress($aMFCGui, $iFileSize, $iBytesTransferred, $iCopySize, $iCopyTransferred, $iCopyTimer)
		EndIf
	Until $iRet = 0
	_MFC_ShowProgress($aMFCGui, $iFileSize, $iBytesTransferred, $iCopySize, $iCopyTransferred, $iCopyTimer)
	FileClose($hDest)
	FileClose($hSource)
	For $i = 0 To 2
		FileSetTime($sDestFile, $aFileTime[$i], $i)
	Next
	Return SetError(0, 0, '')
EndFunc   ;==>_MFC_FileProgressCopy

Func _MFC_ShowProgress(ByRef $aMFCGui, $iFileSize, $iBytesTransferred, $iCopySize, $iCopyTransferred, $iCopyTimer)
	Local $iPercent, $iMBps, $iEndTime, $iTime = TimerDiff($iCopyTimer)
	$iPercent = Int(100 / $iCopySize * $iCopyTransferred)
	GUICtrlSetData($aMFCGui[5], $iPercent & '%')
	GUICtrlSetData($aMFCGui[6], $iPercent)
	If $iTime < 200 Then Return
	$iPercent = Int(100 / $iFileSize * $iBytesTransferred)
	GUICtrlSetData($aMFCGui[3], $iPercent & '%')
	GUICtrlSetData($aMFCGui[4], $iPercent)
	$iMBps = ($iCopyTransferred / $iTime * 1000) / 1048576
	$iEndTime = ($iCopySize - $iCopyTransferred) / ($iMBps * 1048576)
	GUICtrlSetData($aMFCGui[9], StringFormat('%.2f MB/s,  Zeit: %s,  Restzeit: %s', $iMBps, _TicksToTimeFormat($iTime), _TicksToTimeFormat($iEndTime * 1000)))
EndFunc   ;==>_MFC_ShowProgress

Func _MFC_GuiCreate($sTitle = 'Copy', $hParent = '')
	Local $aCopyGUI[10]
	$aCopyGUI[0] = GUICreate($sTitle, 640, 240, -1, -1, $WS_CAPTION, $WS_EX_TOPMOST, $hParent)
	GUISetFont(10, 400, 2, 'Verdana')
	GUISetBkColor(0xBBBBBB)
	GUICtrlCreateLabel('Kopiere:', 10, 10, 70, 18)
	GUICtrlSetFont(-1, 10, 400, 0, 'Verdana')
	$aCopyGUI[1] = GUICtrlCreateLabel('', 80, 10, 550, 18)
	GUICtrlCreateLabel('Nach:', 10, 40, 70, 16)
	GUICtrlSetFont(-1, 10, 400, 0, 'Verdana')
	$aCopyGUI[2] = GUICtrlCreateLabel('', 80, 40, 550, 18)
	GUICtrlCreateLabel('Datei:', 10, 85, 60, 18)
	GUICtrlSetFont(-1, 10, 400, 0, 'Verdana')
	$aCopyGUI[3] = GUICtrlCreateLabel('0 %', 80, 85, 190, 18)
	$aCopyGUI[4] = GUICtrlCreateProgress(10, 105, 620, 12, $PBS_SMOOTH)
	GUICtrlSetColor(-1, 0x6666AA)
	GUICtrlSetBkColor(-1, 0xDDDDDD)
	DllCall('UxTheme.dll', 'int', 'SetWindowTheme', 'hwnd', GUICtrlGetHandle(-1), 'wstr', '', 'wstr', '')
	GUICtrlCreateLabel('Gesamt:', 10, 130, 60, 18)
	GUICtrlSetFont(-1, 10, 400, 0, 'Verdana')
	$aCopyGUI[5] = GUICtrlCreateLabel('0 %', 80, 130, 190, 18)
	$aCopyGUI[6] = GUICtrlCreateProgress(10, 150, 620, 20, $PBS_SMOOTH)
	GUICtrlSetColor(-1, 0x6666AA)
	GUICtrlSetBkColor(-1, 0xDDDDDD)
	DllCall('UxTheme.dll', 'int', 'SetWindowTheme', 'hwnd', GUICtrlGetHandle(-1), 'wstr', '', 'wstr', '')
	$aCopyGUI[7] = GUICtrlCreateButton('Abbrechen', 270, 185, 90, 25)
	GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
	$aCopyGUI[8] = _GUICtrlStatusBar_Create($aCopyGUI[0])
	$aCopyGUI[9] = GUICtrlCreateLabel('', 180, 130, 450, 18)
	GUISetState()
	Return $aCopyGUI
EndFunc   ;==>_MFC_GuiCreate

;===============================================================================
; Function Name:   _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
; Description::    Diese Funktion wandelt Millisekunden in ein anzugebenes Zeitformat um
; Parameter(s):    $iTicks = Zeit in Millisekunden
;                  $sFormat:
;                            %hh für Stunden
;                            %mm für Minuten
;                            %ss für Sekunden
;                            %ms für Millisekunden
;                            sonstige Zeichen, die dazwischen stehen, werden übernommen
; Requirement(s):  -
; Return Value(s): Zeit im ausgewählten Format (String)
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
	Local $aTime[4] = [0, 0, 0, 0], $sOut, $aFormat, $aTimeFormat[4] = ['hh', 'mm', 'ss', 'ms']
	$aTime[2] = Int($iTicks / 1000)
	$aTime[3] = $iTicks - $aTime[2] * 1000
	$aTime[0] = Int($aTime[2] / 3600)
	$aTime[2] = Mod($aTime[2], 3600)
	$aTime[1] = Int($aTime[2] / 60)
	$aTime[2] = Mod($aTime[2], 60)
	$aFormat = StringRegExp($sFormat, '%([^%]+)', 3)
	If Not IsArray($aFormat) Then Return SetError(1, 0, $iTicks)
	For $i = 0 To UBound($aFormat) - 1
		For $j = 0 To UBound($aTimeFormat) - 1
			If StringLeft($aFormat[$i], 2) = $aTimeFormat[$j] Then $sOut &= StringFormat('%02i', $aTime[$j]) & StringMid($aFormat[$i], 3)
		Next
	Next
	Return $sOut
EndFunc   ;==>_TicksToTimeFormat

Func _GetDelList($sPath)
	Local $hSearch, $sItem, $sReturn = '', $aFileAttr, $sTmp
	Local Static $iTimer = TimerInit()
	$hSearch = FileFindFirstFile($sPath & '*')
	If @error Or $hSearch = -1 Then Return SetError(1, FileClose($hSearch), '')
	While True
		If _IsPressed('1B', $hUser32Dll) Then Return SetError(2, FileClose($hSearch), '') ; wenn Benutzer ESC gedrückt hat, Funktion abbrechen
		If TimerDiff($iTimer) > 50 Then ; Anzeige nur alle 50ms aktualisieren
			$iTimer = TimerInit()
			_GUICtrlStatusBar_SetText($hStatus, StringFormat('Schritt 2: Löschliste wird erstellt. Bitte warten! (%s Einträge vorhanden)', $iDelCount))
		EndIf
		$sItem = FileFindNextFile($hSearch)
		If @error Then ExitLoop
		If @extended Then ; wenn Verzeichnis, dann...
			$aFileAttr = DllCall($hKernel32Dll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sItem) ; Attribute holen
			If @error Or BitAND($aFileAttr[0], $FILE_ATTRIBUTE_REPARSE_POINT) Then ContinueLoop ; wenn Reparse-Point, dann überspringen
			$sTmp = StringReplace($sPath & $sItem & '\', $sDestPath, $sSourcePath)
			If Not FileExists($sTmp) Then
				$iDelCount += 1
				$sReturn &= $sPath & $sItem & '\' & @CR
				ContinueLoop
			EndIf
			$sReturn &= _GetDelList($sPath & $sItem & '\') ; Verzeichnis rekursiv auslesen
			If @error > 1 Then Return SetError(@error, 0, '')
			ContinueLoop
		EndIf
		$sTmp = StringReplace($sPath & $sItem, $sDestPath, $sSourcePath)
		If Not FileExists($sTmp) Then
			$iDelCount += 1
			$sReturn &= $sPath & $sItem & @CR
		EndIf
	WEnd
	FileClose($hSearch)
	Return SetError(0, 0, $sReturn)
EndFunc   ;==>_GetDelList

Func _GetCopyList($sPath)
	Local $hSearch, $sItem, $sReturn = '', $aFileAttr, $sTmp
	Local Static $iTimer = TimerInit()
	$hSearch = FileFindFirstFile($sPath & '*')
	If @error Or $hSearch = -1 Then Return SetError(1, FileClose($hSearch), '')
	While True
		If _IsPressed('1B', $hUser32Dll) Then Return SetError(2, FileClose($hSearch), '') ; wenn Benutzer ESC gedrückt hat, Funktion abbrechen
		If TimerDiff($iTimer) > 50 Then ; Anzeige nur alle 50ms aktualisieren
			$iTimer = TimerInit()
			_GUICtrlStatusBar_SetText($hStatus, StringFormat('Schritt 1: Datei- und Verzeichnisliste werden erstellt. Bitte warten! (%s Dateien vorhanden / %s Dateien zum kopieren)', $iFileCount, $iCopyCount))
		EndIf
		$sItem = FileFindNextFile($hSearch)
		If @error Then ExitLoop
		If @extended Then ; wenn Verzeichnis, dann...
			$aFileAttr = DllCall($hKernel32Dll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sItem) ; Attribute holen
			If @error Or BitAND($aFileAttr[0], $FILE_ATTRIBUTE_REPARSE_POINT) Then ContinueLoop ; wenn Reparse-Point, dann überspringen
			$sTmp = StringReplace($sPath & $sItem & '\', $sSourcePath, $sDestPath) ; Zielverzeichnis zusammenstellen
			If Not FileExists($sTmp) Then $sCreateDirList &= $sTmp & @CR ; wenn es noch nicht existiert, dann in Liste aufnehme
			$sReturn &= _GetCopyList($sPath & $sItem & '\') ; Verzeichnis rekursiv auslesen
			If @error > 1 Then Return SetError(@error, 0, '')
			ContinueLoop
		EndIf
		$iFileCount += 1
		$sTmp = StringReplace($sPath & $sItem, $sSourcePath, $sDestPath)
		If Not FileExists($sTmp) Then
			$iCopyCount += 1
			$sReturn &= $sPath & $sItem & @CR ; Datei existiert noch nicht im Zielverzeichnis -> in CopyList aufnehmen
		Else
			If FileGetSize($sPath & $sItem) <> FileGetSize($sTmp) Then
				$iCopyCount += 1
				$sReturn &= $sPath & $sItem & @CR ; Dateigröße hat sich geändert -> in CopyList aufnehmen
			Else
				If BitAND(GUICtrlRead($idChecksum), $GUI_CHECKED) And _Crypt_HashFile($sPath & $sItem, $CALG_MD4) <> _Crypt_HashFile($sTmp, $CALG_MD4) Then
					$iCopyCount += 1
					$sReturn &= $sPath & $sItem & @CR ; Dateigröße gleich, aber Inhalt geändert -> in CopyList aufnehmen
				EndIf
			EndIf
		EndIf
	WEnd
	FileClose($hSearch)
	Return SetError(0, 0, $sReturn)
EndFunc   ;==>_GetCopyList

Func _SelFolder()
	Local $sPath, $sMsg
	Switch @GUI_CtrlId
		Case $idSourceSel
			$sMsg = 'Quellverzeichnis auswählen...'
			$sPath = $sSourcePath
		Case $idDestSel
			$sMsg = 'Zielverzeichnis auswählen...'
			$sPath = $sDestPath
	EndSwitch
	$sPath = FileSelectFolder($sMsg, '', 3, $sPath, $hGui)
	If @error Then Return
	If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
	Switch @GUI_CtrlId
		Case $idSourceSel
			$sSourcePath = $sPath
			_GuiCtrlSetPath($idSourcePath, $sPath, 8)
		Case $idDestSel
			$sDestPath = $sPath
			_GuiCtrlSetPath($idDestPath, $sPath, 8)
	EndSwitch
	If Not FileExists($sPath) Then Return _SetError('Der Pfad existiert nicht!')
	If $sDestPath = $sSourcePath Then Return _SetError('Quell- und Zielverzeichnis dürfen nicht gleich sein!', 0)
	If StringInStr($sDestPath, $sSourcePath) Then Return _SetError('Das Zielverzeichnis darf kein Unterverzeichnis des Quellverzeichnisses sein!', 0)
	If StringInStr($sSourcePath, $sDestPath) Then Return _SetError('Das Zielverzeichnis darf nicht Teil des Quellverzeichnisses sein!', 0)
	_CheckFolder()
EndFunc   ;==>_SelFolder

Func _CheckFolder()
	If FileExists($sSourcePath) And FileExists($sDestPath) Then
		If BitAND(GUICtrlGetState($idStart), $GUI_DISABLE) Then GUICtrlSetState($idStart, $GUI_ENABLE)
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $hCopyIcon)
		_GUICtrlStatusBar_SetText($hStatus, 'Bereit.')
	Else
		If BitAND(GUICtrlGetState($idStart), $GUI_ENABLE) Then GUICtrlSetState($idStart, $GUI_DISABLE)
		If Not FileExists($sSourcePath) Then
			$sMsg = 'Quell'
		Else
			$sMsg = 'Ziel'
		EndIf
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon)
		_GUICtrlStatusBar_SetText($hStatus, $sMsg & 'verzeichnis auswählen!')
	EndIf
EndFunc

Func _SetError($sMsg, $iSleep = 5000)
	If BitAND(GUICtrlGetState($idStart), $GUI_ENABLE) Then GUICtrlSetState($idStart, $GUI_DISABLE)
	_GUICtrlStatusBar_SetText($hStatus, $sMsg)
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $hStopIcon)
	_PlayDefaultSystemSound('SystemHand')
	If $iSleep > 0 Then AdlibRegister('_EndErrorMsg', $iSleep)
	Return True
EndFunc   ;==>_SetError

Func _EndErrorMsg()
	Local $sMsg
	If Not FileExists($sSourcePath) Then
		$sMsg = 'Quell'
	Else
		$sMsg = 'Ziel'
	EndIf
	AdlibUnRegister('_EndErrorMsg')
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon)
	_GUICtrlStatusBar_SetText($hStatus, $sMsg & 'verzeichnis auswählen!')
EndFunc   ;==>_EndErrorMsg

Func _Arrow()
	Local $sArrow
	$sArrow &= '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'
	$sArrow &= 'XvhU1ACcUjeGRlF1XgDKmWI3ZYCqogDmFHtZ1lLUHACv0VDK4Wgq1ABOmbZC6ZR18QChUDkUCoVDpQAIzistp+w1lQDiw6FWNJ2yNwDUioaTVR7FqwBTTsWLU25F1QDRoag4WW91KAAejk7FzdGtKAAcPxTBefdeVAA+fPRDYZhPBQBrSod//vK1oAD/N7/+z5d8FwAfA/346efDhQCMX78t/f5kBACeslR0/gIaFEBVOrZa3gaBjEkARU5ErkJggg=='
	$sArrow = _Base64Decode($sArrow)
	Local $tSource = DllStructCreate('byte[' & BinaryLen($sArrow) & ']')
	DllStructSetData($tSource, 1, $sArrow)
	Local $tDecompress
	_WinAPI_LZNTDecompress($tSource, $tDecompress)
	$tSource = 0
	Return Binary(DllStructGetData($tDecompress, 1))
EndFunc   ;==>_Arrow

Func _SelFolderpng()
	Local $SelFolderpng
	$SelFolderpng &= 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAFLElEQVR4nI2VW2wcVx3Gf2d2Zm/exZuLU9tJG7uQqlWJ1VIRBQjUCYW2CIQqVKSqSBAEgtK+cHmgSFACQlUleEDiFSGqck1oS1PSojxkrQgi4tKQum7sOm7W8cbexpfd9e7szM78zzk8OEVe20r4ns7o6Hw/fd//6IwqFou8p3uHRp/E9D6EqpZQ06NYXYK4rJQ/W3zja2U20Zc4uEs79hf2ZvvMH2dGXl+/73Z8Sd/DZG7aQ9TfQ+BWyG9/iITts9IQhs4IpjEGrYugZ7GU/+r9aiwxZX+EZW84pn766KA98rulkbNrLVVHgg/GU6jlATI9EOky1ZGjdPftx+vvw92ag4yL47qYSPz0hXOfKR/2p2e51VVcdbdhGpcwJscPjsXFc+95Op2BrGANqJZLdscA2+8/TPVykdbZM0QzTaKZkKgiUbo59ZHm4elShd1eknfdfmqpnZQKn6DiNDnyRX947+YAa64tDBBB197tbP3sIyN/evo1Fl99Fl1bIHfh5KHl+67U32GfSnPF62cx1cfyzdmBLfvTB3ZvOcC8xPz4c+8M79kkgYn/t9TzQBJUyvUDlV2c/v002ed/c/DKd7vmFtjtZZjO7GIh1efUbvPu7NvKjkJEK3x/diCfvxPfzfKzL7xxcFfnkK0RVMeIwIpoY716VWU/efmVQ3XDbY5h1jjkZYmuuwp3ewkSrFCrTbXfrvjn6dEBacchFWfsTzoBaOkE1sGEgQhuINY7731liuTOAMdxp3uPnj40OfGwhxfOU65U2uVa4zy99XHKL99a/A47gB0bZ9AJMFWwOrTgxjEei0fHsK0mOmBMJmOVoF7i7dJcrexHc3S35+hKtRO/XGvRCTDrE0RgBDROHKukjnyFbYNpNE9XbD8QLiwu27hCdzDDlmiRfy//2VxZa3GDitqCbYfa4GqNG8QqmWuNXproHl36S5UHUikaep5Cu05mpYzbathjp54a6fBYV9EagI0F0wQTC4qEsbjtGLduRpe+PcPHTYiWKtm4Sj6Yx2sv8ULy3a5J1mnzimwsmFDQvmBELLhicVuRzXx1gQNjim4vIiEr5FoLqI96jDWm4udOPHiifX0AIiCr5uIL0YJgw9Ba3LG8fd9jBT40mqKQEqxfIRNU4J40r72475s593vfGF5vvklFImgB8a8BKov4429acOcyZC7GZGmQiCu4BxSVf93DmRNDQ9uwwe2o/NeHC0cKN0igBRutmutGSJy5cPbvP69YReLBq7ReXmZ8PMk/Zm5RZ44N9gWD6mP7iQoD3PT0h3FSaZPdNXh9gI4FE4FuhKsQt3a+xL0JB5VwUE6CRFtIx5FNkij0IksheilcfcNigdaGijY+FUYE6ws6EKwRbYkxCA7WGhxrUG1DIml9QWkwnouygjZCvMF/HcDUymhbQbXS2FAgFgU5FJFSaKWIFVgFoNqCwcURMW7juGN1GrwNgI6KlG4/i1Gj2Pa16yoS+tRjITAabS2pGJKxwUUBjgKluP+3d5xDiSCBXBdQnPv0BJF+AZu7tArQ8p8JLk1e4OLlaabaV5l0QzWTT6k5ErekURZsxMl9t99NGDed6ktT168IUPMTJ+3OOz6FF/RSOztab1KoNqn8c5zZbd3Uvv9l4p7+z+8hyGfw7hpEXxZM4biqHj9d5FR4Q0CRbzWJ/vYHnGzhrddfOhcJQxZb8m1y8ofPnKyvACMrXAReGebx3OqZJ5tFHtvQP6z76a/VcM9zHzj4xK9LlMhRovnUqVMb+v1/9F9dEd4SY6ZINwAAAABJRU5ErkJggg=='
	Return Binary(_Base64Decode($SelFolderpng))
EndFunc   ;==>_SelFolderpng

Func _Base64Decode($input_string)
	Local $struct = DllStructCreate("int")
	Local $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", 0, "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
	If @error Or Not $a_Call[0] Then Return SetError(1, 0, "")
	Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")
	$a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", "str", $input_string, "int", 0, "int", 1, "ptr", DllStructGetPtr($a), "ptr", DllStructGetPtr($struct, 1), "ptr", 0, "ptr", 0)
	If @error Or Not $a_Call[0] Then Return SetError(2, 0, "")
	Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Decode

Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize = 0x800000)
	Local $tBuffer, $Ret
	$tOutput = 0
	$tBuffer = DllStructCreate('byte[' & $iBufferSize & ']')
	If @error Then Return SetError(1, 0, 0)
	$Ret = DllCall('ntdll.dll', 'uint', 'RtlDecompressBuffer', 'ushort', 0x0002, 'ptr', DllStructGetPtr($tBuffer), 'ulong', $iBufferSize, 'ptr', DllStructGetPtr($tInput), 'ulong', DllStructGetSize($tInput), 'ulong*', 0)
	If @error Then Return SetError(2, 0, 0)
	If $Ret[0] Then Return SetError(3, $Ret[0], 0)
	$tOutput = DllStructCreate('byte[' & $Ret[6] & ']')
	If Not _WinAPI_MoveMemory(DllStructGetPtr($tOutput), DllStructGetPtr($tBuffer), $Ret[6]) Then
		$tOutput = 0
		Return SetError(4, 0, 0)
	EndIf
	Return $Ret[6]
EndFunc   ;==>_WinAPI_LZNTDecompress

Func _WinAPI_MoveMemory($pDestination, $pSource, $iLenght)
	DllCall('ntdll.dll', 'none', 'RtlMoveMemory', 'ptr', $pDestination, 'ptr', $pSource, 'ulong_ptr', $iLenght)
	If @error Then Return SetError(5, 0, 0)
	Return 1
EndFunc   ;==>_WinAPI_MoveMemory

;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:            Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:            $bImage:        the binary string which contains any valid image which is supported by GDI+
; Optional:                  $hHBITMAP:        if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:                    hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format
;
; Requirement(s):        GDIPlus.au3, Memory.au3
; Return Value(s):    Success: handle to bitmap or hbitmap, Error: 0
; Error codes:            1: $bImage is not a binary string
;
; Author(s):                UEZ
; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines
; Version:                    v0.95 Build 2011-06-14 Beta
;=======================================================================================
Func _Load_BMP_From_Mem($bImage, $hHBITMAP = False)
	If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
	Local $declared = True
	If Not $ghGDIPDll Then
		_GDIPlus_Startup()
		$declared = False
	EndIf
	Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary
	Local Const $len = BinaryLen($memBitmap) ;get length of image
	Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
	Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
	Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
	DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
	_MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
	Local $hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0)
	$hStream = $hStream[3]
	Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
	$hBitmap = $hBitmap[2]
	Local Const $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
	DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
			"dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
	$tMem = 0
	If $hHBITMAP Then
		Local Const $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
		_GDIPlus_BitmapDispose($hBitmap)
		If Not $declared Then _GDIPlus_Shutdown()
		Return $hHBmp
	EndIf
	If Not $declared Then _GDIPlus_Shutdown()
	Return $hBitmap
EndFunc   ;==>_Load_BMP_From_Mem

; #FUNCTION# ====================================================================================================================
; Name...........:    _PlayDefaultSystemSound()
; Description ...:    Spielt einen Systemklang, welcher in der Registry definiert ist.
; Syntax.........:    _PlayDefaultSystemSound($sSoundName, $iWait = 0)
; Parameters ....:    $sSoundName                - Name des SystemSound's
;                    | Default                   - Standardton Warnsignal / Default Beep
;                    | CriticalBatteryAlarm      - Alarm bei kritischem Batteriestand / when battery is critical
;                    | DeviceConnect            - Geräteanschluß / when a device is connect
;                    | DeviceDisconnect          - Gerätetrennung / when a device is disconnect
;                    | DeviceFail                - Geräteanschluß fehlgeschlagen / when a deviceconnect is fail
;                    | LowBatteryAlarm           - Alarm bei niedrigem Batteriestand / when battery is low
;                    | MailBeep                  - Posteingangsbenachrichtigung / when email is received
;                    | SystemAsterisk            - Stern / Asterisk
;                    | SystemExclamation         - Hinweis / when windows shows a warning
;                    | SystemExit                - Windows beenden / when Windows shuts down
;                    | SystemHand                - Kritischer Abbruch / when a critical stop occurs
;                    | SystemNotification        - Sprechblase / when a critical stop occurs
;                    | SystemStart               - Windows starten / when Windows starts up
;                    | WindowsLogoff             - beim Windows abmelden / when logging off Windows
;                    | WindowsLogon              - beim Windows anmelden / when logging on Windows
;                    | EmptyRecycleBin           - Löschen des Papierkorbs / when recycle bin is emptied
;                    | Navigating                - Browser Klick / navigating in browser

;                     $iWait                     - Warten bis SoundPlay beendet? (0 = nein / 1 = ja)
; Return values .:    -----
; Author ........:    funkey (AutoIt.de)
; ===============================================================================================================================
Func _PlayDefaultSystemSound($sSoundName, $iWait = 0) ; funkey
	Local $sKey = 'HKEY_CURRENT_USER\AppEvents\Schemes\Apps\.Default'
	If $sSoundName = 'EmptyRecycleBin' Or $sSoundName = 'Navigating' Then $sKey = 'HKEY_CURRENT_USER\AppEvents\Schemes\Apps\Explorer'
	Local $sFile = StringReplace(RegRead($sKey & '\' & $sSoundName & '\.Default', ''), '%SystemRoot%', @WindowsDir)
	If $sFile = "" Then
		SoundPlay(StringReplace(RegRead($sKey & '\.Default\.Default', ''), '%SystemRoot%', @WindowsDir), $iWait)
	Else
		SoundPlay($sFile, $iWait)
	EndIf
EndFunc   ;==>_PlayDefaultSystemSound

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