2012-01-03 169 views
8

我与德尔福7工作,我想找出我的路径.. /所有用户/文件目录。
我碰到下面的代码delphi获取文件夹路径

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)上运行此应用程序。

我该怎么做?
帮助被赞赏:)

回答

5

在我看来,通过CSIDL_COMMON_DOCUMENTS调用SHGetSpecialFolderPath没有任何问题。如果你需要支持XP,那么你不能使用已知的文件夹ID。您可以编写在Vista和更高版本上使用已知文件夹ID的代码,并在早期系统上回退到CSIDL。但为什么要麻烦? MS已通过SHGetSpecialFolderPath为您完成。

+0

我找不到'CSIDL_COMMON_DOCUMENTS' dece在我的'Shlobj.pas'文件中进行说明。 – Shirish11 2012-01-04 04:48:39

+2

它的值为$ 002E,您将不得不在代码中声明常量 – 2012-01-04 07:22:55

3

是不是你应该使用shell32.dll中的ShGetFolderPath?这假设使用IE5或更新版本的Windows 2000。

您需要将shlobj添加到使用该代码的使用行。

function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWORD; pszPath: PChar): HResult; stdcall; external 'shfolder.dll' name 'SHGetFolderPathA'; 

德尔福7不使用的程序的宽版,所以你:

由于没有在源文件中没有定义的SHGetFolderPath,您可以使用它的代码之前,请使用以下可以使用这个代码。

+0

我'shlobj'在我的使用条款。我找不到' ShGetFolderPath'在Delphi 7中。 – Shirish11 2012-01-03 13:34:40

+0

啊,ShGetFolderPath比你的.dcu更新 - 我将更新你的文件的更改应该允许它的工作 – Petesh 2012-01-03 13:39:35

2

正如David所述,使用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. 
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);