2015-04-27 13 views
1

Позволяет пользователям выбирать папку через компонент OpenDialog.Получение специального пути папки из OpenDialog в Delphi

Однако, когда они выбирают такую ​​папку, как «Документы» или «Мои видео» или что-то в этом роде, путь - это просто имя папки.

Я могу получить путь к такой папке через API, но как мне получить путь на основе того, что они выбрали в OpenDialog?

ответ

3

Я считаю, что вы действительно говорите о пользователе, который выбирает библиотеку Windows 7. В этом случае вам нужно использовать специальный код, чтобы найти местоположение сохранения по умолчанию для этой библиотеки.

Для этого вам необходимо использовать интерфейс IFileDialog. Если вы используете TOpenDialog, то у вас нет доступа к интерфейсу IFileDialog. Таким образом, вам нужно использовать диалог Vista, TFileOpenDialog, который показывает интерфейс IFileDialog.

После того как вы этот интерфейс вы можете получить IShellItem интерфейсов для каждого выбранного элемента оболочки путем вызова GetResults для нескольких отдельных диалогов и GetResult для одного отборных диалогов. Затем вы можете передать эти 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; 

код в библиотеках Embarcadero должны делать это, но, к сожалению, что код библиотеки является недостаточным. К настоящему времени он должен поддерживать библиотеки Windows 7.

Лично я не использую диалоговые окна, предоставленные Embarcadero, из-за этой проблемы и других.

+0

В каком блоке можно найти IFIleDialog? – vaid

+1

Возможно, commctrl, но у вас не будет IFileDialog, если ваш delphi старый. Вы должны определить это самостоятельно. –

+0

Я использую XE7, так что, должно быть, все в порядке. – vaid