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

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

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

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

1 ответ

Решение

Я считаю, что вы на самом деле говорите о пользователе, который выбирает библиотеку 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 диалоговые окна файлов из-за этой и других проблем.

Другие вопросы по тегам