【问题标题】:delphi get folder pathdelphi 获取文件夹路径
【发布时间】:2012-01-03 13:09:04
【问题描述】:

我正在使用 Delphi 7,我想找出我的 .. /All Users/Documents 目录的路径。
我遇到了以下代码

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
而且我确实需要在多个操作系统(仅限窗口)上运行这个应用程序。

我该怎么做?
感谢您的帮助:)

【问题讨论】:

    标签: delphi delphi-7 directory


    【解决方案1】:

    在我看来,调用SHGetSpecialFolderPath 传递CSIDL_COMMON_DOCUMENTS 并没有错。如果您需要支持 XP,那么您不能使用已知的文件夹 ID。您可以编写在 Vista 及更高版本上使用已知文件夹 ID 的代码,并在早期系统上回退到 CSIDL。但是为什么要打扰呢? MS 通过SHGetSpecialFolderPath 为您完成了这项工作。

    【讨论】:

    • 我在我的Shlobj.pas 文件中找不到CSIDL_COMMON_DOCUMENTS 减速。
    • 它的价值是 $002E 你必须在你的代码中声明这个常量
    【解决方案2】:

    你不应该使用 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 不使用Wide 版本的例程,因此您可以使用此代码。

    【讨论】:

    • 我的 uses 子句中有 shlobj,但在 Delphi 7 中找不到 ShGetFolderPath
    • 啊,ShGetFolderPath 比您的 .dcu 更新 - 我将通过更改您的文件来更新答案,这应该允许它工作
    【解决方案3】:

    正如 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.
    

    【讨论】:

      【解决方案4】:

      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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-25
        • 2017-11-03
        • 2013-07-05
        • 1970-01-01
        相关资源
        最近更新 更多