Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Pfad der "Special Folders" ermitteln (https://www.delphipraxis.net/103931-pfad-der-special-folders-ermitteln.html)

HannosG 24. Nov 2007 13:54


Pfad der "Special Folders" ermitteln
 
Moin,

d3g beschreibt in Pfad der "Special Folders" ermitteln, wie man über "CSIDL-Konstanten" zu den dazugehörigen Pfadangaben gelangt (z.B. Pfad des Programme-Ordners herausfinden):

Delphi-Quellcode:
uses ActiveX, ShellApi, ShlObj;

...

function GetSpecialFolder(hWindow: HWND; Folder: Integer): String; // z.B. Folder: CSIDL_PROGRAM_FILES = $26 = 38
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;
Warum wird dazu so gut wie immer SHGetSpecialFolderLocation benutzt?
Wozu gibt es denn SHGetSpecialFolderPath?
Damit wickelt man die Funktion doch in einem Zweizeiler ab:

Delphi-Quellcode:
uses ShlObj;

...

function GetSpecialFolder(Folder: Integer): PChar;
begin
  Result:=StrAlloc(MAX_PATH);
  SHGetSpecialFolderPath(0, Result, Folder, false);
end;
MfG,
HannosG

Popov 24. Nov 2007 14:22

Re: Pfad der "Special Folders" ermitteln
 
SHGetSpecialFolderLocation ist älter. Ich hab ein Buch der API32 von 1998 und da ist SHGetSpecialFolderPath nicht drin.

Apollonius 24. Nov 2007 14:26

Re: Pfad der "Special Folders" ermitteln
 
Zitat:

Zitat von MSDN zu SHGetSpecialFolderPath
Minimum operating systems Windows 2000, Windows NT 4.0 with Internet Explorer 4.0, Windows 98, Windows 95 with Internet Explorer 4.0

Allerdings würde ich die kapselnde Funktion anders schreiben. So kriegt man einfach zu leicht ein Speicherleck. Besser wäre es, die Funktion einen String zurückgeben zu lassen und den PChar als lokale Variable wieder freizugeben.

Popov 24. Nov 2007 14:41

Re: Pfad der "Special Folders" ermitteln
 
Allerdings kriegt man das auch kürzer mit SHGetSpecialFolderLocation als oben

Delphi-Quellcode:
function SpecialDirectory(ID: Integer): String; // uses Windows, Shlobj;
var
  pidl : PItemIDList;
  Path : PChar;
begin
  if SUCCEEDED(SHGetSpecialFolderLocation(0, ID, pidl)) then
  begin
    Path := StrAlloc(max_path);
    SHGetPathFromIDList(pidl, Path);
    Result := String(Path);
  end
    else Result := #0;
end;

Apollonius 24. Nov 2007 14:43

Re: Pfad der "Special Folders" ermitteln
 
Du gibst weder pidl noch Path frei!

HannosG 24. Nov 2007 16:08

Re: Pfad der "Special Folders" ermitteln
 
@Popov
Kürzer hinbekommen ist kein Problem, nur hat das mit dem "IMalloc" und dem Freigeben schon seinen Sinn.
3. IMalloc, SHGetMalloc() Pfad der "Special Folders" ermitteln

Die Funktion SHGetSpecialFolderPath belegt eben keinen Speicher für eine "ItemIDList".

@Apollonius
Zitat:

Zitat von Apollonius
Allerdings würde ich die kapselnde Funktion anders schreiben. So kriegt man einfach zu leicht ein Speicherleck. Besser wäre es, die Funktion einen String zurückgeben zu lassen und den PChar als lokale Variable wieder freizugeben.

Da muss ich dir zustimmen. :wink:
OK, die Funktion beginnt zu wachsen. :|
Delphi-Quellcode:
function GetSpecialFolder(Folder: Integer): String;
var
  Path: PChar;
begin
  GetMem(Path,MAX_PATH);
  If SHGetSpecialFolderPath(0, Path, Folder, false)
    then Result:=Path
    else Result:='';
  FreeMem(Path);
end;

thkerkmann 24. Nov 2007 17:10

Re: Pfad der "Special Folders" ermitteln
 
Zitat:

Zitat von HannosG
OK, die Funktion beginnt zu wachsen. :|
Delphi-Quellcode:
function GetSpecialFolder(Folder: Integer): String;
var
  Path: PChar;
begin
  GetMem(Path,MAX_PATH);
  If SHGetSpecialFolderPath(0, Path, Folder, false)
    then Result:=Path
    else Result:='';
  FreeMem(Path);
end;

muss sie doch gar nicht :-)

Delphi-Quellcode:
function GetSpecialFolder(Folder: Integer): String;
var
  Path: array[0..MAX_PATH] of char;
begin
  If SHGetSpecialFolderPath(0, @Path, Folder, false)
    then Result:=Path
    else Result:='';
end;
Gruss

DeddyH 30. Nov 2007 09:35

Re: Pfad der "Special Folders" ermitteln
 
Ich hab da auch noch eine Version:
Delphi-Quellcode:
function GetSpecialFolder(Folder: Integer): String;
begin
  SetLength(Result,MAX_PATH);
  SHGetSpecialFolderPath(0, PChar(Result), Folder, false);
  SetLength(Result,StrLen(PChar(Result)));
end;

HannosG 30. Nov 2007 14:47

Re: Pfad der "Special Folders" ermitteln
 
@DeddyH
Gut, das ist diesmal glaube ich die richtige Form der Direktübergabe.
Aber... SHGetSpecialFolderPath kann auch fehlschlagen und GetSpecialFolder könnte dann irgendein Wert ausgeben, mit dem man nichts zu tun haben möchte. :)

Daher:
Delphi-Quellcode:
function GetSpecialFolder(Folder: Integer): String;
begin
  SetLength(Result,MAX_PATH);
  If SHGetSpecialFolderPath(0, PChar(Result), Folder, false)
    then SetLength(Result,StrLen(PChar(Result)))
    else Result:='';
end;
Hmmm, irgendwie finde ich die Variante von thkerkmann noch am übersichtlichsten.

OldGrumpy 30. Nov 2007 16:43

Re: Pfad der "Special Folders" ermitteln
 
UNC-Pfade können übrigens über 30.000 Zeichen lang werden. Das sollte man bei der Benutzung von MAX_PATH immer im Hinterkopf haben... nicht umsonst bieten die meisten APIs die einen Puffer erwarten die Möglichkeit, sich erst einmal die benötigte Puffergröße geben zu lassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:34 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