Plebios
Plebios

Reputation: 835

Get file information using Delphi windows api

Using Delphi and Windows API is possible from a PItemIDList to get if the file is a folder or not? With this snippet of code I can get the only the name of the file.

procedure TMain.FolderMonitorFileChange(aSender: TObject; aPIDL: PItemIDList);
var
  FileInfo : SHFILEINFOW;
begin
  SHGetFileInfo(LPCTSTR(aPIDL), 0 , FileInfo, SizeOf(FileInfo), SHGFI_PIDL or SHGFI_DISPLAYNAME or SHGFI_TYPENAME or SHGFI_ATTRIBUTES);
  ShowMessage('File change notification: ' + FileInfo.szDisplayName + ' ' + FileInfo.szTypeName );
end;

Thanks

Upvotes: 2

Views: 1715

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595412

For a relative PIDL, you can obtain the IShellFolder interface of the PIDL's parent folder, and then pass the PIDL to the IShellFolder::GetAttributesOf() method.

function IsFolder(Parent: IShellFolder; aChildPIDL: PItemIDList): Boolean;
var
  Attrs: SFGAOF;
begin
  Result := Succeeded(Parent.GetAttributesOf(1, @aChildPidl, @Attrs))
    and (Attrs and SFGAO_FOLDER <> 0);
end;

For an absolute PIDL, you have a few different options:

  • pass the PIDL to SHBindToParent() to convert it to a relative PIDL and retrieve its parent folder's IShellFolder, then call IShellFolder::GetAttributesOf().

    function IsFolder(aPIDL: PItemIDList): Boolean;
    var
      Parent: IShellFolder;
      Child: PItemIDList;
      Attrs: SFGAOF;
    begin
      Result := Succeeded(SHBindToParent(aPidl, IShellFolder, @Parent, @Child))
        and Succeeded(Parent.GetAttributesOf(1, @Child, @Attrs))
        and (Attrs and SFGAO_FOLDER <> 0);
    end;
    
  • pass the PIDL to SHGetFileInfo() using the SHGFI_PIDL flag. Enable the SHGFI_ATTRIBUTES flag to request the item's attributes.

    function IsFolder(aPIDL: PItemIDList): Boolean;
    var
      FileInfo : SHFILEINFO;
    begin
      Result := (SHGetFileInfo(LPCTSTR(aPIDL), 0, @FileInfo, SizeOf(FileInfo), SHGFI_PIDL or  SHGFI_ATTRIBUTES) <> 0)
        and (FileInfo.dwAttributes and SFGAO_FOLDER <> 0);
    end;
    
  • pass the PIDL to SHCreateItemFromIDList() to retrieve an IShellItem interface for it, and then call IShellItem::GetAttributes().

    function IsFolder(aPIDL: PItemIDList): Boolean;
    var
      Item: IShellItem;
      Attrs: SFGAOF;
    begin
      Result := Succeeded(SHCreateItemFromIDList(aPidl, IShellItem, @Item))
        and Succeeded(Item.GetAttributes(SFGAO_FOLDER, @Attrs))
        and (Attrs and SFGAO_FOLDER <> 0);
    end;
    

Upvotes: 4

Related Questions