I m working with Delphi 7 and I want to find out the path of my .. /All Users/Documents directory.
I came across the following code
uses shlobj, ...
function GetMyDocuments: string;
var
r: Bool;
path: array[0..Max_Path] of Char;
begin
r := ShGetSpecialFolderPath(0, path, CSIDL_Personal, False) ;
if not r then
raise Exception.Create('Could not find MyDocuments folder location.') ;
Result := Path;
end;
It works fine but it does not support CSIDL_COMMON_DOCUMENTS
which returns the desired path.
Moreover as per MS CSIDL should no longer be used instead use KNOWNFOLDERID .
And I do need to work this app on multiple OS's (only windows).
How can I do this ?
Help is appreciated :)
In my view there's nothing wrong with calling SHGetSpecialFolderPath
passing CSIDL_COMMON_DOCUMENTS
. If you need to support XP then you can't use known folder IDs. You could write code that used known folder IDs on Vista and up, and fell back to CSIDL on earlier systems. But why bother? MS have done that for you with SHGetSpecialFolderPath
.
As David already stated, use the SHGetSpecialFolderPath function. Vista and W7 will do the CSIDL/Folder conversion for you. If you want to use the newer API, This should to the trick: Please note that this will only work from vista.
unit Unit1;
interface
uses
Windows, ActiveX, Forms, SysUtils, OleAuto, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TShGetKnownFolderPath = function(const rfid: TGUID; dwFlags: DWord; hToken: THandle; out ppszPath: PWideChar): HResult; stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
function ShGetKnownFolderPath(const rfid: TGUID; dwFlags: DWord; hToken: THandle; out ppszPath: PWideChar): HResult;
var Shell: HModule;
Fn: TShGetKnownFolderPath;
begin
Shell := LoadLibrary('shell32.dll');
Win32Check(Shell <> 0);
try
@Fn := GetProcAddress(Shell, 'SHGetKnownFolderPath');
Win32Check(Assigned(Fn));
Result := Fn(rfid, dwFlags, hToken, ppszPath);
finally
FreeLibrary(Shell);
end;
end;
function GetPublicDocuments: string;
var
ret: HResult;
Buffer: PWideChar;
begin
ret := ShGetKnownFolderPath(StringToGuid('{ED4824AF-DCE4-45A8-81E2-FC7965083634}'), 0, 0, Buffer) ;
OleCheck(ret);
try
Result := Buffer;
finally
CoTaskMemFree(Buffer);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(GetPublicDocuments);
end;
end.
Aren't you supposed to use ShGetFolderPath from shell32.dll? This assumes using windows 2000 with IE5 or newer.
you need to add shlobj
to the uses line for the code that makes use of it.
As there is no definition for SHGetFolderPath in the source, you can use the following before the code that uses it:
function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWORD; pszPath: PChar): HResult; stdcall; external 'shfolder.dll' name 'SHGetFolderPathA';
Delphi 7 does not make use of the Wide version of the routine, so you can use this code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With