1

[編集]

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 からフォルダー名とファイル名を取得しようとします。ファイル名 (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;
4

1 に答える 1

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

于 2013-03-03T21:25:26.047 に答える