我正在使用Delphi 7,我想找出 .. /所有用户/文档目录的路径。
我遇到了以下代码
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;
它工作正常,但它不支持返回所需路径的CSIDL_COMMON_DOCUMENTS
。
此外,根据MS CSIDL不应再使用KNOWNFOLDERID 我确实需要在多个操作系统(仅限Windows)上运行此应用程序。
我该怎么做?
感谢帮助:)
答案 0 :(得分:5)
在我看来,调用SHGetSpecialFolderPath
传递CSIDL_COMMON_DOCUMENTS
并没有错。如果您需要支持XP,则无法使用已知的文件夹ID。您可以编写在Vista及更高版本上使用已知文件夹ID的代码,并在早期系统上回退到CSIDL。但为什么要这么麻烦? MS已经SHGetSpecialFolderPath
为您完成了这项工作。
答案 1 :(得分:3)
你不应该使用shell32.dll中的ShGetFolderPath吗?假设使用带有IE5或更新版本的Windows 2000。
您需要将shlobj
添加到使用它的代码的使用行。
由于源代码中没有SHGetFolderPath的定义,您可以在使用它的代码之前使用以下内容:
function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWORD; pszPath: PChar): HResult; stdcall; external 'shfolder.dll' name 'SHGetFolderPathA';
Delphi 7没有使用广泛版本的例程,因此您可以使用此代码。
答案 2 :(得分:2)
正如大卫已经说过的那样,使用SHGetSpecialFolderPath函数。 Vista和W7将为您进行CSIDL /文件夹转换。 如果你想使用更新的API,这应该是诀窍: 请注意,这只适用于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.
答案 3 :(得分:2)
根据Embarcadero在本文档中的建议:VistaUACandDelphi.pdf
Uses SHFolder;
function GetSpecialFolder (CSIDL: Integer; ForceFolder: Boolean = FALSE): string;
CONST SHGFP_TYPE_CURRENT = 0;
VAR i: Integer;
begin
SetLength(Result, MAX_PATH);
if ForceFolder
then ShGetFolderPath(0, CSIDL OR CSIDL_FLAG_CREATE, 0, 0, PChar(Result))= S_ok
else ShGetFolderPath(0, CSIDL, 0, 0, PChar(Result));
i:= Pos(#0, Result);
if i> 0
then SetLength(Result, pred(i));
Result:= Trail (Result);
end;
像这样使用:
s:= GetSpecialFolder(CSIDL_LOCAL_APPDATA, true);