Recent File List

    • Offizieller Beitrag

    Hi,
    ihr kennt alle aus jeder Anwendung, in der man Dateien öffnen muß, die Recent File List - die Auflistung der zuletzt genutzten Dateien in der Reihenfolge ihres Aufrufs bis zu einer maximalen Anzahl.
    Ich habe das gerade in einem Projekt benötigt und es in eine Funktion gepackt. Vielleicht kann es ja jemand mal gebrauchen.
    Wahlweise kann die letzte Datei an erster oder letzter Position stehen.
    Da ich nicht unendlich viele Parameter übergeben wollte, sind die Angaben für die INI-Datei fix. Wenn man andere Sektions- und Schlüsselnamen verwenden möchte, läßt sich dies aber problemlos in der Funktion anpassen.

    Hier auch mal ein durchkommentiertes Bsp., wie man es verwenden könnte. Und falls wieder die Frage kommt, ob das (Bsp.) auch mit GUIGetMsg() geht: Im Prinzip ja, aber nur mit einem erheblichen Aufwand, da das Makro @GUI_CtrlID nur im OnEventMode zur Verfügung steht.

    Spoiler anzeigen
    [autoit]

    #cs MUSTER INI-Datei
    [recent_num]
    max=5
    aktuell=0

    [/autoit] [autoit][/autoit] [autoit]

    [recent_file]
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    #include<GUIConstantsEx.au3>
    #include<Array.au3>
    Opt("GUIOnEventMode",1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $INIPath = @ScriptDir & '\TEST_settings.INI', $path
    Global $maxFiles = 5 ; Vorbelegung, wird überschrieben falls in INI anderer Wert
    Global $currCountFiles = 0 ; Vorbelegung, wird überschrieben falls in INI anderer Wert
    Global $aRecentFiles[1] ; zwingend als Array deklarieren, wird im Prog angepaßt
    Global $aItemID[1][2] = [[-1,0]] ; führt ID's der MenüItems, Vorbelegung für Überprüfung

    [/autoit] [autoit][/autoit] [autoit]

    If Not FileExists($INIPath) Then ; Erstellung INI falls noch nicht vorhanden
    IniWrite($INIPath, 'recent_num', 'maximum', 5)
    IniWrite($INIPath, 'recent_num', 'aktuell', 0)
    Else ; Auslesen aktuell gespeicherter Werte aus der INI
    $maxFiles = IniRead($INIPath, 'recent_num', 'maximum', 5)
    $currCountFiles = IniRead($INIPath, 'recent_num', 'aktuell', 0)
    If $currCountFiles > 0 Then
    $aRecentFiles = IniReadSection($INIPath, 'recent_file')
    ReDim $aItemID[$aRecentFiles[0][0]][2] ; Array für MenüItems auf Anzahl gespeicherter Dateien anpassen
    $aItemID[0][0] = 1 ; Vorbelegung -1 aufheben für Überprüfung
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $GUI = GUICreate('Recent Files')
    GUISetOnEvent($GUI_EVENT_CLOSE, '_ende')
    $btn = GUICtrlCreateButton('Datei wählen', 100, 50, 120, 25)
    GUICtrlSetOnEvent(-1, '_btnClick')
    $mnu = GUICtrlCreateMenu('Datei')
    $item_end = GUICtrlCreateMenuItem('Beenden',$mnu)
    GUICtrlSetOnEvent(-1, '_ende')
    GUICtrlCreateMenuItem('',$mnu)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    If $aItemID[0][0] <> -1 Then ; wenn Einträge in INI, MenüItems erstellen
    _Array2DDelete($aRecentFiles, 0) ; Zähler löschen für gleiche Größe beider Arrays
    For $i = 0 To UBound($aRecentFiles) -1
    $split = _StringSplitOnce($aRecentFiles[$i][1], '\', -1) ; gespeicherten Pfad splitten
    $aItemID[$i][0] = GUICtrlCreateMenuItem($split[1], $mnu) ; Dateinamen als MenüItem erstellen
    GUICtrlSetOnEvent(-1, '_itemClick')
    $aItemID[$i][1] = $i ; Zuweisung Arrayposition zur Ctrl-ID
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _ende()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _btnClick()
    Local $split
    $path = FileOpenDialog('Bitte Datei auswählen', @ScriptDir, "Textdateien (*.txt;*.log;*.bat;*.ini)", 3)
    If @error Then Return MsgBox(262192, 'Achtung', 'Keine Datei gewählt')
    _RecentFiles($INIPath, $aRecentFiles, $path, $currCountFiles, $maxFiles, 0) ; aktuelle Datei an oberster Position speichern
    If $aItemID[0][0] = -1 Then ; noch kein MenüItem vorhanden
    $split = _StringSplitOnce($aRecentFiles[0][1], '\', -1) ; Dateinamen absplitten
    $aItemID[0][0] = GUICtrlCreateMenuItem($split[1], $mnu) ; Item erstellen, ID speichern
    GUICtrlSetOnEvent(-1, '_itemClick')
    $aItemID[0][1] = 0 ; Arrayposition des kpl. Pfades zuweisen
    Else ; bereits MenüItem vorhanden
    For $i = 0 To UBound($aItemID) -1 ; alle bestehenden Items löschen
    GUICtrlDelete($aItemID[$i][0])
    Next
    ReDim $aItemID[UBound($aRecentFiles)][2] ; Array für Item-ID auf neue Größe anpassen
    For $i = 0 To UBound($aItemID) -1 ; und Items erstellen, ID's speichern, Pos. zuweisen
    $split = _StringSplitOnce($aRecentFiles[$i][1], '\', -1)
    $aItemID[$i][0] = GUICtrlCreateMenuItem($split[1], $mnu)
    GUICtrlSetOnEvent(-1, '_itemClick')
    $aItemID[$i][1] = $i
    Next
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _itemClick()
    Local $index = _ArraySearch($aItemID, @GUI_CtrlId, 0, 0, 0, 0, 1, 0) ; im ID-Array nach Position des geklickten Items suchen
    MsgBox(0, 'Geklickter Pfad', $aRecentFiles[$index][1]) ; Eintrag aus File-Liste an dieser Position verwerten
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;==================================================================================================
    ; Function Name: _RecentFiles(ByRef $INI, ByRef $ARRAY, $FILE, ByRef $CURRCOUNT, ByRef $MAXCOUNT [, $ASC=1])
    ; Description:: Verwalten der zuletzt genutzten Dateien in einer INI
    ; wahlweise an Pos. 0 die älteste (Standard) oder neueste Datei
    ; Parameter(s): $INI Pfad der INI-Datei
    ; $ARRAY Das 2D-Array mit den Dateien, Rückgabe von INIReadSection
    ; Falls noch nicht existent, muß die übergebene Variable auf jeden Fall
    ; ein Array sein!
    ; $FILE aktuelle Datei/Pfad, zum Hinterlegen in der INI
    ; $CURRCOUNT aktuelle Anzahl hinterlegter Dateien/Pfade
    ; $MAXCOUNT maximal zulässige Anzahl zu hinterlegender Dateien/Pfade
    ; $ASC aktuelle Datei wird an erste Stelle (Pos 0 im Array) oder an
    ; letzte Stelle (Ubound-1 im Array)-Standard geschrieben
    ; Requirement(s): INI mit Sektionen
    ; [recent_num] und Schlüsseln "maximum, aktuell"
    ; (Variablen zum Einlesen der Werte und Übergeben an die Funktion)
    ; [recent_file] (Schlüsselwort ist für alle Einträge "file")
    ; Wenn die INI mit INIReadSection eingelesen wird, löscht die Funktion Zeile 0 (Zähler)
    ; UDF _Array2DDelete()
    ; #include <Array.au3>
    ; Return Value(s): Keine
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _RecentFiles(ByRef $INI, ByRef $ARRAY, $FILE, ByRef $CURRCOUNT, ByRef $MAXCOUNT, $ASC=1)
    Local $index
    If UBound($ARRAY, 2) Then
    If IsNumber($ARRAY[0][0]) Then _Array2DDelete($ARRAY, 0)
    EndIf
    If $ASC = 1 Then
    If UBound($ARRAY, 2) Then
    $index = _ArraySearch($ARRAY, $FILE, 0, 0, 0, 0, 1, 1)
    If $index = -1 Then
    If $CURRCOUNT = $MAXCOUNT -1 Then
    _Array2DDelete($ARRAY, 0)
    Else
    $CURRCOUNT += 1
    IniWrite($INI, 'recent_num', 'aktuell', $CURRCOUNT)
    EndIf
    Else
    _Array2DDelete($ARRAY, $index)
    EndIf
    ReDim $ARRAY[UBound($ARRAY)+1][2]
    Else
    ReDim $ARRAY[1][2]
    EndIf
    $ARRAY[UBound($ARRAY)-1][0] = 'file'
    $ARRAY[UBound($ARRAY)-1][1] = $FILE
    Else
    If UBound($ARRAY, 2) Then
    $index = _ArraySearch($ARRAY, $FILE, 0, 0, 0, 0, 1, 1)
    If $index = -1 Then
    If $CURRCOUNT < $MAXCOUNT -1 Then
    $CURRCOUNT += 1
    IniWrite($INI, 'recent_num', 'aktuell', $CURRCOUNT)
    ReDim $ARRAY[UBound($ARRAY)+1][2]
    EndIf
    Else
    _Array2DDelete($ARRAY, $index)
    ReDim $ARRAY[UBound($ARRAY)+1][2]
    EndIf
    For $i = UBound($ARRAY)-1 To 1 Step -1
    $ARRAY[$i][0] = 'file'
    $ARRAY[$i][1] = $ARRAY[$i-1][1]
    Next
    $ARRAY[0][1] = $FILE
    Else
    ReDim $ARRAY[1][2]
    $ARRAY[UBound($ARRAY)-1][0] = 'file'
    $ARRAY[UBound($ARRAY)-1][1] = $FILE
    EndIf
    EndIf
    IniWriteSection($INI, 'recent_file', $ARRAY, 0)
    EndFunc ;==>_RecentFiles

    [/autoit] [autoit][/autoit] [autoit]

    Func _Array2DDelete(ByRef $ARRAY, $iDEL)
    Local $i, $k, $l
    If ( Not IsArray($ARRAY) ) Then
    SetError(1)
    Return 0
    EndIf
    If ( $iDEL < 0 ) Or ( $iDEL > UBound($ARRAY)-1 ) Then
    SetError(2)
    Return 0
    EndIf
    Local $UBound2nd = UBound($ARRAY,2)
    If @error = 2 Then
    Local $arTmp[UBound($ARRAY)-1]
    $k = 0
    For $i = 0 To UBound($ARRAY)-1
    If $i <> $iDEL Then
    $arTmp[$k] = $ARRAY[$i]
    $k += 1
    EndIf
    Next
    Else
    Local $arTmp[UBound($ARRAY)-1][$UBound2nd]
    $k = 0
    For $i = 0 To UBound($ARRAY)-1
    If $i <> $iDEL Then
    For $l = 0 To $UBound2nd-1
    $arTmp[$k][$l] = $ARRAY[$i][$l]
    Next
    $k += 1
    EndIf
    Next
    EndIf
    $ARRAY = $arTmp
    Return -1
    EndFunc ;==>_Array2DDelete

    [/autoit] [autoit][/autoit] [autoit]

    Func _StringSplitOnce($STRING, $DELIM, $OCCURENCE=1)
    If $STRING = '' Then Return SetError(1)
    If $DELIM = '' Then Return SetError(2)
    Local $Out[2]
    Local $len = StringLen($STRING)
    Local $pos = StringInStr($STRING, $DELIM, 1, $OCCURENCE)
    If @error Then Return SetError(3)
    $Out[0] = StringLeft($STRING, $pos-1)
    $Out[1] = StringRight($STRING, $len-$pos)
    Return $Out
    EndFunc ;==>_StringSplitOnce

    [/autoit]