Delphi - 获取文件夹图标

标签 delphi winapi

如何获取特殊文件夹的图标,例如桌面

function GetFolderIcon( FName: string ): integer;
var
  FInfo: TSHFileInfo;
begin
  if SHGetFileInfo(pChar(FName), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo),
     SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES or SHGFI_PIDL or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then begin
        Result := FInfo.iIcon
    end
  else
    Result := -1;
end;

GetFolderIcon(GetSpecialFolder(CSIDL_DESKTOP)); retern -1

最佳答案

CSIDL_DESKTOP 是“代表 Windows 桌面的虚拟文件夹,命名空间的根”。因此,它没有可以传递给 SHGetFileInfo() 的文件系统路径。您可能会想到CSIDL_DESKTOPDIRECTORY,它是“用于在桌面上物理存储文件对象的文件系统目录(不要与桌面文件夹本身混淆)” :

GetFolderIcon(GetSpecialFolder(CSIDL_DESKTOPDIRECTORY));

调用 SHGetFileInfo() 时,您可以指定 SHGFI_PIDL 标志,以便可以传递 PIDL 而不是文件系统路径。这允许查询虚拟元素。您的代码已在使用 SHGFI_PIDL,但未使用任何 PIDL,这意味着您一开始就错误地使用了 SHGetFileInfo()

试试这个:

uses
  ..., ShlObj, SHFolder;

function GetSpecialFolderPath(FolderID: Integer): String;
var
  Path: array[0..MAX_PATH] of Char;
begin
  if SHGetFolderPath(0, FolderID, nil, SHGFP_TYPE_CURRENT, Path) = 0 then
    Result := Path
  else
    Result := '';
end;

function GetSpecialFolderPidl(FolderID: Integer): PItemIDList;
begin
  Result := nil;
  SHGetSpecialFolderLocation(0, FolderID, Result);
end;

function GetFolderIcon( FName: String ): integer; overload;
var
  FInfo: TSHFileInfo;
begin
  ZeroMemory(@FInfo, SizeOf(FInfo));
  if SHGetFileInfo(PChar(FName), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo), SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then
  begin
    Result := FInfo.iIcon;
    if FInfo.hIcon <> 0 then DestroyIcon(FInfo.hIcon);
  end else
    Result := -1;
end;

function GetFolderIcon( Pidl: PItemIDList ): integer; overload;
var
  FInfo: TSHFileInfo;
begin
    if SHGetFileInfo(PChar(Pidl), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo), SHGFI_PIDL or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_ICON or SHGFI_OPENICON ) <> 0 then
  begin
    Result := FInfo.iIcon;
    if FInfo.hIcon <> 0 then DestroyIcon(FInfo.hIcon);
  end
  else
    Result := -1;
end;

var
  Icon: Integer;
  Pidl: PItemIDList;
begin
  Icon := -1;
  Pidl := GetSpecialFolderPidl(CSIDL_DESKTOP);
  if Pidl <> nil then
  try
    Icon := GetFolderIcon(Pidl);
  finally
    CoTaskMemFree(Pidl);
  end;
end;

var
  Icon: Integer;
  Path: string;
begin
  Icon := -1;
  Path := GetSpecialFolderPath(CSIDL_DESKTOPDIRECTORY);
  if Path <> '' then
    Icon := GetFolderIcon(Path);
end;

关于Delphi - 获取文件夹图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33353404/

相关文章:

c# - 如何确定修改文件的最后一个进程?

Delphi 10.2 Coinbase Pro API 签名

delphi - 如何在对象检查器中查看属性的类型?

delphi - 创建时约束组件父级

c++ - Marlett 字体 : Can I load it and use it in WinAPI

c++ - 如何获取桌面的窗口句柄?

delphi - 没有带有这些参数的重载版本 - 具有读/写属性的 var param

delphi - 调用不同形式的类函数

c++ - 如何获取卷序列号

c - NtQuerySystemInformation - 内存泄漏