Pfad der "Special Folders" ermitteln
Wie bekomme ich den Pfad von "Special Folders" (Desktop, Favoriten etc.)?
1. Warum so kompliziert? Die Pfade der angesprochenen "Special Folders" stehen zwar in der Registry, aber laut Microsoft könnten sich die Orte ändern. Daher soll man die Funktion SHGetSpecialFolderLocation verwenden. Diese Funktion ist aber nicht ganz so einfach und um sie sauber auzuführen muss man sich etwas mit dem COM-Interface IMalloc auseinandersetzen. 2. Die benötigten Units Folgende Units werden benötigt:
Delphi-Quellcode:
3. IMalloc, SHGetMalloc()
uses
{ ... }, ActiveX, // IMalloc ShellAPI, // SHGetSpecialFolderLocation() und SHGetPathFromIDList() ShlObj; // CSIDL_-Konstanten Die Funktion SHGetSpecialFolderLocation belegt Speicher um den Path in einer sogennanten ItemIDList zurückzugeben (eine Liste von PIDLs, den Bezeichnern für alle Objekte im Shell Namespace, dem baumförmig aufgebauten Dateisystem wie im Windows-Explorer links zu sehen). Da für diese Liste Speicher von dieser Funktion reserviert wurde, jedoch nicht freigegeben werden kann (weil ein Pointer auf die Liste ja an unser Programm weitergeben werden muss), sind wir für das freigeben des Speichers, wenn wir die Liste nicht mehr benötigen, zuständig. Normalerweise würde man das ja über FreeMem() machen, jedoch weist der Pointer, der auf die Liste zeigt, in einen fremden Adressraum, wir können da also nicht so einfach herumpfuschen. Ein Freigeben mit FreeMem() würde in einer Schutzverletzung resultieren. Microsoft bietet hier als Lösung das Speicherverwaltungsinterface IMalloc an. Dessen Methode IMalloc.Free() übergibt man den Pointer auf den freizugebenden Speicher und die Sache ist gegessen. Um einen Pointer auf die VTable von IMalloc zu bekommen (damit wir die Methode Free() aufrufen können) benutzen wir die Funktion SHGetMalloc. Der folgende Code demonstriert, die man ein IMalloc-Interface zu "fassen" bekommt:
Delphi-Quellcode:
Nun kann man IMalloc.Free() ganz einfach so aufrufen:
var
pMalloc: IMalloc; // ... // get IMalloc interface pointer if (SHGetMalloc(pMalloc) <> S_OK) then begin MessageBox(hWindow, 'Couldn''t get pointer to IMalloc interface.', 'SHGetMalloc(pMalloc)', 16); Exit; end;
Delphi-Quellcode:
4. SHGetSpecialFolderLocation() und SHGetPathFromIDList()
var
p: PChar; // ... pMalloc.Free(p); Jetzt kann man mit der Funktion SHGetSpecialFolderLocation den Pfad zum herauszufindenen Ordner anfordern. Diese Funktion ist wie folgt deklariert: (C/C++)
Code:
(Object Pascal)
HRESULT SHGetSpecialFolderLocation(
HWND hwndOwner, int nFolder, LPITEMIDLIST* ppidl );
Delphi-Quellcode:
Der erste Parameter spezifiziert das Handle des aufrufenden Fensters, das dritte ist der Pointer auf die Item-ID-Liste. Ausschlaggeben für den Ordner, der zurückgegeben wird, ist nFolder. Hier wird eine der folgenden Konstanten übergeben:
function SHGetSpecialFolderLocation(
hwndOwner: HWND; nFolder: Integer; var ppidl: PItemIDList ): HRESULT; stdcall;
Code:
Interessant wären auch CSIDL_MYMUSIC, CSIDL_MYPICTURES, CSIDL_SYSTEM, CSIDL_WINDOWS und CSIDL_PROGRAM_FILES, aber diese scheinen in Delphi (noch) nicht deklariert zu sein. Es gibt noch ein paar andere Werte, die virtuelle Ordner spezifieren, aber diese haben keinen Pfad im Dateisystem (z.B. die Netzwerkumgebung).
CSIDL_COOKIES Cookies
CSIDL_DESKTOPDIRECTORY Desktop CSIDL_FAVORITES Favoriten CSIDL_HISTORY Internet-Verlauf CSIDL_INTERNET_CACHE "Temporary Internet Files" CSIDL_PERSONAL Eigene Dateien CSIDL_PROGRAMS "Programme" im Startmenü CSIDL_RECENT "Dokumente" im Startmenü CSIDL_SENDTO "Senden an" im Kontextmenü CSIDL_STARTMENU Startmenü CSIDL_STARTUP Autostart Hinzu kommt jetzt noch die Funktion SHGetPathFromIDList, die aus der zurückgebenen Item-ID-Liste den Pfad holt. Die Deklaration: (C/C++)
Code:
(Object Pascal)
BOOL SHGetPathFromIDList(
LPCITEMIDLIST pidl, LPTSTR pszPath );
Delphi-Quellcode:
Jetzt noch ein Anwendungsbeispiel:
function SHGetPathFromIDList(
pidl: PItemIDList; pszPath: PChar ): Boolean; stdcall;
Delphi-Quellcode:
5. Die fertige Funktion GetSpecialFolder()
var
pidl: PItemIDList; Folder: Integer; hWindow: HWND; // ... SHGetSpecialFolderLocation(hWindow, Folder, pidl); GetMem(Path, MAX_PATH); SHGetPathFromIDList(pidl, Path); Result := Path; FreeMem(Path); Nun dürfte es relativ einfach sein, eine Funktion daraus zu basteln (weil ich den meisten Code schon oben einkopiert habe *g*):
Delphi-Quellcode:
Zum Schluss noch ein Anwendungsbeispiel:
function GetSpecialFolder(hWindow: HWND; Folder: Integer): String;
var pMalloc: IMalloc; pidl: PItemIDList; Path: PChar; begin // get IMalloc interface pointer if (SHGetMalloc(pMalloc) <> S_OK) then begin MessageBox(hWindow, 'Couldn''t get pointer to IMalloc interface.', 'SHGetMalloc(pMalloc)', 16); Exit; end; // retrieve path SHGetSpecialFolderLocation(hWindow, Folder, pidl); GetMem(Path, MAX_PATH); SHGetPathFromIDList(pidl, Path); Result := Path; FreeMem(Path); // free memory allocated by SHGetSpecialFolderLocation pMalloc.Free(pidl); end;
Delphi-Quellcode:
Fertig *g*.
procedure TForm1.Button1Click(Sender: TObject);
begin ShowMessage(GetSpecialFolder(Handle, CSIDL_RECENT)); end; MfG, d3g [edit=Chakotay1308][code]- durch [delphi]-Tags ersetzt. Mfg, Chakotay1308[/edit] [edit=flomei]Wir "räumen auf", daher Titel geändert... Mfg, flomei[/edit] [edit=Matze]Alte MSDN-Links entfernt und MSDN-Tags gesetzt. MfG, Matze[/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz