#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=icons\Program.ico
#AutoIt3Wrapper_Outfile=FileCommander.exe
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Description=FileCommander
#AutoIt3Wrapper_Res_Fileversion=1.3.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Oscar (www.autoit.de)
#AutoIt3Wrapper_Res_Language=1031
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#NoTrayIcon

#include <Array.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <File.au3>
#include <FileConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiStatusBar.au3>
#include <ListBoxConstants.au3>
#include <ListViewConstants.au3>
#include <Misc.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Opt('GUIOnEventMode', 1)
Opt('GUICloseOnESC', 0)
Opt('MustDeclareVars', 1)
Opt('GUIResizeMode', $GUI_DOCKAUTO)

Global $sTitle = 'FileCommander'
Global $sVersion = '1.3.0.0'
Global $sDate = '11.12.2010'
ConsoleWrite(@AppDataDir & @CRLF)
Global $sAppDir = @AppDataDir & '\FileCommander\'
If Not FileExists($sAppDir) Then DirCreate($sAppDir)
Global $sIniFile = $sAppDir & 'FileCommander.ini'
Global $sScriptDir = @ScriptDir
If StringRight($sScriptDir, 1) <> '\' Then $sScriptDir &= '\'
Global $sIconDir = $sScriptDir & 'icons\'
Global $sLogfile = $sAppDir & 'FileCommander.log'
Global $fLogfile = Execute(IniRead($sIniFile, 'Config', 'Logfile', False))
Global $fMaximized = Execute(IniRead($sIniFile, 'Config', 'Maximized', False))
Global $iWidth = IniRead($sIniFile, 'Config', 'Width', 700)
Global $iHeight = IniRead($sIniFile, 'Config', 'Height', 502)
Global $iX = IniRead($sIniFile, 'Config', 'X', @DesktopWidth / 2 - 350)
Global $iY = IniRead($sIniFile, 'Config', 'Y', @DesktopHeight / 2 - 251)
Global $aColWidth[5], $aSize[5] = [100, 60, 60, 100, 40]
For $i = 0 To 4
	$aColWidth[$i] = IniRead($sIniFile, 'Config', 'LVCol' & $i, $aSize[$i])
Next
Global $sColOrder = IniRead($sIniFile, 'Config', 'ColOrder', '0|1|2|3|4')
Global $aPath[2] = [IniRead($sIniFile, 'Config', 'LeftPath', 'C:\'), IniRead($sIniFile, 'Config', 'RightPath', 'C:\')]
Global $aDirList = IniReadSection($sIniFile, 'DirList')
If Not IsArray($aDirList) Then Global $aDirList[1][2] = [[0, '']]

Global $sIniVersion = IniRead($sIniFile, 'Program', 'Version', '0.0.0.0')
If $sIniVersion < '1.3.0.0' Then ; update from old Inifile
	FileDelete($sIniFile)
	IniWrite($sIniFile, 'Program', 'Version', $sVersion)
	IniWrite($sIniFile, 'Config', 'X', $iX)
	IniWrite($sIniFile, 'Config', 'Y', $iY)
	IniWrite($sIniFile, 'Config', 'Width', $iWidth)
	IniWrite($sIniFile, 'Config', 'Height', $iHeight)
	IniWrite($sIniFile, 'Config', 'Maximized', $fMaximized)
	For $i = 0 To 4
		IniWrite($sIniFile, 'Config', 'LVCol' & $i, $aColWidth[$i])
	Next
	IniWrite($sIniFile, 'Config', 'ColOrder', $sColOrder)
	IniWrite($sIniFile, 'Config', 'Logfile', $fLogfile)
	IniWrite($sIniFile, 'Config', 'LeftPath', $aPath[0])
	IniWrite($sIniFile, 'Config', 'RightPath', $aPath[1])
EndIf

Global $aColorActive[2] = [0x005599, 0xFFFF22], $aColorInactive[2] = [0xEEEEEE, 0x000000]
Global $sHeader = 'Name|Erw.|Größe|Datum|Attr.', $aHeader = StringSplit($sHeader, '|', 2)
Global $aDrives, $ahDriveButtons, $ahDriveIcon[2], $ahLabel[2], $ahPath[2], $ahDirList[2], $ahReload[2], $ahUp[2], $ahLV[2], $ahInfo[2], $ahContextMenu[2]
Global $iActiveLV = 0, $fCancel = False, $sOldSelItems = '|'

Global Const $tagSHFILEINFO = 'dword hIcon; int iIcon; DWORD dwAttributes; CHAR szDisplayName[255]; CHAR szTypeName[80];'
Global Const $SHGFI_USEFILEATTRIBUTES = 0x10
Global Const $SHGFI_SYSICONINDEX = 0x4000
Global Const $SHGFI_SMALLICON = 0x1
Global Const $SHGFI_LARGEICON = 0x0
Global $FOLDER_ICON_INDEX = _GUIImageList_GetFileIconIndex(@SystemDir, 0, 1)
Global $UP_ICON_INDEX = _GUIImageList_GetFileIconIndex($sIconDir & 'up.ico', 0, 1)

; Main-Gui
Global $hGui = GUICreate($sTitle & '   v' & StringLeft($sVersion, 3), 700, 502, $iX, $iY, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
GUISetBkColor(0xC0C0C0)
GUISetFont(10, 400, 0, 'Tahoma', $hGui, 5)
GUISetIcon($sIconDir & 'program.ico', 0)

Global $hFileMenu = GUICtrlCreateMenu('Datei')
GUICtrlCreateMenuItem('Programm beenden', $hFileMenu)
GUICtrlSetOnEvent(-1, '_End')
Global $hEditMenu = GUICtrlCreateMenu('Markieren')
GUICtrlCreateMenuItem('Alles markieren', $hEditMenu)
GUICtrlSetOnEvent(-1, '_MarkAll')
GUICtrlCreateMenuItem('Nichts markieren', $hEditMenu)
GUICtrlSetOnEvent(-1, '_MarkNothing')
GUICtrlCreateMenuItem('Alle Verzeichnisse markieren', $hEditMenu)
GUICtrlSetOnEvent(-1, '_MarkDirs')
GUICtrlCreateMenuItem('Größe der markierten Verzeichnisse einlesen', $hEditMenu)
GUICtrlSetOnEvent(-1, '_ReadMarkDirSize')
GUICtrlCreateMenuItem('Größe aller Verzeichnisse einlesen', $hEditMenu)
GUICtrlSetOnEvent(-1, '_ReadAllDirSize')
GUICtrlCreateMenuItem('Alle Dateien markieren', $hEditMenu)
GUICtrlSetOnEvent(-1, '_MarkFiles')
GUICtrlCreateMenuItem('Alle Dateien mit der gleichen Endung markieren', $hEditMenu)
GUICtrlSetOnEvent(-1, '_MarkSameExt')
Global $hConfigMenu = GUICtrlCreateMenu('Einstellungen')
GUICtrlCreateMenuItem('Spaltenreihenfolge ändern...', $hConfigMenu)
GUICtrlSetOnEvent(-1, '_ChangeColOrder')
Global $hLogfile = GUICtrlCreateMenuItem('Kopier-/Löschvorgänge in Logdatei schreiben', $hConfigMenu)
GUICtrlSetOnEvent(-1, '_SwitchLogfile')
If $fLogfile Then GUICtrlSetState(-1, $GUI_CHECKED)
Global $hHelpMenu = GUICtrlCreateMenu('?')
GUICtrlCreateMenuItem('Programm-Informationen', $hHelpMenu)
GUICtrlSetOnEvent(-1, '_ProgInfo')
GUICtrlCreateMenuItem('Danksagungen', $hHelpMenu)
GUICtrlSetOnEvent(-1, '_Thanks')

_CreateDriveButtons()

$ahDriveIcon[0] = GUICtrlCreateButton('', 2, 27, 42, 42, BitOR($BS_VCENTER, $BS_ICON))
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahLabel[0] = GUICtrlCreateLabel('', 46, 27, 303, 18)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahPath[0] = GUICtrlCreateInput('', 46, 46, 236, 22, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahDirList[0] = GUICtrlCreateButton('', 283, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'fav.ico', 1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_OpenDirList')
GUICtrlSetTip(-1, 'Verzeichnisliste (Favoriten)' & @CR & 'Linke Maustaste = Liste anzeigen' & @CR & 'Rechte Maustaste = Liste bearbeiten')
Global $hContext = GUICtrlCreateContextMenu($ahDirList[0])
GUICtrlCreateMenuItem('Aktuelles Verzeichnis hinzufügen', $hContext)
GUICtrlSetOnEvent(-1, '_AddDirToFav')
GUICtrlCreateMenuItem('Verzeichnisliste bearbeiten', $hContext)
GUICtrlSetOnEvent(-1, '_ShowEditGui')

$ahReload[0] = GUICtrlCreateButton('', 305, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'refresh.ico', -1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_ReloadLeftLV')
GUICtrlSetTip(-1, 'Verzeichnis neu einlesen')

$ahUp[0] = GUICtrlCreateButton('', 327, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'up.ico', 1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_LVLeftUp')
GUICtrlSetTip(-1, 'Eine Verzeichnisebene nach oben wechseln')

$ahLV[0] = GUICtrlCreateListView($sHeader, 2, 70, 347, 326, $LVS_SHOWSELALWAYS, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_FULLROWSELECT, $LVS_EX_HEADERDRAGDROP))
GUICtrlSetOnEvent(-1, '_SortLV')
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKTOP)
_CreateContextMenu($ahLV[0], 0)

$ahInfo[0] = GUICtrlCreateLabel('', 2, 397, 347, 20, Default, $WS_EX_CLIENTEDGE)
GUICtrlSetBkColor(-1, 0xFFFFAA)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

$ahDriveIcon[1] = GUICtrlCreateButton('', 350, 27, 42, 42, BitOR($BS_VCENTER, $BS_ICON))
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahLabel[1] = GUICtrlCreateLabel('', 394, 27, 303, 18, Default)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahPath[1] = GUICtrlCreateInput('', 394, 46, 236, 22, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

$ahDirList[1] = GUICtrlCreateButton('', 631, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'fav.ico', 1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_OpenDirList')
GUICtrlSetTip(-1, 'Verzeichnisliste (Favoriten)' & @CR & 'Linke Maustaste = Liste anzeigen' & @CR & 'Rechte Maustaste = Liste bearbeiten')
Global $hContext = GUICtrlCreateContextMenu($ahDirList[1])
GUICtrlCreateMenuItem('Aktuelles Verzeichnis hinzufügen', $hContext)
GUICtrlSetOnEvent(-1, '_AddDirToFav')
GUICtrlCreateMenuItem('Verzeichnisliste bearbeiten', $hContext)
GUICtrlSetOnEvent(-1, '_ShowEditGui')

$ahReload[1] = GUICtrlCreateButton('', 653, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'Refresh.ico', -1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_ReloadRightLV')
GUICtrlSetTip(-1, 'Verzeichnis neu einlesen')

$ahUp[0] = GUICtrlCreateButton('', 675, 46, 22, 22, $BS_ICON)
GUICtrlSetImage(-1, $sIconDir & 'up.ico', 1, 0)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_LVRightUp')
GUICtrlSetTip(-1, 'Eine Verzeichnisebene nach oben wechseln')

$ahLV[1] = GUICtrlCreateListView($sHeader, 350, 70, 347, 326, $LVS_SHOWSELALWAYS, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_FULLROWSELECT, $LVS_EX_HEADERDRAGDROP))
GUICtrlSetOnEvent(-1, '_SortLV')
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKTOP)
_CreateContextMenu($ahLV[1], 1)

$ahInfo[1] = GUICtrlCreateLabel('', 350, 397, 347, 20, Default, $WS_EX_CLIENTEDGE)
GUICtrlSetBkColor(-1, 0xFFFFAA)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

For $i = 0 To 4
	_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($ahLV[0]), $i, $aColWidth[$i])
	_GUICtrlListView_SetColumnWidth(GUICtrlGetHandle($ahLV[1]), $i, $aColWidth[$i])
Next
_GUICtrlListView_JustifyColumn($ahLV[0], 2, 1)
_GUICtrlListView_JustifyColumn($ahLV[1], 2, 1)
_GUICtrlListView_SetColumnOrder($ahLV[0], $sColOrder)
_GUICtrlListView_SetColumnOrder($ahLV[1], $sColOrder)

_GUICtrlListView_SetImageList($ahLV[0], _GUIImageList_GetSystemImageList(), 1)
_GUICtrlListView_SetImageList($ahLV[1], _GUIImageList_GetSystemImageList(), 1)

Global $hChangeAttr = GUICtrlCreateButton('&Attr. ändern', 0, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_ChangeAttr')

Global $hRename = GUICtrlCreateButton('&Umbenennen', 100, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_Rename')

Global $hMove = GUICtrlCreateButton('&Verschieben', 200, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_Copy')

Global $hCopy = GUICtrlCreateButton('&Kopieren', 300, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_Copy')

Global $hDelete = GUICtrlCreateButton('&Löschen', 400, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_Delete')

Global $hNewDir = GUICtrlCreateButton('Neuer &Ordner', 500, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_NewDir')

Global $hNewFile = GUICtrlCreateButton('Neue &Datei', 600, 420, 100, 25)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)
GUICtrlSetOnEvent(-1, '_NewFile')

Global $hProgress = GUICtrlCreateProgress(1, 446, 698, 12)
GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

Global $hStatus = _GUICtrlStatusBar_Create($hGui)
Global $aStatusIcons[2]
$aStatusIcons[0] = _WinAPI_LoadShell32Icon(221)
$aStatusIcons[1] = _WinAPI_LoadShell32Icon(219)

; Attribute-Gui
Global $hAttrGui = GUICreate($sTitle & ' - Dateiattribute bearbeiten', 370, 290, -1, -1, BitOR($WS_POPUPWINDOW, $WS_CAPTION), Default, $hGui)
GUISetBkColor(0xC8C8C8)
GUISetIcon($sIconDir & 'program.ico', 0)
GUISetFont(10, 400, 0, 'Tahoma', $hAttrGui, 5)
GUICtrlCreateLabel('Hier können die Dateiattribute der markierten Dateien und Verzeichnisse geändert werden.', 20, 10, 320, 35)
Global $hRecursiv = GUICtrlCreateCheckbox('Bei Verzeichnissen rekursiv ändern', 30, 56, 320, 20)
Global $ahAttr[4], $aAttrName[4] = ['R = ReadOnly', 'A = Archive', 'S = System', 'H = Hidden']
GUICtrlCreateGroup('Dateiattribute ändern (Tristate-Modus = unverändert):', 10, 90, 350, 110)
For $i = 0 To 3
	$ahAttr[$i] = GUICtrlCreateCheckbox($aAttrName[$i], 30, 110 + $i * 20, 150, 20, $BS_AUTO3STATE)
	GUICtrlSetState(-1, $GUI_INDETERMINATE)
Next
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateIcon('user32.dll', -2, 15, 210, 32, 32)
GUICtrlCreateLabel('Änderungen sollten nur von erfahrenen Benutzern vorgenommen werden!', 55, 210, 300, 40)
Global $hAttrAccept = GUICtrlCreateButton('Übernehmen', 150, 255, 100, 25)
Global $hAttrCancel = GUICtrlCreateButton('Abbrechen', 260, 255, 100, 25)

; DirList-Gui
Global $hDirListGui = GUICreate($sTitle, 240, 300, -1, -1, $WS_POPUP, Default, $hGui)
GUISetFont(10, 400, 0, 'Tahoma', $hDirListGui, 5)
Global $hDirList = GUICtrlCreateList('', 0, 0, 240, 300, BitOR($LBS_NOINTEGRALHEIGHT, $LBS_SORT, $WS_VSCROLL))
GUICtrlSetOnEvent(-1, '_SelectDir')

; DirListEdit-Gui
Global $hEditGui = GUICreate($sTitle & ' - Verzeichnisliste bearbeiten', 640, 320, -1, -1, BitOR($WS_POPUPWINDOW, $WS_CAPTION), Default, $hGui)
GUISetOnEvent($GUI_EVENT_CLOSE, '_HideEditGui')
GUISetFont(10, 400, 0, 'Tahoma', $hEditGui, 5)
GUISetBkColor(0xC8C8C8)
GUISetIcon($sIconDir & 'program.ico', 0)
Global $hEditLV = GUICtrlCreateListView('Name|Pfad', 5, 5, 630, 230)
Global $hEditContext = GUICtrlCreateContextMenu($hEditLV)
GUICtrlCreateMenuItem('Eintrag löschen', $hEditContext)
GUICtrlSetOnEvent(-1, '_DirListItemDelete')
GUICtrlCreateGroup('Eintrag ändern:', 5, 240, 630, 75)
GUICtrlCreateLabel('Name', 20, 262, 100, 18)
Global $hEditName = GUICtrlCreateInput('', 20, 280, 280, 20)
GUICtrlCreateLabel('Pfad', 305, 262, 100, 18)
Global $hEditPath = GUICtrlCreateInput('', 305, 280, 280, 20)
Global $hEditOk = GUICtrlCreateButton('Ok', 590, 279, 35, 22)
GUICtrlSetOnEvent(-1, '_DirListItemOk')
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlCreateGroup('', -99, -99, 1, 1)

For $i = 1 To $aDirList[0][0]
	GUICtrlSetData($hDirList, $aDirList[$i][0])
	GUICtrlCreateListViewItem($aDirList[$i][0] & '|' & $aDirList[$i][1], $hEditLV)
Next
_GUICtrlListView_SetColumnWidth($hEditLV, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetColumnWidth($hEditLV, 1, $LVSCW_AUTOSIZE)

GUIRegisterMsg($WM_SIZE, 'WM_SIZE')
GUIRegisterMsg($WM_MOVE, 'WM_MOVE')
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
If Not IsDeclared('WM_DEVICECHANGE') Then Global Const $WM_DEVICECHANGE = 0x0219
GUIRegisterMsg($WM_DEVICECHANGE, 'WM_DEVICECHANGE')
GUIRegisterMsg($WM_GETMINMAXINFO, 'WM_GETMINMAXINFO')
_GUICtrlListView_RegisterSortCallBack($ahLV[0])
_GUICtrlListView_RegisterSortCallBack($ahLV[1])

If $fMaximized Then
	WinSetState($hGui, '', @SW_MAXIMIZE)
Else
	WinMove($hGui, '', $iX, $iY, $iWidth, $iHeight)
EndIf
GUISetState(@SW_SHOW, $hGui)

GUICtrlSetData($ahPath[1], $aPath[1])
_CreateListViewItems($ahLV[1], $aPath[1])
_MarkButton(1, $aPath[1])

GUICtrlSetData($ahPath[0], $aPath[0])
_CreateListViewItems($ahLV[0], $aPath[0])
_MarkButton(0, $aPath[0])

GUICtrlSetState($ahLV[$iActiveLV], $GUI_FOCUS)

_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
HotKeySet('!c', '_Cancel')
AdlibRegister('_DeActivateButtons', 200)

While Sleep(500)
WEnd

Func _End()
	AdlibUnRegister('_DeActivateButtons')
	_GUICtrlListView_UnRegisterSortCallBack($ahLV[0])
	_GUICtrlListView_UnRegisterSortCallBack($ahLV[1])
	IniWrite($sIniFile, 'Config', 'Maximized', BitAND(WinGetState($hGui), 32) = 32)
	For $i = 0 To 4
		IniWrite($sIniFile, 'Config', 'LVCol' & $i, _GUICtrlListView_GetColumnWidth($ahLV[0], $i))
	Next
	IniWrite($sIniFile, 'Config', 'LeftPath', GUICtrlRead($ahPath[0]))
	IniWrite($sIniFile, 'Config', 'RightPath', GUICtrlRead($ahPath[1]))
	IniWrite($sIniFile, 'Config', 'ColOrder', $sColOrder)
	_WinAPI_DestroyIcon($aStatusIcons[0])
	_WinAPI_DestroyIcon($aStatusIcons[1])
	Exit
EndFunc   ;==>_End

Func _ShowEditGui()
	Local $aWinPos = WinGetPos($hGui)
	WinMove($hEditGui, '', $aWinPos[0] + $aWinPos[2] / 2 - 320, $aWinPos[1] + 40)
	GUISetState(@SW_SHOW, $hEditGui)
EndFunc   ;==>_ShowEditGui

Func _HideEditGui()
	GUISetState(@SW_HIDE, $hEditGui)
EndFunc   ;==>_HideEditGui

Func _DirListItemOk()
	Local $iSelItem, $sName, $sPath
	$iSelItem = _GUICtrlListView_GetSelectedIndices($hEditLV)
	$sName = GUICtrlRead($hEditName)
	$sPath = GUICtrlRead($hEditPath)
	_GUICtrlListView_SetItemText($hEditLV, $iSelItem, $sName, 0)
	_GUICtrlListView_SetItemText($hEditLV, $iSelItem, $sPath, 1)
	$aDirList[$iSelItem + 1][0] = $sName
	$aDirList[$iSelItem + 1][1] = $sPath
	IniWriteSection($sIniFile, 'DirList', $aDirList)
	GUICtrlSetData($hDirList, '')
	For $i = 1 To $aDirList[0][0]
		GUICtrlSetData($hDirList, $aDirList[$i][0])
	Next
EndFunc   ;==>_DirListItemOk

Func _DirListItemDelete()
	Local $iSelItem
	$iSelItem = _GUICtrlListView_GetSelectedIndices($hEditLV)
	_GUICtrlListView_DeleteItemsSelected($hEditLV)
	_ArrayDelete($aDirList, $iSelItem + 1)
	$aDirList[0][0] = UBound($aDirList) - 1
	IniWriteSection($sIniFile, 'DirList', $aDirList)
	GUICtrlSetData($hEditName, '')
	GUICtrlSetData($hEditPath, '')
	GUICtrlSetData($hDirList, '')
	For $i = 1 To $aDirList[0][0]
		GUICtrlSetData($hDirList, $aDirList[$i][0])
	Next
EndFunc   ;==>_DirListItemDelete

Func _OpenDirList()
	Switch @GUI_CtrlId
		Case $ahDirList[0]
			ControlFocus($hGui, '', $ahLV[0])
		Case $ahDirList[1]
			ControlFocus($hGui, '', $ahLV[1])
	EndSwitch
	Local $aWinPos, $aCtrlPos, $iListHeight = 300
	$aWinPos = WinGetPos($hGui)
	$aCtrlPos = ControlGetPos($hGui, '', @GUI_CtrlId)
	If ($aDirList[0][0] * 18) < 300 Then $iListHeight = $aDirList[0][0] * 18
	WinMove($hDirListGui, '', $aWinPos[0] + $aCtrlPos[0] + 8, $aWinPos[1] + $aCtrlPos[1] + 72, 240, $iListHeight)
	GUISetState(@SW_SHOW, $hDirListGui)
EndFunc   ;==>_OpenDirList

Func _SelectDir()
	If $aDirList[0][0] = 0 Then Return
	GUISetState(@SW_HIDE, $hDirListGui)
	Local $sPath, $sName = GUICtrlRead($hDirList)
	For $i = 1 To $aDirList[0][0]
		If $sName = $aDirList[$i][0] Then ExitLoop
	Next
	_MarkButton($iActiveLV, $aDirList[$i][1])
	GUICtrlSetData($ahPath[$iActiveLV], $aDirList[$i][1])
	_CreateListViewItems($ahLV[$iActiveLV], $aDirList[$i][1])
EndFunc   ;==>_SelectDir

Func _AddDirToFav()
	Local $sPath = GUICtrlRead($ahPath[$iActiveLV]), $sName
	Local $sDefault = StringRegExpReplace($sPath, '.+\\(.+)\\', '$1')
	Local $sMsg = 'Unter welchem Namen soll das Verzeichnis gespeichert werden?'
	Local $aWinPos = WinGetPos($hGui)
	Do
		$sName = InputBox($sTitle, $sMsg, $sDefault, '', 260, 140, $aWinPos[0] + $aWinPos[2] / 2 - 130, $aWinPos[1] + 50, 0, $hGui)
		If @error Then Return
	Until Not _NameExists($sName)
	ReDim $aDirList[UBound($aDirList) + 1][2]
	$aDirList[UBound($aDirList) - 1][0] = $sName
	$aDirList[UBound($aDirList) - 1][1] = $sPath
	$aDirList[0][0] = UBound($aDirList) - 1
	IniWriteSection($sIniFile, 'DirList', $aDirList)
	GUICtrlSetData($hDirList, '')
	_GUICtrlListView_DeleteAllItems($hEditLV)
	For $i = 1 To $aDirList[0][0]
		GUICtrlSetData($hDirList, $aDirList[$i][0])
		GUICtrlCreateListViewItem($aDirList[$i][0] & '|' & $aDirList[$i][1], $hEditLV)
	Next
EndFunc   ;==>_AddDirToFav

Func _NameExists(ByRef $sName)
	If $aDirList[0][0] = 0 Then Return False
	For $i = 1 To $aDirList[0][0]
		If $sName = $aDirList[$i][0] Then Return True
	Next
	Return False
EndFunc   ;==>_NameExists

Func _ChangeColOrder()
	Local $sNewColOrder, $sMsg, $aTest
	Local $aWinPos = WinGetPos($hGui)
	$sMsg = 'Anzeigereihenfolge der Spalten in den Dateilisten ändern.\n\n'
	$sMsg &= 'Bedeutung der Zahlen:\n\t0 = Datei-/Verzeichnisname\n\t1 = Dateierweiterung\n\t'
	$sMsg &= '2 = Dateigröße\n\t3 = Dateidatum\n\t4 = Dateiattribute\n\n'
	$sMsg &= 'Hinweis: Zwischen den Zahlen muss ein "|" als Trennzeichen stehen.'
	Do
		$sNewColOrder = InputBox($sTitle, StringFormat($sMsg), $sColOrder, '', 380, 250, $aWinPos[0] + $aWinPos[2] / 2 - 190, $aWinPos[1] + 50, 0, $hGui)
		If @error Then Return
		If Not StringRegExp($sNewColOrder, '\d\|\d\|\d\|\d\|\d') Then ContinueLoop
		$aTest = StringSplit($sNewColOrder, '|', 2)
		_ArraySort($aTest)
	Until _ArrayToString($aTest, '') = '01234'
	_GUICtrlListView_SetColumnOrder($ahLV[0], $sNewColOrder)
	_GUICtrlListView_SetColumnOrder($ahLV[1], $sNewColOrder)
	_GUICtrlListView_RedrawItems($ahLV[0], 0, _GUICtrlListView_GetItemCount($ahLV[0]))
	_GUICtrlListView_RedrawItems($ahLV[1], 0, _GUICtrlListView_GetItemCount($ahLV[1]))
	$sColOrder = $sNewColOrder
EndFunc   ;==>_ChangeColOrder

Func _CreateContextMenu(ByRef $hListView, $iCount)
	$ahContextMenu[$iCount] = GUICtrlCreateContextMenu($hListView)
	GUICtrlCreateMenuItem('Alles markieren', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_MarkAll')
	GUICtrlCreateMenuItem('Nichts markieren', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_MarkNothing')
	GUICtrlCreateMenuItem('Alle Verzeichnisse markieren', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_MarkDirs')
	GUICtrlCreateMenuItem('Größe der markierten Verzeichnisse einlesen', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_ReadMarkDirSize')
	GUICtrlCreateMenuItem('Größe aller Verzeichnisse einlesen', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_ReadAllDirSize')
	GUICtrlCreateMenuItem('Alle Dateien markieren', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_MarkFiles')
	GUICtrlCreateMenuItem('Alle Dateien mit der gleichen Endung markieren', $ahContextMenu[$iCount])
	GUICtrlSetOnEvent(-1, '_MarkSameExt')
EndFunc   ;==>_CreateContextMenu

Func _DeActivateButtons()
	Local $hwndLV = GUICtrlGetHandle($ahLV[$iActiveLV]), $iCount = _GUICtrlListView_GetSelectedCount($hwndLV)
	If $iCount = 0 Or ($iCount = 1 And _GUICtrlListView_GetItemText($hwndLV, 0, 0) = '..' And _GUICtrlListView_GetItemSelected($hwndLV, 0)) Then
		If BitAND(GUICtrlGetState($hChangeAttr), $GUI_ENABLE) Then
			For $iCtrlID = $hChangeAttr To $hDelete
				GUICtrlSetState($iCtrlID, $GUI_DISABLE)
			Next
		EndIf
	Else
		If BitAND(GUICtrlGetState($hChangeAttr), $GUI_DISABLE) Then
			For $iCtrlID = $hChangeAttr To $hDelete
				GUICtrlSetState($iCtrlID, $GUI_ENABLE)
			Next
		EndIf
	EndIf
	If GUICtrlRead($hEditName) & '|' & GUICtrlRead($hEditPath) <> _GUICtrlListView_GetItemTextString($hEditLV) Then
		If BitAND(GUICtrlGetState($hEditOk), $GUI_DISABLE) Then GUICtrlSetState($hEditOk, $GUI_ENABLE)
	Else
		If BitAND(GUICtrlGetState($hEditOk), $GUI_ENABLE) Then GUICtrlSetState($hEditOk, $GUI_DISABLE)
	EndIf
EndFunc   ;==>_DeActivateButtons

Func _SortLV() ; passt noch nicht
;~ 	Local $hListView = @GUI_CtrlId, $iCol = GUICtrlGetState($hListView), $fSubDir = False
;~ 	Local $aPattern[4] = ['(\d{2}).(\d{2}).(\d{4})  (\d{2}):(\d{2}):(\d{2})', '$3$2$1$4$5$6', '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', '$3.$2.$1  $4:$5:$6']
;~ 	If _GUICtrlListView_GetItemText(GUICtrlGetHandle($hListView), 0, 0) = '..' Then $fSubDir = _GUICtrlListView_DeleteItem(GUICtrlGetHandle($hListView), 0)
;~ 	For $i = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
;~ 		_GUICtrlListView_SetItemText($hListView, $i, StringReplace(_GUICtrlListView_GetItemText($hListView, $i, 2), '.', ''), 2)
;~ 		_GUICtrlListView_SetItemText($hListView, $i, StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $i, 3), $aPattern[0], $aPattern[1]), 3)
;~ 	Next
;~ 	_GUICtrlListView_SortItems($hListView, $iCol)
;~ 	For $i = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
;~ 		_GUICtrlListView_SetItemText($hListView, $i, _StringAddThousandsSep(_GUICtrlListView_GetItemText($hListView, $i, 2)), 2)
;~ 		_GUICtrlListView_SetItemText($hListView, $i, StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $i, 3), $aPattern[2], $aPattern[3]), 3)
;~ 	Next
;~ 	If $fSubDir Then _GUICtrlListView_InsertItem($hListView, '..', 0, $UP_ICON_INDEX, _GUICtrlListView_GetItemCount($hListView) + 9999)
EndFunc   ;==>_SortLV

Func _MarkAll()
	ControlFocus($hGui, '', $ahLV[$iActiveLV])
	_GUICtrlListView_SetItemSelected($ahLV[$iActiveLV], -1, True)
	If _GUICtrlListView_GetItemText($ahLV[$iActiveLV], 0, 0) = '..' Then _GUICtrlListView_SetItemSelected($ahLV[$iActiveLV], 0, False)
EndFunc   ;==>_MarkAll

Func _MarkNothing()
	ControlFocus($hGui, '', $ahLV[$iActiveLV])
	_GUICtrlListView_SetItemSelected($ahLV[$iActiveLV], -1, False)
EndFunc   ;==>_MarkNothing

Func _MarkDirs()
	ControlFocus($hGui, '', $ahLV[$iActiveLV])
	For $i = 0 To _GUICtrlListView_GetItemCount($ahLV[$iActiveLV]) - 1
		If _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $i, 0) = '..' Then ContinueLoop
		_GUICtrlListView_SetItemSelected($ahLV[$iActiveLV], $i, _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $i, 1) = '<DIR>')
	Next
EndFunc   ;==>_MarkDirs

Func _MarkFiles()
	ControlFocus($hGui, '', $ahLV[$iActiveLV])
	For $i = 0 To _GUICtrlListView_GetItemCount($ahLV[$iActiveLV]) - 1
		If _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $i, 0) = '..' Then ContinueLoop
		_GUICtrlListView_SetItemSelected($ahLV[$iActiveLV], $i, _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $i, 1) <> '<DIR>')
	Next
EndFunc   ;==>_MarkFiles

Func _MarkSameExt()
	Local $hwndLV = GUICtrlGetHandle($ahLV[$iActiveLV]), $aSelIndices = _GUICtrlListView_GetSelectedIndices($hwndLV, True)
	If $aSelIndices[0] = 0 Then Return
	For $i = 0 To _GUICtrlListView_GetItemCount($hwndLV) - 1
		For $j = 1 To $aSelIndices[0]
			If $i = $aSelIndices[$j] Then ContinueLoop
			If _GUICtrlListView_GetItemText($hwndLV, $i, 1) = _GUICtrlListView_GetItemText($hwndLV, $aSelIndices[$j], 1) Then
				_GUICtrlListView_SetItemSelected($hwndLV, $i, True)
				ExitLoop
			EndIf
		Next
	Next
EndFunc   ;==>_MarkSameExt

Func _ReadMarkDirSize()
	Local $hwndLV = GUICtrlGetHandle($ahLV[$iActiveLV]), $aSelIndices = _GUICtrlListView_GetSelectedIndices($hwndLV, True), $sPath, $sName, $iSize
	If $aSelIndices[0] = 0 Then Return
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	For $i = 1 To $aSelIndices[0]
		If $fCancel Then
			$fCancel = False
			If BitAND(WinGetState($hGui), 8) Then
				_PlayDefaultSystemSound('SystemHand')
				_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
				_GUICtrlStatusBar_SetText($hStatus, 'Funktion abgebrochen.')
				GUICtrlSetData($hProgress, 0)
				Return
			EndIf
		EndIf
		If _GUICtrlListView_GetItemText($hwndLV, $aSelIndices[$i], 1) = '<DIR>' Then
			$sName = _GUICtrlListView_GetItemText($hwndLV, $aSelIndices[$i], 0)
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
			_GUICtrlStatusBar_SetText($hStatus, 'Lese Verzeichnis: "' & $sName & '"')
			$iSize = DirGetSize($sPath & $sName)
			If Not @error Then _GUICtrlListView_SetItemText($hwndLV, $aSelIndices[$i], _StringAddThousandsSep($iSize), 2)
		EndIf
		GUICtrlSetData($hProgress, 100 / $aSelIndices[0] * $i)
	Next
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
	Sleep(500)
	GUICtrlSetData($hProgress, 0)
EndFunc   ;==>_ReadMarkDirSize

Func _ReadAllDirSize()
	Local $hwndLV = GUICtrlGetHandle($ahLV[$iActiveLV]), $iCount = _GUICtrlListView_GetItemCount($hwndLV), $sPath, $sName, $iSize
	If $iCount = 0 Then Return
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	For $i = 0 To $iCount - 1
		If $fCancel Then
			$fCancel = False
			If BitAND(WinGetState($hGui), 8) Then
				_PlayDefaultSystemSound('SystemHand')
				_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
				_GUICtrlStatusBar_SetText($hStatus, 'Funktion abgebrochen.')
				GUICtrlSetData($hProgress, 0)
				Return
			EndIf
		EndIf
		If _GUICtrlListView_GetItemText($hwndLV, $i, 1) = '<DIR>' Then
			$sName = _GUICtrlListView_GetItemText($hwndLV, $i, 0)
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
			_GUICtrlStatusBar_SetText($hStatus, 'Lese Verzeichnis: "' & $sName & '"')
			$iSize = DirGetSize($sPath & _GUICtrlListView_GetItemText($hwndLV, $i, 0))
			If Not @error Then _GUICtrlListView_SetItemText($hwndLV, $i, _StringAddThousandsSep($iSize), 2)
		EndIf
		GUICtrlSetData($hProgress, 100 / $iCount * ($i + 1))
	Next
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
	Sleep(500)
	GUICtrlSetData($hProgress, 0)
EndFunc   ;==>_ReadAllDirSize

Func _ChangeAttr()
	Local $sPath, $aSelIndices, $sName, $sExt, $sNewAttr, $fRecursive
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	$aSelIndices = _GUICtrlListView_GetSelectedIndices($ahLV[$iActiveLV], True)
	If $aSelIndices[0] = 0 Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Keine Einträge markiert.')
		Return
	EndIf
	GUISetState(@SW_LOCK, $hGui)
	Opt('GUIOnEventMode', 0)
	For $i = 0 To 3
		GUICtrlSetState($ahAttr[$i], $GUI_INDETERMINATE)
	Next
	GUICtrlSetState($hRecursiv, $GUI_UNCHECKED)
	GUISetState(@SW_SHOW, $hAttrGui)
	While True
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE, $hAttrCancel
				ExitLoop
			Case $hAttrAccept
				GUISetState(@SW_LOCK, $hAttrGui)
				$sNewAttr = _ReadAttr()
				$fRecursive = Number(BitAND(GUICtrlRead($hRecursiv), $GUI_CHECKED) = $GUI_CHECKED)
				For $i = 1 To $aSelIndices[0]
					$sName = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 0)
					If $sName = '..' Then ContinueLoop
					$sExt = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 1)
					If $sExt <> '' Then $sExt = '.' & $sExt
					Switch $sExt
						Case '.<DIR>'
							FileSetAttrib($sPath & $sName, $sNewAttr, $fRecursive)
						Case Else
							FileSetAttrib($sPath & $sName & $sExt, $sNewAttr)
					EndSwitch
				Next
				_CreateListViewItems($ahLV[$iActiveLV], $sPath)
				GUISetState(@SW_UNLOCK, $hAttrGui)
				ExitLoop
		EndSwitch
	WEnd
	GUISetState(@SW_HIDE, $hAttrGui)
	GUISetState(@SW_UNLOCK, $hGui)
	Opt('GUIOnEventMode', 1)
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
EndFunc   ;==>_ChangeAttr

Func _ReadAttr()
	Local $sNewAttr, $sAttr = 'RASH'
	For $i = 0 To 3
		Switch GUICtrlRead($ahAttr[$i])
			Case $GUI_CHECKED
				$sNewAttr &= '+' & StringMid($sAttr, $i + 1, 1)
			Case $GUI_UNCHECKED
				$sNewAttr &= '-' & StringMid($sAttr, $i + 1, 1)
		EndSwitch
	Next
	Return $sNewAttr
EndFunc   ;==>_ReadAttr

Func _Rename()
	Local $sPath, $aSelIndices, $sName, $sExt, $sTmp
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	If Not FileExists($sPath) Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Pfad existiert nicht mehr.')
		Return
	EndIf
	$aSelIndices = _GUICtrlListView_GetSelectedIndices($ahLV[$iActiveLV], True)
	If $aSelIndices[0] = 0 Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Keine Einträge markiert.')
		Return
	EndIf
	For $i = 1 To $aSelIndices[0]
		$sName = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 0)
		If $sName = '..' Then ContinueLoop
		$sExt = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 1)
		If $sExt <> '' Then $sExt = '.' & $sExt
		Switch $sExt
			Case '.<DIR>'
				$sTmp = InputBox($sTitle, 'Verzeichnis umbenennen', $sName, '', 320, 135, Default, Default, 0, $hGui)
				If @error Then ExitLoop
				If $sTmp == $sName Then ContinueLoop
				If DirMove($sPath & $sName, $sPath & $sTmp) Then
					_LogWrite('Dir "' & $sPath & $sName & '" renamed to "' & $sPath & $sTmp & '"')
					_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
					_GUICtrlStatusBar_SetText($hStatus, 'Verzeichnis umbenannt.')
				Else
					_PlayDefaultSystemSound('SystemHand')
					_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
					_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Verzeichnis konnte nicht umbenannt werden.')
				EndIf
			Case Else
				$sTmp = InputBox($sTitle, 'Datei umbenennen', $sName & $sExt, '', 320, 135, Default, Default, 0, $hGui)
				If @error Then ExitLoop
				If $sTmp == $sName & $sExt Then ContinueLoop
				If FileMove($sPath & $sName & $sExt, $sPath & $sTmp) Then
					_LogWrite('File "' & $sPath & $sName & $sExt & '" renamed to "' & $sPath & $sTmp & '"')
					_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
					_GUICtrlStatusBar_SetText($hStatus, 'Datei umbenannt.')
				Else
					_PlayDefaultSystemSound('SystemHand')
					_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
					_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Datei konnte nicht umbenannt werden.')
				EndIf
		EndSwitch
	Next
	_CreateListViewItems($ahLV[$iActiveLV], $sPath)
	Sleep(2000)
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
EndFunc   ;==>_Rename

Func _Cancel()
	$fCancel = True
EndFunc   ;==>_Cancel

Func _Copy()
	Local $aSelIndices, $sSourcePath, $sDestPath, $sName, $sExt, $aCopyFiles, $iPercent, $aDirSize
	Switch @GUI_CtrlId
		Case $hCopy
			Local $aMsg[2] = ['Kopiervorgang abgebrochen.', 'Kopiere "']
		Case $hMove
			Local $aMsg[2] = ['Verschiebevorgang abgebrochen.', 'Verschiebe "']
	EndSwitch
	$sSourcePath = GUICtrlRead($ahPath[$iActiveLV])
	If Not FileExists($sSourcePath) Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Der Quellpfad existiert nicht mehr.')
		Return
	EndIf
	$sDestPath = GUICtrlRead($ahPath[1 - $iActiveLV])
	If Not FileExists($sDestPath) Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Zielpfad existiert nicht mehr.')
		Return
	EndIf
	$aSelIndices = _GUICtrlListView_GetSelectedIndices($ahLV[$iActiveLV], True)
	If $aSelIndices[0] = 0 Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Keine Einträge markiert.')
		Return
	EndIf
	For $i = 1 To $aSelIndices[0]
		If $fCancel Then
			$fCancel = False
			If BitAND(WinGetState($hGui), 8) Then
				_PlayDefaultSystemSound('SystemHand')
				_CreateListViewItems($ahLV[1 - $iActiveLV], $sDestPath)
				_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
				_GUICtrlStatusBar_SetText($hStatus, $aMsg[0])
				GUICtrlSetData($hProgress, 0)
				Return
			EndIf
		EndIf
		$sName = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 0)
		If $sName = '..' Then ContinueLoop
		$sExt = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 1)
		If $sExt <> '' Then $sExt = '.' & $sExt
		Switch $sExt
			Case '.<DIR>'
				$aCopyFiles = _RecursiveFileListToArray($sSourcePath & $sName)
				If Not IsArray($aCopyFiles) Then
					DirCreate($sDestPath & $sName)
				Else
					$iPercent = 100 / $aSelIndices[0]
					For $j = 1 To $aCopyFiles[0]
						If $fCancel Then
							$fCancel = False
							If BitAND(WinGetState($hGui), 8) Then
								_PlayDefaultSystemSound('SystemHand')
								_CreateListViewItems($ahLV[1 - $iActiveLV], $sDestPath)
								_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
								_GUICtrlStatusBar_SetText($hStatus, $aMsg[0])
								GUICtrlSetData($hProgress, 0)
								Return
							EndIf
						EndIf
						$aCopyFiles[$j] = StringReplace($aCopyFiles[$j], $sSourcePath, '')
						If StringRight($aCopyFiles[$j], 1) = '\' Then
							$aDirSize = DirGetSize($sSourcePath & $aCopyFiles[$j], 3)
							If $aDirSize[1] = 0 And $aDirSize[2] = 0 Then
								DirCreate($sDestPath & $aCopyFiles[$j])
								If @GUI_CtrlId = $hMove Then DirRemove($sSourcePath & $aCopyFiles[$j])
							EndIf
							ContinueLoop
						EndIf
						_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
						_GUICtrlStatusBar_SetText($hStatus, $aMsg[1] & $aCopyFiles[$j] & '"')
						Switch @GUI_CtrlId
							Case $hCopy
								If FileCopy($sSourcePath & $aCopyFiles[$j], $sDestPath & $aCopyFiles[$j], 9) Then _LogWrite('File "' & $sSourcePath & $aCopyFiles[$j] & '" copied')
							Case $hMove
								If FileMove($sSourcePath & $aCopyFiles[$j], $sDestPath & $aCopyFiles[$j], 9) Then _LogWrite('File "' & $sSourcePath & $aCopyFiles[$j] & '" moved')
						EndSwitch
						GUICtrlSetData($hProgress, (100 / $aSelIndices[0] * ($i - 1)) + ($iPercent / $aCopyFiles[0] * $j))
					Next
				EndIf
				If @GUI_CtrlId = $hMove And Not DirRemove($sSourcePath & $sName, 1) Then _LogWrite('Dir "' & $sSourcePath & $sName & '" cannot removed')
			Case Else
				_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
				_GUICtrlStatusBar_SetText($hStatus, $aMsg[1] & $sSourcePath & $sName & $sExt & '"')
				Switch @GUI_CtrlId
					Case $hCopy
						If FileCopy($sSourcePath & $sName & $sExt, $sDestPath, 9) Then _LogWrite('File "' & $sSourcePath & $sName & $sExt & '" copied')
					Case $hMove
						If FileMove($sSourcePath & $sName & $sExt, $sDestPath, 9) Then _LogWrite('File "' & $sSourcePath & $sName & $sExt & '" moved')
				EndSwitch
		EndSwitch
		GUICtrlSetData($hProgress, 100 / $aSelIndices[0] * $i)
	Next
	If @GUI_CtrlId = $hMove Then _CreateListViewItems($ahLV[$iActiveLV], $sSourcePath)
	_CreateListViewItems($ahLV[1 - $iActiveLV], $sDestPath)
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
	Sleep(500)
	GUICtrlSetData($hProgress, 0)
EndFunc   ;==>_Copy

Func _Delete()
	Local $aSelIndices, $sPath, $sName, $sExt
	If MsgBox(4 + 32 + 256, $sTitle, 'Sollen die markierten Verzeichnisse' & @CR & 'und Dateien wirklich gelöscht werden?', 0, $hGui) = 7 Then
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Funktion abgebrochen.')
		Return
	Else
		$sPath = GUICtrlRead($ahPath[$iActiveLV])
		If Not FileExists($sPath) Then
			_PlayDefaultSystemSound('SystemHand')
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
			_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Pfad existiert nicht mehr.')
			Return
		EndIf
		$aSelIndices = _GUICtrlListView_GetSelectedIndices($ahLV[$iActiveLV], True)
		If $aSelIndices[0] = 0 Then
			_PlayDefaultSystemSound('SystemHand')
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
			_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Keine Einträge markiert.')
			Return
		EndIf
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
		_GUICtrlStatusBar_SetText($hStatus, 'Lösche markierte Dateien und Verzeichnisse. Bitte warten!')
		For $i = 1 To $aSelIndices[0]
			If $fCancel Then
				$fCancel = False
				If BitAND(WinGetState($hGui), 8) Then
					_PlayDefaultSystemSound('SystemHand')
					_CreateListViewItems($ahLV[$iActiveLV], $sPath)
					_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
					_GUICtrlStatusBar_SetText($hStatus, 'Löschvorgang abgebrochen.')
					GUICtrlSetData($hProgress, 0)
					Return
				EndIf
			EndIf
			$sName = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 0)
			If $sName = '..' Then ContinueLoop
			$sExt = _GUICtrlListView_GetItemText($ahLV[$iActiveLV], $aSelIndices[$i], 1)
			If $sExt <> '' Then $sExt = '.' & $sExt
			Switch $sExt
				Case '.<DIR>'
					If DirRemove($sPath & $sName, 1) Then _LogWrite('Delete DIR "' & $sPath & $sName & '"')
				Case Else
					If FileDelete($sPath & $sName & $sExt) Then _LogWrite('Delete FILE "' & $sPath & $sName & $sExt & '"')
			EndSwitch
			GUICtrlSetData($hProgress, 100 / $aSelIndices[0] * $i)
		Next
		_CreateListViewItems($ahLV[$iActiveLV], $sPath)
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
		_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
		Sleep(500)
		GUICtrlSetData($hProgress, 0)
	EndIf
EndFunc   ;==>_Delete

Func _SwitchLogfile()
	$fLogfile = Not $fLogfile
	Switch $fLogfile
		Case True
			GUICtrlSetState($hLogfile, $GUI_CHECKED)
		Case False
			GUICtrlSetState($hLogfile, $GUI_UNCHECKED)
	EndSwitch
	IniWrite($sIniFile, 'Config', 'Logfile', $fLogfile)
EndFunc   ;==>_SwitchLogfile

Func _LogWrite($sLine)
	If $fLogfile Then FileWriteLine($sLogfile, StringFormat('%02i.%02i.%04i %02i:%02i:%02i   %s', @MDAY, @MON, @YEAR, @HOUR, @MIN, @SEC, $sLine))
EndFunc   ;==>_LogWrite

Func _LVLeftUp()
	Local $sPath = StringRegExpReplace(GUICtrlRead($ahPath[0]), '(.+\\).+\\', '$1')
	ControlFocus($hGui, '', $ahLV[0])
	GUICtrlSetData($ahPath[0], $sPath)
	_CreateListViewItems($ahLV[0], $sPath)
EndFunc   ;==>_LVLeftUp

Func _LVRightUp()
	Local $sPath = StringRegExpReplace(GUICtrlRead($ahPath[1]), '(.+\\).+\\', '$1')
	ControlFocus($hGui, '', $ahLV[1])
	GUICtrlSetData($ahPath[1], $sPath)
	_CreateListViewItems($ahLV[1], $sPath)
EndFunc   ;==>_LVRightUp

Func _ReloadLeftLV()
	ControlFocus($hGui, '', $ahLV[0])
	_CreateListViewItems($ahLV[0], GUICtrlRead($ahPath[0]))
EndFunc   ;==>_ReloadLeftLV

Func _ReloadRightLV()
	ControlFocus($hGui, '', $ahLV[1])
	_CreateListViewItems($ahLV[1], GUICtrlRead($ahPath[1]))
EndFunc   ;==>_ReloadRightLV

Func _NewFile()
	Local $sPath, $sFilename, $hFile
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	If Not FileExists($sPath) Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Pfad existiert nicht mehr.')
		Return
	EndIf
	$sFilename = InputBox('Neue Datei', 'Bitte Dateinamen eingeben:', 'neu.txt', '', 270, 130, Default, Default, 0, $hGui)
	If @error Then
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Funktion abgebrochen.')
		Return
	EndIf
	$sFilename = _GetUniqueFileName($sPath & $sFilename)
	$hFile = FileOpen($sFilename, 2)
	If $hFile <> -1 Then
		FileClose($hFile)
		_CreateListViewItems($ahLV[$iActiveLV], $sPath)
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
		_GUICtrlStatusBar_SetText($hStatus, 'Die Datei "' & $sFilename & '" wurde erstellt.')
	Else
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Datei konnte nicht erstellt werden.')
	EndIf
EndFunc   ;==>_NewFile

Func _NewDir()
	Local $sPath, $sFilename, $hFile
	$sPath = GUICtrlRead($ahPath[$iActiveLV])
	If Not FileExists($sPath) Then
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Pfad existiert nicht mehr.')
		Return
	EndIf
	While True
		$sFilename = InputBox('Neues Verzeichnis', 'Bitte Verzeichnisnamen eingeben:', 'neu', '', 270, 130, Default, Default, 0, $hGui)
		If @error Then
			_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
			_GUICtrlStatusBar_SetText($hStatus, 'Funktion abgebrochen.')
			Return
		EndIf
		If Not FileExists($sPath & $sFilename) Then ExitLoop
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Ein Verzeichnis mit diesem Namen existiert bereits.')
	WEnd
	If DirCreate($sPath & $sFilename) Then
		_CreateListViewItems($ahLV[$iActiveLV], $sPath)
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
		_GUICtrlStatusBar_SetText($hStatus, 'Das Verzeichnis "' & $sPath & $sFilename & '" wurde erstellt.')
	Else
		_PlayDefaultSystemSound('SystemHand')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Verzeichnis konnte nicht erstellt werden.')
	EndIf
EndFunc   ;==>_NewDir

Func _MarkButton($iLV, $sPath)
	For $i = 1 To $aDrives[0]
		If $aDrives[$i] = StringLeft($sPath, 2) Then
			GUICtrlSetState($ahDriveButtons[$i - 1][$iLV], $GUI_CHECKED)
			GUICtrlSetState($ahDriveButtons[$i - 1][$iLV], $GUI_FOCUS)
		Else
			GUICtrlSetState($ahDriveButtons[$i - 1][$iLV], $GUI_UNCHECKED)
		EndIf
	Next
EndFunc   ;==>_MarkButton

Func _ReadDriveLeft()
	Local $sPath = GUICtrlRead(@GUI_CtrlId, 1) & '\'
	If DriveStatus($sPath) <> 'READY' Then
		_PlayDefaultSystemSound('DeviceFail')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Laufwerk nicht bereit.')
		Return
	EndIf
	GUICtrlSetState($ahLV[0], $GUI_FOCUS)
	GUICtrlSetData($ahPath[0], $sPath)
	_CreateListViewItems($ahLV[0], $sPath)
EndFunc   ;==>_ReadDriveLeft

Func _ReadDriveRight()
	Local $sPath = GUICtrlRead(@GUI_CtrlId, 1) & '\'
	If DriveStatus($sPath) <> 'READY' Then
		_PlayDefaultSystemSound('DeviceFail')
		_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[1])
		_GUICtrlStatusBar_SetText($hStatus, 'Fehler! Laufwerk nicht bereit.')
		Return
	EndIf
	GUICtrlSetState($ahLV[1], $GUI_FOCUS)
	GUICtrlSetData($ahPath[1], $sPath)
	_CreateListViewItems($ahLV[1], $sPath)
EndFunc   ;==>_ReadDriveRight

Func _CreateListViewItems(ByRef $hListView, $sPath)
	Local $sDriveIcon, $aDirs, $aFiles, $iIndex, $sDate, $sAttr, $iSize, $sName, $sExt, $iDirSize = 0, $sInfo, $sDrive, $sLabel
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
	_GUICtrlStatusBar_SetText($hStatus, 'Lese Verzeichnis. Bitte warten!')
	ToolTip('Lese Verzeichnis. Bitte warten!', Default, Default, $sTitle, 1, 1)
	_GUICtrlListView_BeginUpdate($hListView)
	_GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($hListView))
	If StringLen($sPath) > 3 Then _GUICtrlListView_AddItem($hListView, '..', $UP_ICON_INDEX, _GUICtrlListView_GetItemCount($hListView) + 9999)
	$aDirs = _FileListToArray($sPath, '*', 2)
	If Not @error Then
		For $i = 1 To $aDirs[0]
			If Not _IsReparsePoint($sPath & $aDirs[$i]) Then
				$sDate = StringRegExpReplace(FileGetTime($sPath & $aDirs[$i], 0, 1), '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', '$3.$2.$1  $4:$5:$6')
				$sAttr = StringRegExpReplace(FileGetAttrib($sPath & $aDirs[$i]), '[NDOCT]', '')
				$iIndex = _GUICtrlListView_AddItem($hListView, $aDirs[$i], $FOLDER_ICON_INDEX, _GUICtrlListView_GetItemCount($hListView) + 9999)
				_GUICtrlListView_AddSubItem($hListView, $iIndex, '<DIR>', 1)
				_GUICtrlListView_AddSubItem($hListView, $iIndex, '-', 2)
				_GUICtrlListView_AddSubItem($hListView, $iIndex, $sDate, 3)
				_GUICtrlListView_AddSubItem($hListView, $iIndex, $sAttr, 4)
			EndIf
		Next
	Else
		Local $aDirs[1] = [0]
	EndIf
	$aFiles = _FileListToArray($sPath, '*', 1)
	If Not @error Then
		For $i = 1 To $aFiles[0]
			$sDate = StringRegExpReplace(FileGetTime($sPath & $aFiles[$i], 0, 1), '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', '$3.$2.$1  $4:$5:$6')
			$sAttr = StringRegExpReplace(FileGetAttrib($sPath & $aFiles[$i]), '[NDOCT]', '')
			$iSize = FileGetSize($sPath & $aFiles[$i])
			$iDirSize += $iSize
			$sName = StringRegExpReplace($aFiles[$i], '(.*)\..*', '$1')
			$sExt = StringRegExpReplace($aFiles[$i], '.*\.(.*)', '$1')
			If $sExt = $aFiles[$i] Then $sExt = ''
			$iIndex = _GUICtrlListView_AddItem($hListView, $sName, _GUIImageList_GetFileIconIndex($sPath & $aFiles[$i]), _GUICtrlListView_GetItemCount($hListView) + 9999)
			_GUICtrlListView_AddSubItem($hListView, $iIndex, $sExt, 1)
			_GUICtrlListView_AddSubItem($hListView, $iIndex, _StringAddThousandsSep($iSize), 2)
			_GUICtrlListView_AddSubItem($hListView, $iIndex, $sDate, 3)
			_GUICtrlListView_AddSubItem($hListView, $iIndex, $sAttr, 4)
		Next
	Else
		Local $aFiles[1] = [0]
	EndIf
	$sInfo = ' ' & $aDirs[0] & ' Verzeichnis' & _Iif($aDirs[0] <> 1, 'se, ', ', ')
	$sInfo &= $aFiles[0] & ' Datei' & _Iif($aFiles[0] <> 1, 'en (', ' (')
	$sInfo &= _ByteAutoSize($iDirSize) & ')'
	$sDrive = StringLeft($sPath, 2)
	$sLabel = ' [' & DriveGetLabel($sDrive) & ']  ' & _ByteAutoSize(DriveSpaceTotal($sDrive) * 2 ^ 20)
	$sLabel &= ' (' & _ByteAutoSize(DriveSpaceFree($sDrive) * 2 ^ 20) & ' frei)'
	Switch DriveGetType($sDrive)
		Case 'Removable'
			$sDriveIcon = 'removable.ico'
			If $sDrive = 'A:' Or $sDrive = 'B:' Then $sDriveIcon = 'floppy.ico'
		Case 'Fixed'
			$sDriveIcon = 'hdd.ico'
		Case 'CDROM'
			$sDriveIcon = 'cdrom.ico'
		Case 'Network'
			$sDriveIcon = 'network.ico'
		Case 'Unknown'
			$sDriveIcon = 'unknown.ico'
	EndSwitch
	Switch $hListView
		Case $ahLV[0]
			GUICtrlSetImage($ahDriveIcon[0], $sIconDir & $sDriveIcon, -1, 1)
			GUICtrlSetData($ahLabel[0], $sLabel)
			GUICtrlSetData($ahInfo[0], $sInfo)
		Case $ahLV[1]
			GUICtrlSetImage($ahDriveIcon[1], $sIconDir & $sDriveIcon, -1, 1)
			GUICtrlSetData($ahLabel[1], $sLabel)
			GUICtrlSetData($ahInfo[1], $sInfo)
	EndSwitch
	_GUICtrlListView_EndUpdate($hListView)
	ToolTip('')
	_GUICtrlStatusBar_SetIcon($hStatus, 0, $aStatusIcons[0])
	_GUICtrlStatusBar_SetText($hStatus, 'Fertig.')
EndFunc   ;==>_CreateListViewItems

Func _CreateDriveButtons($fDelete = False)
	Local $aPos = WinGetPos($hGui)
	If $fDelete Then
		For $i = 0 To UBound($ahDriveButtons) - 1
			GUICtrlDelete($ahDriveButtons[$i][0])
			GUICtrlDelete($ahDriveButtons[$i][1])
		Next
		WinSetTrans($hGui, '', 0)
		WinMove($hGui, '', $aPos[0], $aPos[1], 716, 540)
	EndIf
	$aDrives = DriveGetDrive('ALL')
	Global $ahDriveButtons[$aDrives[0]][2]
	GUIStartGroup()
	For $i = 1 To $aDrives[0]
		$ahDriveButtons[$i - 1][0] = GUICtrlCreateCheckbox(StringUpper($aDrives[$i]), 2 + ($i - 1) * 22, 2, 22, 22, BitOR($BS_PUSHLIKE, $BS_AUTORADIOBUTTON))
		GUICtrlSetOnEvent(-1, '_ReadDriveLeft')
		GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT)
	Next
	GUIStartGroup()
	For $i = 1 To $aDrives[0]
		$ahDriveButtons[$i - 1][1] = GUICtrlCreateCheckbox(StringUpper($aDrives[$i]), 350 + ($i - 1) * 22, 2, 22, 22, BitOR($BS_PUSHLIKE, $BS_AUTORADIOBUTTON))
		GUICtrlSetOnEvent(-1, '_ReadDriveRight')
		GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT)
	Next
	If $fDelete Then
		WinMove($hGui, '', $aPos[0], $aPos[1], $aPos[2], $aPos[3])
		WinSetTrans($hGui, '', 255)
	EndIf
EndFunc   ;==>_CreateDriveButtons

Func WM_DEVICECHANGE($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $ilParam
	If $iwParam = 0x8000 Or $iwParam = 0x8004 Then _CreateDriveButtons(True)
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DEVICECHANGE

Func WM_MOVE($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $iwParam, $ilParam
	GUISetState(@SW_HIDE, $hDirListGui)
	Local $aPos = WinGetPos($hGui)
	IniWrite($sIniFile, 'Config', 'X', $aPos[0])
	IniWrite($sIniFile, 'Config', 'Y', $aPos[1])
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOVE

Func WM_SIZE($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $iwParam, $ilParam
	GUISetState(@SW_HIDE, $hDirListGui)
	Local $aPos = WinGetPos($hGui)
	If $aPos[0] <> -32000 And $aPos[1] <> -32000 Then
		IniWrite($sIniFile, 'Config', 'X', $aPos[0])
		IniWrite($sIniFile, 'Config', 'Y', $aPos[1])
		IniWrite($sIniFile, 'Config', 'Width', $aPos[2])
		IniWrite($sIniFile, 'Config', 'Height', $aPos[3])
	EndIf
	_GUICtrlStatusBar_Resize($hStatus)
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE

Func WM_GETMINMAXINFO($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $iMsg, $iwParam
	Local $minmaxinfo
	If $hWnd = $hGui Then
		$minmaxinfo = DllStructCreate('int;int;int;int;int;int;int;int;int;int', $ilParam)
		DllStructSetData($minmaxinfo, 7, 716)
		DllStructSetData($minmaxinfo, 8, 540)
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_GETMINMAXINFO

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg
	Local $hWndFrom = $ilParam
	Local $iCode = _WinAPI_HiWord($iwParam)
	Local $hWndEdit1 = GUICtrlGetHandle($ahPath[0])
	Local $hWndEdit2 = GUICtrlGetHandle($ahPath[1])
	Switch $iCode
		Case $EN_SETFOCUS
			GUISetState(@SW_HIDE, $hDirListGui)
			Switch $hWndFrom
				Case $hWndEdit1
					$iActiveLV = 0
					GUICtrlSetBkColor($ahPath[0], $aColorActive[0])
					GUICtrlSetColor($ahPath[0], $aColorActive[1])
					GUICtrlSetBkColor($ahPath[1], $aColorInactive[0])
					GUICtrlSetColor($ahPath[1], $aColorInactive[1])
				Case $hWndEdit2
					$iActiveLV = 1
					GUICtrlSetBkColor($ahPath[1], $aColorActive[0])
					GUICtrlSetColor($ahPath[1], $aColorActive[1])
					GUICtrlSetBkColor($ahPath[0], $aColorInactive[0])
					GUICtrlSetColor($ahPath[0], $aColorInactive[1])
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
	#forceref $hWnd, $iMsg, $iwParam
	Local $tNMHDR, $hWndFrom, $tInfo, $iItem, $sText, $sPath, $sExt
	$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
	Switch $hWndFrom
		Case GUICtrlGetHandle($hEditLV)
			Switch DllStructGetData($tNMHDR, 'Code')
				Case $NM_CLICK
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
					$iItem = DllStructGetData($tInfo, 'Index')
					GUICtrlSetData($hEditName, _GUICtrlListView_GetItemText($hEditLV, $iItem, 0))
					GUICtrlSetData($hEditPath, _GUICtrlListView_GetItemText($hEditLV, $iItem, 1))
			EndSwitch
		Case _GUICtrlListView_GetHeader($ahLV[0])
			Switch DllStructGetData($tNMHDR, 'Code')
				Case -321
					_CheckLVColWidth(0)
				Case -16
					_SetLVColOrder(0)
					ConsoleWrite("Links :" & DllStructGetData($tNMHDR, 'Code') & @CRLF)
			EndSwitch
		Case _GUICtrlListView_GetHeader($ahLV[1])
			Switch DllStructGetData($tNMHDR, 'Code')
				Case -321
					_CheckLVColWidth(1)
				Case -16
					_SetLVColOrder(1)
					ConsoleWrite("Rechts :" & DllStructGetData($tNMHDR, 'Code') & @CRLF)
			EndSwitch
		Case GUICtrlGetHandle($ahLV[0])
			Switch DllStructGetData($tNMHDR, 'Code')
				Case $NM_DBLCLK
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
					$iItem = DllStructGetData($tInfo, 'Index')
					$sText = _GUICtrlListView_GetItemText($ahLV[0], $iItem, 0)
					Switch $sText
						Case ''
							; nothing
						Case '..'
							$sPath = StringRegExpReplace(GUICtrlRead($ahPath[0]), '(.+\\).+\\', '$1')
							GUICtrlSetData($ahPath[0], $sPath)
							_CreateListViewItems($ahLV[0], $sPath)
						Case Else
							$sExt = _GUICtrlListView_GetItemText($ahLV[0], $iItem, 1)
							If $sExt <> '' Then $sExt = '.' & $sExt
							$sPath = GUICtrlRead($ahPath[0]) & $sText
							Switch $sExt
								Case '.<DIR>'
									$sPath &= '\'
									GUICtrlSetData($ahPath[0], $sPath)
									_CreateListViewItems($ahLV[0], $sPath)
								Case Else
									ShellExecute($sPath & $sExt, '', GUICtrlRead($ahPath[0]))
							EndSwitch
					EndSwitch
				Case $NM_SETFOCUS
					GUISetState(@SW_HIDE, $hDirListGui)
					$iActiveLV = 0
					GUICtrlSetBkColor($ahPath[0], $aColorActive[0])
					GUICtrlSetColor($ahPath[0], $aColorActive[1])
					GUICtrlSetBkColor($ahPath[1], $aColorInactive[0])
					GUICtrlSetColor($ahPath[1], $aColorInactive[1])
			EndSwitch
		Case GUICtrlGetHandle($ahLV[1])
			Switch DllStructGetData($tNMHDR, 'Code')
				Case $NM_DBLCLK
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
					$iItem = DllStructGetData($tInfo, 'Index')
					$sText = _GUICtrlListView_GetItemText($ahLV[1], $iItem, 0)
					Switch $sText
						Case ''
							; nothing
						Case '..'
							$sPath = StringRegExpReplace(GUICtrlRead($ahPath[1]), '(.+\\).+\\', '$1')
							GUICtrlSetData($ahPath[1], $sPath)
							_CreateListViewItems($ahLV[1], $sPath)
						Case Else
							$sExt = _GUICtrlListView_GetItemText($ahLV[1], $iItem, 1)
							If $sExt <> '' Then $sExt = '.' & $sExt
							$sPath = GUICtrlRead($ahPath[1]) & $sText
							Switch $sExt
								Case '.<DIR>'
									$sPath &= '\'
									GUICtrlSetData($ahPath[1], $sPath)
									_CreateListViewItems($ahLV[1], $sPath)
								Case Else
									ShellExecute($sPath & $sExt)
							EndSwitch
					EndSwitch
				Case $NM_SETFOCUS
					GUISetState(@SW_HIDE, $hDirListGui)
					$iActiveLV = 1
					GUICtrlSetBkColor($ahPath[1], $aColorActive[0])
					GUICtrlSetColor($ahPath[1], $aColorActive[1])
					GUICtrlSetBkColor($ahPath[0], $aColorInactive[0])
					GUICtrlSetColor($ahPath[0], $aColorInactive[1])
			EndSwitch
	EndSwitch
	$tNMHDR = ''
	$tInfo = ''
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _SetLVColOrder($iLV)
	Local $aOrder = _GUICtrlListView_GetColumnOrderArray(GUICtrlGetHandle($ahLV[$iLV]))
	_GUICtrlListView_SetColumnOrderArray(GUICtrlGetHandle($ahLV[1 - $iLV]), $aOrder)
	_GUICtrlListView_RedrawItems($ahLV[1 - $iLV], 0, _GUICtrlListView_GetItemCount($ahLV[1 - $iLV]))
	_ArrayDelete($aOrder, 0)
	$sColOrder = _ArrayToString($aOrder)
EndFunc   ;==>_SetLVColOrder

Func _CheckLVColWidth($iLV)
	ConsoleWrite("CheckLVColWidth" & @CRLF)
	For $i = 0 To 4
		_GUICtrlListView_SetColumnWidth($ahLV[1 - $iLV], $i, _GUICtrlListView_GetColumnWidth($ahLV[$iLV], $i))
	Next
EndFunc   ;==>_CheckLVColWidth

Func _Thanks()
	Local $sMsg = 'Mein Dank geht an:\n\n'
	$sMsg &= '- Jonathan Bennett & AutoIt Team\n\tfür die Programmiersprache "AutoIt"\n'
	$sMsg &= '- Gun-Food und Peethebee\n\tfür das tolle Forum "www.autoit.de"\n'
	$sMsg &= '- funkey (www.autoit.de)\n\tfür die Funktion "_PlayDefaultSystemSound"\n'
	$sMsg &= '- progandy (www.autoit.de) für die Funktionen: \n\t"_IsReparsePoint"\n\t"_WinAPI_SHGetFileInfo"\n\t"_GUIImageList_GetSystemImageList"\n\t"_GUIImageList_GetFileIconIndex"\n'
	$sMsg &= '- Raupi (www.autoit.de)\n\tfür die Verbesserungsvorschläge und Fehlerbeseitigungen\n'
	MsgBox(0, $sTitle & '   -   Danksagungen', StringFormat($sMsg, $sVersion, $sDate), 0, $hGui)
EndFunc   ;==>_Thanks

Func _ProgInfo()
	Local $sMsg = 'Version:\t%s\nDatum:\t%s\nAutor:\tOscar (www.autoit.de)\nEMail:\tOscar@elektronik-kurs.de\n\n'
	$sMsg &= 'Rechtliches:\n'
	$sMsg &= '- Dieses Programm darf, zeitlich unbegrenzt, kostenlos genutzt werden!\n'
	$sMsg &= '- Eine evtl. Weitergabe muss kostenlos, vollständig und unverändert erfolgen!\n'
	$sMsg &= '- Änderungen am Programm dürfen nur durch den Autor vorgenommen werden!\n'
	MsgBox(0, $sTitle & '   -   Programm-Informationen', StringFormat($sMsg, $sVersion, $sDate), 0, $hGui)
EndFunc   ;==>_ProgInfo

;===============================================================================
; Function Name:   _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim])
; Description::    gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
; Parameter(s):    $sPath = Startverzeichnis
;                  $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
;                  $iFlag = Auswahl
;                           0 = Dateien & Verzeichnisse
;                           1 = nur Dateien
;                           2 = nur Verzeichnisse
;                  $iFormat = Rückgabeformat
;                             0 = String
;                             1 = Array mit [0] = Anzahl
;                             2 = Nullbasiertes Array
;                  $iRecursion = Verzeichnisse rekursiv durchsuchen
;                                0 = Nein
;                                1 = Ja
;                  $sDelim = Trennzeichen für die String-Rückgabe
; Requirement(s):  AutoIt 3.3.0.0
; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
; Author(s):       Oscar (www.autoit.de)
;                  Anregungen von: bernd670 (www.autoit.de)
;===============================================================================
Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF)
	Local $hSearch, $sFile, $sReturn = ''
	If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
	$hSearch = FileFindFirstFile($sPath & '*.*')
	If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
	While True
		$sFile = FileFindNextFile($hSearch)
		If @error Then ExitLoop
		If @extended Then
			If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
			If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0)
			ContinueLoop
		EndIf
		If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
	WEnd
	FileClose($hSearch)
	If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
	If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
	Return $sReturn
EndFunc   ;==>_RecursiveFileListToArray

;===============================================================================
; Function Name:   _ByteAutoSize($iSize[, $iRound][, $iFormat][, $bThousands])
; Description::    Gibt einen Bytewert in einer bestimmten Einheit zurück
; Parameter(s):    $iSize = Größe in Byte übergeben
;                  $iRound = Anzahl der Nachkommastellen (0...8)
;                  $iFormat = bestimmt den Rückgabewert
;                     0 = Automatisch (je nach übergebenen Wert)
;                     1 = in Byte
;                     2 = in KByte
;                     3 = in MByte
;                     4 = in GByte
;                  $bThousands = Rückgabe mit Tausendertrennzeichen (True/False)
; Requirement(s):  #include <String.au3>
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _ByteAutoSize($iSize, $iRound = 2, $iFormat = 0, $bThousands = True)
	Local $aSize[4] = [' Byte', ' KByte', ' MByte', ' GByte'], $sReturn
	If $iFormat < 0 Or $iFormat > 4 Then $iFormat = 0
	If $iRound < 0 Or $iRound > 8 Then $iRound = 2
	If Not IsBool($bThousands) Then $bThousands = False
	$iSize = Abs($iSize)
	If $iFormat = 0 Then
		For $i = 30 To 0 Step -10
			If $iSize > (2 ^ $i) Then
				$iFormat = $i / 10 + 1
				ExitLoop
			EndIf
		Next
	EndIf
	If $iFormat = 0 Then $iFormat = 1
	$sReturn = StringFormat('%.' & $iRound & 'f', Round($iSize / (2 ^ (($iFormat - 1) * 10)), $iRound))
	If $bThousands Then $sReturn = _StringAddThousandsSep($sReturn, '.', ',')
	Return $sReturn & $aSize[$iFormat - 1]
EndFunc   ;==>_ByteAutoSize

;===============================================================================
; Function Name:   _GetUniqueFileName($sPath)
; Description::    Wenn der Dateiname bereits existiert wird ein Zähler
;                  in Form von: "_(1)" an den Dateinamen angehängt.
; Parameter(s):    $sPath = kompletter Pfad der Datei
; Requirement(s):  -
; Return Value(s): bei Erfolg = der (neue) Dateiname
;                  bei Fehler wird @error = 1 (Pfad falsch angegeben)
; Author(s):       Oscar (www.autoit.de)
;===============================================================================
Func _GetUniqueFileName($sPath)
	Local $aPath, $sNumber = '', $iCount = 0
	$aPath = StringRegExp($sPath, '(.+\\)(.+?)(?:_\(\d*\))*(\..+)', 3)
	If @error Then Return SetError(1, 0, 0)
	While FileExists($aPath[0] & $aPath[1] & $sNumber & $aPath[2])
		$iCount += 1
		$sNumber = '_(' & $iCount & ')'
	WEnd
	Return $aPath[0] & $aPath[1] & $sNumber & $aPath[2]
EndFunc   ;==>_GetUniqueFileName


#cs
	***** Ab hier Funktionen von anderen Usern *****
#ce

; Author: progandy (www.autoit.de)
Func _IsReparsePoint($FLS)
	Dim Static $K32 = DllOpen('kernel32.dll')
	Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
	If @error Then Return SetError(1, @error, False)
	Return BitAND($DA[0], 1024) = 1024
EndFunc   ;==>_IsReparsePoint

; Author: progandy (www.autoit.de)
Func _GUIImageList_GetSystemImageList($bLargeIcons = False)
	Local $dwFlags, $hIml, $FileInfo = DllStructCreate($tagSHFILEINFO)
	$dwFlags = BitOR($SHGFI_USEFILEATTRIBUTES, $SHGFI_SYSICONINDEX)
	If Not ($bLargeIcons) Then
		$dwFlags = BitOR($dwFlags, $SHGFI_SMALLICON)
	EndIf
;~    '// Load the image list - use an arbitrary file extension for the
;~    '// call to SHGetFileInfo (we don't want to touch the disk, so use
;~    '// FILE_ATTRIBUTE_NORMAL && SHGFI_USEFILEATTRIBUTES).
	$hIml = _WinAPI_SHGetFileInfo(".txt", $FILE_ATTRIBUTE_NORMAL, _
			DllStructGetPtr($FileInfo), DllStructGetSize($FileInfo), $dwFlags)
	Return $hIml
EndFunc   ;==>_GUIImageList_GetSystemImageList

; Author: progandy (www.autoit.de)
Func _WinAPI_SHGetFileInfo($pszPath, $dwFileAttributes, $psfi, $cbFileInfo, $uFlags)
	Local $return = DllCall("shell32.dll", "DWORD*", "SHGetFileInfo", "str", $pszPath, "DWORD", $dwFileAttributes, "ptr", $psfi, "UINT", $cbFileInfo, "UINT", $uFlags)
	If @error Then Return SetError(@error, 0, 0)
	Return $return[0]
EndFunc   ;==>_WinAPI_SHGetFileInfo

; Author: progandy (www.autoit.de)
Func _GUIImageList_GetFileIconIndex($sFileSpec, $bLargeIcons = False, $bForceLoadFromDisk = False)
	Local $dwFlags, $FileInfo = DllStructCreate($tagSHFILEINFO)
	$dwFlags = $SHGFI_SYSICONINDEX
	If $bLargeIcons Then
		$dwFlags = BitOR($dwFlags, $SHGFI_LARGEICON)
	Else
		$dwFlags = BitOR($dwFlags, $SHGFI_SMALLICON)
	EndIf
;~ ' We choose whether to access the disk or not. If you don't
;~ ' hit the disk, you may get the wrong icon if the icon is
;~ ' not cached. But the speed is very good!
	If Not $bForceLoadFromDisk Then
		$dwFlags = BitOR($dwFlags, $SHGFI_USEFILEATTRIBUTES)
	EndIf
;~ ' sFileSpec can be any file. You can specify a
;~ ' file that does not exist and still get the
;~ ' icon, for example sFileSpec = "C:\PANTS.DOC"
	Local $lR = _WinAPI_SHGetFileInfo( _
			$sFileSpec, $FILE_ATTRIBUTE_NORMAL, DllStructGetPtr($FileInfo), DllStructGetSize($FileInfo), _
			$dwFlags _
			)
	If ($lR = 0) Then
		Return SetError(1, 0, -1)
	Else
		Return DllStructGetData($FileInfo, "iIcon")
	EndIf
EndFunc   ;==>_GUIImageList_GetFileIconIndex

; #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

; #FUNCTION# ====================================================================================================================
; Name...........: _StringAddThousandsSep
; Description ...: Returns the original numbered string with the Thousands delimiter inserted.
; Syntax.........: _StringAddThousandsSep($sString[, $sThousands = -1[, $sDecimal = -1]])
; Parameters ....: $sString    - The string to be converted.
;                  $sThousands - Optional: The Thousands delimiter
;                  $sDecimal   - Optional: The decimal delimiter
; Return values .: Success - The string with Thousands delimiter added.
; Author ........: SmOke_N (orignal _StringAddComma
; Modified.......: Valik (complete re-write, new function name)
; ===============================================================================================================================
Func _StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
	If $sString = '-' Then Return $sString ; This Line is only for FileCommander
	Local $sResult = "" ; Force string
	Local $rKey = "HKCU\Control Panel\International"
	If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
	If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
	Local $aNumber = StringRegExp($sString, "(\D?\d+)\D?(\d*)", 1) ; This one works for negatives.
	If UBound($aNumber) = 2 Then
		Local $sLeft = $aNumber[0]
		While StringLen($sLeft)
			$sResult = $sThousands & StringRight($sLeft, 3) & $sResult
			$sLeft = StringTrimRight($sLeft, 3)
		WEnd
		$sResult = StringTrimLeft($sResult, StringLen($sThousands)) ; Strip leading thousands separator
		If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
	EndIf
	Return $sResult
EndFunc   ;==>_StringAddThousandsSep