Wenn wir von speziellen Ordnern reden meinen wir Verzeichnisse wie den Favoritenordner, Desktopordner, Send-To-Ordner usw. Also Ordner die bei jedem Rechner und bei jedem angemeldeten Benutzer wo anders im Dateisystem liegen kann. Den kompletten Pfad zu diesen Ordnern steckt auch teilweise in der Registry. Da sich diese Pfade laut Microsoft ändern können soll man die Funktion
SHGetSpecialFolderLocation benutzen.
Die Funktion
SHGETSPECIALFOLDERLOCATION bekommt unter anderem als Parameter eine Folder-Id übergeben. Diese Folder-Id gibt an von welchem spezial Ordner wir den Pfad haben möchten. Die Funktion und die entsprechenden Folder-Ids (Konstanten) sind in der Unit
ShlObj.pas definiert. Weiter unten findes Du zwei Konstanten die die Borländer wohl vergessen haben zu definieren. In der
MSDN findet ihr die Beschreibung der einzelnen Konstanten. Den Pfad bekommen wir durch den Aufruf von SHGetSpecialFolderLocation nicht als String zurück sondern in einer sogenannten ItemIDList. Um jetzt von dieser sogenannten ItemIdList auf einen String zu kommen benutzen wir die Funktion
SHGETPATHFROMIDLIST.
Hier nun ein Beispiel für den Aufruf der beiden Funktionen um den Pfad vom Favoritenordner zubekommen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var pIdL: PItemIDList; Path: Array [0..Max_Path] Of Char; Begin SHGetSpecialFolderLocation (0, CSIDL_FAVORITES, pIdL);
SHGetPathFromIDList (pIDL, Path);
MessageDlg (Path, mtInformation, [mbOK], 0); End; |
Die Funktion SHGetSpecialFolderLocation belegt
automatisch für die Variable pIdL Speicher. Allerdings müssen
wir uns darum kümmern das dieser Speicher wieder freigegeben wird. Da es sich hier um einen fremden Speicherbereich handelt können wir diesen nicht einfach mit
FreeMem (pIdl); freigeben. Wir benutzen deshalb das Speicherverwaltungsinterface
IMalloc (in Unit ActiveX.pas definiert) um den Speicher wieder freizugeben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| Var Allocator: IMalloc; Begin If Succeeded (SHGetMalloc (Allocator)) Then Begin Allocator.Free (pIdL); {$IFDEF VER100} Allocator.Release; {$ENDIF} End; End |
Das wars!
Alles in allem könnte nun eine universell einsetzbare Funktion wie folgt implementiert sein:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| Uses ActiveX, ShlObj;
Function GetSpecialFolder (aFolder: Integer): String; var pIdL: PItemIDList; Path: Array [0..Max_Path] Of Char; Allocator: IMalloc; Begin SHGetSpecialFolderLocation (0, aFolder, pIdL);
SHGetPathFromIDList (pIDL, Path);
If Succeeded (SHGetMalloc (Allocator)) Then Begin Allocator.Free (pIdL); {$IFDEF VER100} Allocator.Release; {$ENDIF} End;
Result := Path; End; |
Ein Aufruf dieser Funktion könnte wie folgt sein:
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.Button1Click(Sender: TObject); begin MessageDlg (GetSpecialFolder (CSIDL_FAVORITES), mtInformation, [mbOK], 0); end; |
In der Unit ShlObj.pas fehlen noch zwei wichtige Folder-Ids. Wenn man diese braucht musst Du diese selbst definieren:
Delphi-Quelltext
1: 2: 3:
| Const CSIDL_LOCAL_APPDATA = $001C; CSIDL_COMMON_APPDATA = $0023; |
Moderiert von Tino: Hinweis von Martin1966 eingebaut.