2012-01-03 168 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);