- 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
#cs MUSTER INI-Datei
[recent_num]
max=5
aktuell=0
[recent_file]
#ce
#include<GUIConstantsEx.au3>
#include<Array.au3>
Opt("GUIOnEventMode",1)
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
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
$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()
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
While True
Sleep(100)
WEnd
Func _ende()
Exit
EndFunc
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
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
;==================================================================================================
; 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
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
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