2012-01-03 18 views
8

Estoy trabajando con Delphi 7 y quiero averiguar la ruta de mi directorio ../All Users/Documents.
me encontré con el siguiente códigocarpeta delphi get ruta

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; 

Funciona bien, pero no es compatible con CSIDL_COMMON_DOCUMENTS que devuelve la ruta deseada.

Además, según MS CSIDL ya no se debe utilizar en su lugar use KNOWNFOLDERID.
Y necesito trabajar esta aplicación en varios sistemas operativos (solo ventanas).

¿Cómo puedo hacer esto?
Se agradece la ayuda :)

Respuesta

5

En mi opinión, no hay nada de malo en llamar SHGetSpecialFolderPath pasando CSIDL_COMMON_DOCUMENTS. Si necesita admitir XP, entonces no puede usar ID de carpetas conocidas. Podrías escribir código que utilizara identificadores de carpetas conocidas en Vista y posteriores, y volver a recurrir a CSIDL en sistemas anteriores. ¿Pero por qué molestarse? MS lo hizo por usted con SHGetSpecialFolderPath.

+0

No puedo encontrar 'CSIDL_COMMON_DOCUMENTS' dece Lección en mi archivo 'Shlobj.pas'. – Shirish11

+2

Tiene un valor de $ 002E, tendrá que declarar la constante en su código –

3

¿No se supone que debes usar ShGetFolderPath de shell32.dll? Esto supone usar Windows 2000 con IE5 o posterior.

necesita agregar shlobj a la línea de usos para el código que hace uso de ella.

Como no hay una definición para SHGetFolderPath en la fuente, se puede utilizar el siguiente antes del código que lo utiliza:

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

Delphi 7 no hace uso de la versión amplia de la rutina, por lo que puede usar este código

+0

tengo 'shlobj' en mi cláusula de usos y no puedo encontrar' ShGetFolderPath' en Delphi 7. – Shirish11

+0

Ah, ShGetFolderPath es más nuevo que su .dcu - Actualizaré la respuesta con un cambio para su archivo que debería permitir que funcione – Petesh

2

Como David ya indicó, use la función SHGetSpecialFolderPath. Vista y W7 harán la conversión de CSIDL/Carpeta por usted. Si desea utilizar la API más nueva, esto debería ser el truco: Tenga en cuenta que esto solo funcionará desde 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

Como recomendó Embarcadero en este documento: 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; 

utilizar de esta manera:

s:= GetSpecialFolder(CSIDL_LOCAL_APPDATA, true); 
Cuestiones relacionadas