I let my users select a folder via the OpenDialog component.
However, when they select a folder such as Documents or My Videos or something like that, the path is just the name of the folder.
I can get the path of such folder via the API, but how do I get the path based on what they've selected in the OpenDialog?
I believe that you are actually talking about a user selecting a Windows 7 library. In which case you need to use special code to find the default save location for that library.
You need to use the IFileDialog
interface to do this. If you use TOpenDialog
then you don't have access to the IFileDialog
interface. So you need to use the Vista dialog, TFileOpenDialog
which does expose the IFileDialog
interface.
Once you have this interface you can obtain IShellItem
interfaces for each selected shell item by calling GetResults
for multi-select dialogs, and GetResult
for single-select dialogs. You can then pass these IShellItem
interfaces to a function like this:
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;
The code in the Embarcadero libraries should be doing this, but sadly that library code is deficient. It should be supporting Windows 7 libraries by now.
Personally, I don't use the Embarcadero provided file dialogs because of this issue and others.