[编辑]
function PathFromShellItem(AShellItem: IShellItem): string;
{Helper function to get path from ShellItem}
var
hr: HRESULT;
iPath: PWideChar;
begin
hr := AShellItem.GetDisplayName(SIGDN_FILESYSPATH, iPath);
if hr = 0 then
Result := iPath
else
Result := '';
end;
下面的代码试图从IShellItem获取foldername和filename。正确获取文件名(iName),但文件夹名称(iFolder)始终为“”。为什么pfd.GetFolder没有返回文件夹名称?我试图以错误的方式获取文件夹名称吗?
function TFileDialogEvent.OnSelectionChange(const pfd: IFileDialog): HResult; stdcall;
{Handle the OnSelectionChange event and fill labels with information}
var
ShellItem: IShellItem;
iFilename: string;
iFolder: string;
iName: PWideChar;
begin
if pfd.GetFolder(ShellItem) = S_OK then
iFolder := PathFromShellItem(ShellItem);
OleCheck(pfd.GetFileName(iName));
{Set the filepath}
if DirectoryExists(iFolder) then
iFilename := IncludeTrailingPathDelimiter(iFolder) + string(iName);
end;
答案 0 :(得分:2)
PathFromShellItem
的代码不正确。你需要这样的东西,受文件对话框的VCL代码的启发:
function GetItemName(const Item: IShellItem; var ItemName: string): HRESULT;
var
pszItemName: PWideChar;
begin
Result := Item.GetDisplayName(SIGDN_FILESYSPATH, pszItemName);
if Failed(Result) then
Result := Item.GetDisplayName(SIGDN_NORMALDISPLAY, pszItemName);
if Succeeded(Result) then
try
ItemName := pszItemName;
finally
CoTaskMemFree(pszItemName);
end;
end;
function FileDialogFilename(const pfd: IFileDialog): string;
var
Item: IShellItem;
FileName: string;
pszFileName: PWideChar;
begin
if Succeeded(pfd.GetFolder(Item)) and
Succeeded(GetItemName(Item, FileName)) and
Succeeded(pfd.GetFileName(pszFileName)) then
try
Result := TPath.Combine(FileName, pszFileName);
finally
CoTaskMemFree(pszFileName);
end;
end;
如果您实际上无法使用TCustomFileDialog.GetFileName
,则可以使用TFileOpenDialog
作为此代码的模板。想一想,为什么不能只使用TFileOpenDialog
。