2015-04-27 58 views
1

我讓我的用戶通過OpenDialog組件選擇一個文件夾。從Delphi中的OpenDialog選擇中獲取特殊文件夾路徑

但是,當他們選擇一個文件夾如「文檔」或「我的視頻」或類似的文件夾時,路徑就是該文件夾的名稱。

我可以通過API獲取此文件夾的路徑,但是如何根據他們在OpenDialog中選擇的路徑獲取路徑 ?

回答

3

我相信你實際上是在談論用戶選擇Windows 7庫。在這種情況下,您需要使用特殊代碼來查找該庫的默認保存位置。

您需要使用IFileDialog接口來執行此操作。如果您使用TOpenDialog,則無法訪問IFileDialog界面。所以你需要使用Vista對話框TFileOpenDialog,它確實暴露了IFileDialog接口。

一旦你有了這個接口,你可以通過調用GetResults多選擇對話框,並GetResult單選擇對話框獲取每個選擇的外殼項目IShellItem接口。然後,您可以將這些IShellItem接口傳遞到這樣的功能:

function ShellItemFileSystemPath(const si: IShellItem): string; 
var 
    attribs: DWORD; 
    pszPath: PChar; 
    lib: IShellLibrary; 
    defSaveFolder: IShellItem; 
begin 
    OleCheck(si.GetAttributes(SFGAO_FILESYSTEM, attribs)); 
    if attribs=0 then begin 
    // This could be a library, in which case we shall return the default save location 
    if Succeeded(CoCreateInstance(CLSID_ShellLibrary, nil, CLSCTX_INPROC_SERVER, IID_IShellLibrary, lib)) 
    and Succeeded(lib.LoadLibraryFromItem(si, STGM_READ)) 
    and Succeeded(lib.GetDefaultSaveFolder(DSFT_DETECT, IShellItem, defSaveFolder)) then begin 
     Result := ShellItemFileSystemPath(defSaveFolder); 
     exit; 
    end; 
    raise EValidityError.CreateFmt(
     'Cannot operate on ''%s'' because it is not part of the file system.', 
     [ShellItemDisplayName(si)] 
    ); 
    end; 
    OleCheck(si.GetDisplayName(SIGDN_FILESYSPATH, pszPath)); 
    Try 
    Result := pszPath; 
    Finally 
    CoTaskMemFree(pszPath); 
    End; 
end; 

在英巴卡迪諾庫中的代碼應該這樣做,但遺憾的是該庫的代碼是有缺陷的。到目前爲止,它應該支持Windows 7庫。

就我個人而言,由於這個問題和其他問題,我不使用Embarcadero提供的文件對話框。

+0

哪個單元可以找到IFIleDialog? – vaid

+1

可能commctrl但你不會有IFileDialog,如果你的Delphi是舊的。你必須自己定義它。 –

+0

我使用XE7,所以它應該沒問題。 – vaid

相關問題