如何从 Delphi 代码中的 IShellItem2.GetProperty 输出中获取 FindData 结构?

How to get the FindData structure from the IShellItem2.GetProperty output in Delphi code?

我正在使用 IShellFolder 枚举 Windows shell,并努力从 IShellItem2.GetProperty 的 TPropVariant 输出中获取 FindData 结构,以便我可以探索其内容。

问题是:如何从 Delphi 代码中的 TPropVariant 输出中获取 FindData?在这种情况下,C++ 片段对我没有帮助(这就是我发布的原因,因为有几个我无法正确翻译。)

我有的是:

var  
  ShellItem2: IShellItem2;
  ppropvar: TPropVariant;
  HR: HResult;
  FindData: TWin32FindData;
  FileSize: Int64;

if ShellItem2.GetProperty(PKEY_FindData, ppropvar) = S_OK then
begin
  //It's ok, then how do I get FindData?

  //Calculate the file size, for instace.
  FileSize := FindData.nFileSizeLow or Int64(FindData.nFileSizeHigh) shl 32;
end;

我找不到任何关于 WIN32_FIND_DATA 如何存储在 PROPVARIANT 中的正式文档。但是,根据在 this Qt code patch 中找到的代码片段,PROPVARIANT 的最后一个字段包含指向 WIN32_FIND_DATAW 的指针,因此请尝试如下操作:

type
  PWin32FindDataW = ^TWin32FindDataW;
  PPWin32FindDataW = ^PWin32FindDataW;
var
  ShellItem2: IShellItem2;
  ppropvar: TPropVariant;
  FindData: PWin32FindDataW;
  FileSize: UInt64;
begin
  ...
  if ShellItem2.GetProperty(PKEY_FindData, ppropvar) = S_OK then begin
    FindData := PPWin32FindDataW(PByte(@ppropvar) + sizeof(ppropvar) - sizeof(Pointer))^;
    // alternatively:
    // FindData := PWin32FindDataW(ppropvar.caub.pElems);
    if FindData <> nil then begin
      FileSize := FindData.nFileSizeLow or (UInt64(FindData.nFileSizeHigh) shl 32);
      ...
    end;
    PropVariantClear(ppropvar);
  end;
  ...
end;
function GetItemFindData(AItem: IShellItem2; out AFindData: TWin32FindDataW): Boolean;
var
  PV: TPropVariant;
begin
  Result := False;
  PV.vt := VT_EMPTY;
  if AItem.GetProperty(PKEY_FindData, PV) = S_OK then
    begin
      if (PV.vt = VT_UI1 or VT_VECTOR) and (PV.caub.cElems = SizeOf(AFindData)) and Assigned(PV.caub.pElems) then
        begin
          CopyMemory(@AFindData, PV.caub.pElems, SizeOf(AFindData));
          Result := True;
        end;
      PropVariantClear(PV);
    end;
end;