#include <GUIConstants.au3>
#Include <GuiList.au3>
#include <file.au3>
#Include <Misc.au3>
#Include <GuiStatusBar.au3>
Dim $Extension = "", $Pfad = "", $Daten[1], $arDisp[1], $currPosIndex, $file, $fileShort, $anzahl, $progress_step, $progress_val = 0
Dim $ListPfad = @MyDocumentsDir & "\", $ListFile = "Rekursiv_List.txt", $ListFileShort = "Rekursiv_Short.txt"
Dim $ListFileShortPrint = "Rekursiv_Short_P.txt", $a_PartsText[2] = ["", ""], $a_PartsRightEdge[2] = [40, -1], $PfadExec
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Ordner- / Dateisuche (rekursiv)", 600, 458, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "AForm1Close")
GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, "SpecialEvents")
$List1 = GUICtrlCreateList("", 24, 106, 550, 354, $WS_VSCROLL)
GUICtrlSetOnEvent(-1, "ListClick")
$Label1 = GUICtrlCreateLabel("Pfad:", 28, 16, 29, 17)
$iPath = GUICtrlCreateInput("", 59, 13, 280, 21, $ES_READONLY)
$Checkbox1 = GUICtrlCreateCheckbox("nur Ordner", 24, 47, 78, 17)
GUICtrlSetOnEvent(-1, "ACheckbox1Click")
$Checkbox2 = GUICtrlCreateCheckbox("ganzen Pfad zeigen", 24, 79, 130, 17)
GUICtrlSetOnEvent(-1, "ACheckbox2Click")
GUICtrlSetState(-1, $GUI_HIDE)
$Checkbox3 = GUICtrlCreateCheckbox("kompletten Pfad drucken", 435, 79, 160, 17)
GUICtrlSetState(-1, $GUI_HIDE)
$lExtension = GUICtrlCreateLabel("Erweiterung", 185, 41, 90, 17)
$lExtension1 = GUICtrlCreateLabel("z.B. 'exe' oder ' * '", 185, 58, 900,17)
$iExtension = GUICtrlCreateInput("", 282, 45, 57, 21, $ES_CENTER)
$bPath = GUICtrlCreateButton("Pfad wählen", 349, 13, 70, 21, 0)
GUICtrlSetOnEvent(-1, "bPathClick")
$lTipTime = GUICtrlCreateLabel("Zeit für ToolTipp:", 185, 80)
$iTipTime = GUICtrlCreateInput ("4", 282, 77, 57, 21, $ES_CENTER)
$updown = GUICtrlCreateUpdown($iTipTime)
$bAuslesen = GUICtrlCreateButton("Auslesen", 349, 45, 70, 21, 0)
GUICtrlSetOnEvent(-1, "bAuslesenClick")
$bPrint = GUICtrlCreateButton("Drucken", 349, 77, 70, 21, 0)
GUICtrlSetOnEvent(-1, "bPrintClick")
$bClear = GUICtrlCreateButton("Löschen", 505, 45, 70, 21, 0)
GUICtrlSetOnEvent(-1, "bClearClick")
$bEnde = GUICtrlCreateButton("Ende", 505, 13, 70, 21, 0)
GUICtrlSetOnEvent(-1, "bEndeClick")
$StatusBar1 = _GUICtrlStatusBarCreate($Form1, $a_PartsRightEdge, $a_PartsText)
$progressbar1 = _GUICtrlStatusBarCreateProgress($StatusBar1, 1)
GUICtrlSetColor(-1,32250)
GUICtrlSetState(-1, $GUI_HIDE)

$Busy = GUICreate("",160,110,-1,-1,$WS_POPUP)
GUISetBkColor(0x708090)
$label_busy = GUICtrlCreateLabel("Einen Moment bitte." & @LF & @LF & "Die notwendigen Daten" _
		& @LF & "werden ermittelt..", 20, 15, 120, 100, $SS_CENTER)
GUICtrlSetFont(-1, 10, Default,2)
GUICtrlSetColor(-1, 0xF0E68C)

$RightMenu = GUICreate("RightMenu", 135, 71, -1, -1, $WS_POPUP)
$bShellEx = GUICtrlCreateButton("Datei Ausführen", 2, 2, 130, 20, 0)
GUICtrlSetOnEvent(-1, "bShellExClick")
$bClipboard = GUICtrlCreateButton("Copy To Clipboard", 2, 24, 130, 20, 0)
GUICtrlSetOnEvent(-1, "bClipboardClick")
$bEscR_Menu = GUICtrlCreateButton("Abbrechen", 2, 48, 130, 20, 0)
GUICtrlSetOnEvent(-1, "bEscR_MenuClick")

GUISetState(@SW_SHOW, $Form1)

While 1
	Sleep(100)
WEnd

Func SpecialEvents()    
    If @GUI_CTRLID = $GUI_EVENT_SECONDARYDOWN Then
		$ctrlfocus = ControlGetFocus($Form1,"Ordner- / Dateisuche (rekursiv)")
		If $ctrlfocus = "ListBox1" And GUICtrlRead($Checkbox2) = 1  And _
			_GUICtrlListGetText($List1, _GUICtrlListGetCaretIndex($List1)) <> "" _
		Then
			$PfadExec = _GUICtrlListGetText($List1, _GUICtrlListGetCaretIndex($List1))
			If $Extension = "n" Then 
				GUICtrlSetState($bShellEx, $GUI_DISABLE)
				GUISetState(@SW_SHOW, $RightMenu)
			Else
				GUICtrlSetState($bShellEx, $GUI_ENABLE)
				GUISetState(@SW_SHOW, $RightMenu)
			EndIf	
		EndIf
    EndIf    
EndFunc

Func ACheckbox1Click()
	If GUICtrlRead($Checkbox1) = 1 Then
		GUICtrlSetState($lExtension,$GUI_HIDE)
		GUICtrlSetState($lExtension1,$GUI_HIDE)
		GUICtrlSetState($iExtension,$GUI_HIDE)
	Else
		GUICtrlSetState($lExtension,$GUI_SHOW)
		GUICtrlSetState($lExtension1,$GUI_SHOW)
		GUICtrlSetState($iExtension,$GUI_SHOW)
	EndIf
EndFunc

Func ACheckbox2Click()
	_GUICtrlStatusBarSetText($StatusBar1, "", 0)
	_GUICtrlStatusBarSetText($StatusBar1, "", 1)
	_GUICtrlStatusBarSetBKColor($StatusBar1, 0xD3D3D3)
	If GUICtrlRead($Checkbox2) = 1 Then
		_DisplayListLong()
	Else
		_DisplayListShort()
	EndIf
EndFunc

Func AForm1Close()
	Exit
EndFunc

Func bClearClick()
	GUICtrlSetData($iPath,"")
	GUICtrlSetData($iExtension,"")
	GUICtrlSetData($List1,"")
	GUICtrlSetState($Checkbox1, $GUI_UNCHECKED)
	GUICtrlSetState($Checkbox2, $GUI_UNCHECKED)
	GUICtrlSetState($Checkbox3, $GUI_UNCHECKED)
	GUICtrlSetState($lExtension,$GUI_SHOW)
	GUICtrlSetState($lExtension1,$GUI_SHOW)
	GUICtrlSetState($iExtension,$GUI_SHOW)
	GUICtrlSetState($Checkbox2, $GUI_HIDE)
	GUICtrlSetState($Checkbox3, $GUI_HIDE)
	_GUICtrlStatusBarSetText($StatusBar1, "", 0)
	_GUICtrlStatusBarSetText($StatusBar1, "", 1)
	_GUICtrlStatusBarSetBKColor($StatusBar1, 0xD3D3D3)
	$Pfad = ""
	$PfadExec = ""
EndFunc

Func bAuslesenClick()
Dim $tmp = "", $asc
	If $Pfad = "" Then
		MsgBox(0, "ACHTUNG!", "Es wurde kein Pfad ausgewählt!")
		bPathClick()
		Return 0
	EndIf
	If GUICtrlRead($Checkbox1) = 1 Then
		$Extension = "n"
	Else
		$Extension = GUICtrlRead($iExtension)
		If Not StringInStr($Extension, "*") Then
			$len = StringLen($Extension)
			For $i = 1 To $len
				$asc = Asc(StringLower(StringMid($Extension,$i,1)))
				If ($asc > 47 And $asc < 58) Or ($asc > 96 And $asc < 123) Then $tmp = $tmp & StringMid($Extension,$i,1)
			Next
			$Extension = $tmp
			If StringLen($Extension) > 3 Then
				$tmp = MsgBox(4,"ACHTUNG!", "Die Erweiterung ist länger als 3 Zeichen."& @LF & @LF & "                         " & _
						$Extension & @LF & @LF & "              Wollen Sie korrigieren?" )
				If $tmp = 6 Then
					GUICtrlSetState($iExtension, $GUI_FOCUS)
					Return 0
				EndIf
			ElseIf StringLen($Extension) = 0 Then
				MsgBox(0,"ACHTUNG!", "Die Erweiterung wurde nicht festgelegt!")
				GUICtrlSetState($iExtension, $GUI_FOCUS)
				Return 0
			EndIf
		EndIf
	EndIf
	GUISetState(@SW_SHOW, $Busy)
	_WriteAllFiles()
	GUISetState(@SW_HIDE, $Busy)
	_DisplayListShort()
	GUICtrlSetState($Checkbox2, $GUI_SHOW)
	GUICtrlSetState($Checkbox3, $GUI_SHOW)
EndFunc

Func ListClick()
	$currPosIndex = _GUICtrlListGetCaretIndex($List1)
	$info = _GUICtrlListGetText($List1, $currPosIndex)
	$tmp = StringSplit($info, "\")
	If $tmp[0] > 3 Then
		$inf1 = ""
		$inf2 = ""
		$split = Floor($tmp[0] / 2)+1
		For $i = 1 To $split
			$inf1 = $inf1 & $tmp[$i] & "\"
		Next
		For $i = $split+1 To $tmp[0]
			$inf2 = $inf2 & $tmp[$i] & "\"
		Next
		$info = $inf1 & @LF & $inf2
	EndIf
	If StringRight($info, 1) = "\" Then $info = StringTrimRight($info, 1)
	_GUICtrlStatusBarSetBKColor($StatusBar1, 0x90EE90)
	GUICtrlSetFont($StatusBar1, 10, Default,2)
	_GUICtrlStatusBarSetText($StatusBar1, $currPosIndex+1, 0)
	_GUICtrlStatusBarSetText($StatusBar1, $info, 1)
	ToolTip("(" & $currPosIndex+1 & ".) " & $info)
	Sleep(GUICtrlRead($iTipTime)*1000)
	ToolTip("")
EndFunc

Func bEndeClick()
	Exit
EndFunc

Func bPathClick()
	$Pfad = FileSelectFolder("Bitten den Pfad auswählen","",6)
	If StringRight($Pfad, 1) <> "\" Then $Pfad = $Pfad & "\"
	GUICtrlSetData($iPath,$Pfad)
	If GUICtrlRead($iPath) = "\" Then 
		GUICtrlSetData($iPath,"")
		$Pfad = ""
	EndIf
EndFunc

Func bPrintClick()
	If GUICtrlRead($Checkbox3) = 1 Then
		_FilePrintCom($ListPfad & $ListFile)	; Ausgabe auf Standard-Drucker
	Else
		_FilePrintCom($ListPfad & $ListFileShortPrint)
	EndIf
EndFunc

Func bClipboardClick()
	ClipPut($PfadExec)
	GUISetState(@SW_HIDE, $RightMenu)
EndFunc
		
Func bEscR_MenuClick()
	GUISetState(@SW_HIDE, $RightMenu)
EndFunc
		
Func bShellExClick()
	GUISetState(@SW_HIDE, $RightMenu)
	ShellExecute($PfadExec)
EndFunc

Func _WriteAllFiles()
	If FileExists($ListPfad & "\" & $ListFile) Then _
		FileMove($ListPfad & "\" & $ListFile, $ListPfad & "\" & "Rekursiv_List.bak", 1)
	If FileExists($ListPfad & "\" & $ListFileShort) Then _
		FileMove($ListPfad & "\" & $ListFileShort, $ListPfad & "\" & "Rekursiv_List_Short.bak", 1)
	If FileExists($ListPfad & "\" & $ListFileShortPrint) Then _
		FileMove($ListPfad & "\" & $ListFileShortPrint, $ListPfad & "\" & "Rekursiv_Short_P.bak", 1)
	If $Extension = "n" Then
		$Daten = _GetFileList($Pfad,$Extension,1)	; alle Ordner
	Else
		If Not StringInStr($Extension, "*") Then
			$Daten = _GetFileList($Pfad,"*." & $Extension)	; Dateien mit gewählter Erweiterung
		Else
			$Daten = _GetFileList($Pfad,"*.*")				; alle Dateien
		EndIf
	EndIf
	If Not IsArray($Daten) Or $Daten[0] = 0 Then
		GUICtrlSetData($List1, "Keine Dateien/Ordner gemäß Suchmuster vorhanden.")
		Return 0
	EndIf
	$file = FileOpen($ListPfad & $ListFile, 1)
	$fileShort = FileOpen($ListPfad & $ListFileShort, 1)
	$fileShortPrint = FileOpen($ListPfad & $ListFileShortPrint, 1)
	For $i = 1 To $Daten[0]
		FileWriteLine($file, $Daten[$i])
		$var = StringSplit($Daten[$i], "\")
		FileWriteLine($fileShort, $var[0] & "|" & $var[$var[0]])	; Anz. Elemente & letztes Element
		FileWriteLine($fileShortPrint, $var[$var[0]])
	Next
	FileClose($file)
	FileClose($fileShort)
	FileClose($fileShortPrint)
EndFunc

Func _DisplayListLong()
	GUICtrlSetData($List1, "")
	_FileReadToArray($ListPfad & $ListFile, $arDisp)
	$anzahl = $arDisp[0]-1
	$v = 15 ; Verzögerungszeit für Progressbar (1,5 sec gesamt)
	$progress_step = (100 / $anzahl)
	If $anzahl < 100 Then $v = 1000 / $anzahl
	GUICtrlSetState($progressbar1, $GUI_SHOW)
	For $i = 1 To $arDisp[0]-1
		GUICtrlSetData($List1, $arDisp[$i])
		$tmp = Floor($progress_val)
		$progress_val = $progress_val + $progress_step
		If Floor($progress_val) > $tmp Then
			GUICtrlSetData ($progressbar1,Floor($progress_val))
			Sleep($v) ; dadurch kein Springen der Progressbar
		EndIf
	Next
	_GUICtrlListSetTopIndex($List1, 0)
	GUICtrlSetData ($progressbar1, 100)
	Sleep(1200)
	GUICtrlSetData ($progressbar1, 0)
	GUICtrlSetState($progressbar1, $GUI_HIDE)
EndFunc

Func _DisplayListShort()
	GUICtrlSetData($List1, "")
	_FileReadToArray($ListPfad & $ListFileShort, $arDisp)
	$anzahl = $arDisp[0]-1
	$v = 15 ; Verzögerungszeit für Progressbar (1,5 sec gesamt)
	$progress_step = (100 / $anzahl)
	If $anzahl < 100 Then $v = 1000 / $anzahl
	GUICtrlSetState($progressbar1, $GUI_SHOW)
	For $i = 1 To $arDisp[0]-1
		$var = StringSplit($arDisp[$i], "|")
		$point = ""
		If $var[1] > 1 Then
			For $j = 1 To $var[1]-1
				$point = $point & ". "
			Next
		EndIf
		GUICtrlSetData($List1, $point & $var[2])
		$tmp = Floor($progress_val)
		$progress_val = $progress_val + $progress_step
		If Floor($progress_val) > $tmp Then
			GUICtrlSetData ($progressbar1,Floor($progress_val))
			Sleep($v) ; dadurch kein Springen der Progressbar
		EndIf
	Next
	_GUICtrlListSetTopIndex($List1, 0)
	GUICtrlSetData ($progressbar1, 100)
	Sleep(1200)
	GUICtrlSetData ($progressbar1, 0)
	GUICtrlSetState($progressbar1, $GUI_HIDE)
EndFunc


; Function:		_FilePrintCom()
; Author:		jos van der Zande
Func _FilePrintCom($iFile)
	If Not FileExists($iFile) Then Return SetError(1,0,0)
	$objShellApp = ObjCreate("Shell.Application")
	$objShellApp.ShellExecute($iFile,0,0,"PRINT",0)
EndFunc

; Function:		_GetFileList()
; Author:		jos van der Zande
;				Einbindung des $DIR_ONLY-Flag von BugFix
Func _GetFileList($T_DIR,$T_MASK,$DIR_ONLY=0)
	Dim $N_DIRNAMES[200000] ; max number of directories that can be scanned
	Local $N_DIRCOUNT = 0
	Local $N_FILE
	Local $N_SEARCH
	Local $N_TFILE
	Local $N_OFILE
	Local $T_FILENAMES
	Local $T_FILECOUNT
	Local $T_DIRCOUNT = 1
	; check Filemask \ for empty File-Array by GetDirOnly
	If $T_MASK = "n" Then $T_MASK = "*.no"
	; remove the end \ If specified
	If StringRight($T_DIR,1) = "\" Then $T_DIR = StringTrimRight($T_DIR,1)
	$N_DIRNAMES[$T_DIRCOUNT] = $T_DIR
	; Exit if base dir doesn't exists
	If Not FileExists($T_DIR) Then Return 0
	; keep on looping until all directories are scanned
	While $T_DIRCOUNT > $N_DIRCOUNT
		$N_DIRCOUNT = $N_DIRCOUNT + 1
		; find all subdirs in this directory and save them in a array
		$N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\*.*")
		While 1
			$N_FILE = FileFindNextFile($N_SEARCH)
			If @error Then ExitLoop
			; skip these references
			If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
			$N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
			; if Directory than add to the list of directories to be processed
			If StringInStr(FileGetAttrib( $N_TFILE ),"D") > 0 Then
				$T_DIRCOUNT = $T_DIRCOUNT + 1
				$N_DIRNAMES[$T_DIRCOUNT] = $N_TFILE
			EndIf
		Wend
		FileClose($N_SEARCH)      ; find all Files that mtach the MASK
		$N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\" & $T_MASK )
		If $N_SEARCH = -1 Then ContinueLoop
		While 1
			$N_FILE = FileFindNextFile($N_SEARCH)
			If @error Then ExitLoop
			; skip these references
			If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
			$N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
			; if Directory than add to the list of directories to be processed
			If StringInStr(FileGetAttrib( $N_TFILE ),"D") = 0 Then
				$T_FILENAMES  = $T_FILENAMES & $N_TFILE & @CR
				$T_FILECOUNT = $T_FILECOUNT + 1
				;MsgBox(0,'filecount ' & $T_FILECOUNT ,$N_TFILE)
			EndIf
		Wend
		FileClose($N_SEARCH)
	Wend
	If $DIR_ONLY = 0 Then
		$T_FILENAMES  = StringTrimRight($T_FILENAMES,1)
		$N_OFILE = StringSplit($T_FILENAMES,@CR)
		Return( $N_OFILE )
	Else
		ReDim $N_DIRNAMES[$N_DIRCOUNT+1]
		$N_DIRNAMES[0] = $N_DIRCOUNT
		Return $N_DIRNAMES
	EndIf
EndFunc   ;==>_GetFileList