如何获取驱动器、设备或文件的默认系统图标

How to get the default system icon for a drive, a device or a file

我正在创建一个远程文件管理器。服务器端应用程序获取计算机中的驱动程序、目录和文件列表,将其保存为流并在我当前所在的计算机中将其发送给我。一切正常。

在当前计算机中,首先我使用 "OnCreate" 事件用 shell 图标(来自同一台当前计算机)填充 TListImage,然后 link 使用 ListView 填充它将显示文件列表。因此,一旦收到列表,我就使用下面的这个函数在 ListView 中显示通用文件图标:

function GetGenericFileIconIndex(Filename: string): Integer;
var
  FInfo: TSHFileInfo;
begin
  Result := -1;
  if (SHGetFileInfo(PChar(Filename), FILE_ATTRIBUTE_NORMAL, FInfo, SizeOf(FInfo),
    SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES) <> 0) then
    Result := FInfo.iIcon;
end;

for I := 0 to Pred(List.Count) do
begin
  Item := ListView.Items.Add;
  Item.ImageIndex := GetGenericFileIconIndex(List[I]);
  Item.Caption := List[I];
end;

使用文件 name/extension 我可以获得正确的 shell 图标,即使在不同的计算机上也是如此。但我还需要显示正确的驱动器类型图标。例如,在远程计算机上 "D:\" 是本地固定驱动器,但在当前计算机上 "D:\" 是 CD/DVD 驱动器,所以我无法使用驱动器号获取此图标。我需要一种从远程计算机(固定驱动器)获取 "generic" 驱动器类型图标索引并将其发送到当前计算机的方法。

例如,我的目标是为本地硬盘获取默认图标,为远程磁盘获取默认图标, CD/DVD 设备等等...

对不起,英语不是我的母语。我尽力解释了。

也许我需要的是不可能的,请告诉我...

谢谢!

你一定要使用 SHGetStockIconInfo function:

HRESULT SHGetStockIconInfo(
          SHSTOCKICONID   siid,
          UINT            uFlags,
  _Inout_ SHSTOCKICONINFO *psii
);

SHSTOCKICONID 类型的 siid 参数用于标识要检索哪个 股票系统图标

function GetDefaultSystemIcon(ASiid: Integer): Integer;
var
  sInfo: TSHStockIconInfo;
begin
  sInfo.cbSize := SizeOf(TSHStockIconInfo);
  if S_OK = SHGetStockIconInfo(ASiid, SHGSI_SYSICONINDEX, sInfo) then
    Result := sInfo.iSysImageIndex
  else
    Result := -1;
end;

您可以像这样调用上面的方法 GetDefaultSystemIcon(SIID_DRIVECD) 来获取 默认 CDROM 驱动器图标索引。


来自 Microsoft 文档:

Minimum supported client      Windows Vista [desktop apps only]
Minimum supported server    Windows Server 2008 [desktop apps only]

较旧的 ShellAPI 单元可能没有 SHGetStockIconInfo 声明:在这种情况下,必须将以下 unit 添加到 Delphi 项目。

注意以下单位的使用仅限于shell32.dll[中的SHGetStockIconInfo功能的可用性=40=] 系统库 - 即导出函数需要库。

unit MyShellAPI;

interface

uses
  Windows;

type
  SHSTOCKICONID = Integer;

  _SHSTOCKICONINFO = record
    cbSize: Cardinal;
    hIcon: HICON;
    iSysImageIndex,
    iIcon: Integer;
    szPath: packed array [0..MAX_PATH-1] of Char;
  end;
  SHStockIconInfo = _SHSTOCKICONINFO;
  TSHStockIconInfo = SHSTOCKICONINFO;
  PSHStockIconInfo = ^TSHStockIconInfo;

const
  //https://msdn.microsoft.com/en-us/library/windows/desktop/bb762179%28v=vs.85%29.aspx
  SHGFI_ADDOVERLAYS       = [=12=]0000020;
  SHGFI_ATTR_SPECIFIED    = [=12=]0020000;
  SHGFI_ATTRIBUTES        = [=12=]0000800;
  SHGFI_DISPLAYNAME       = [=12=]0000200;
  SHGFI_EXETYPE           = [=12=]0002000;
  SHGFI_ICON              = [=12=]0000100;
  SHGFI_ICONLOCATION      = [=12=]0001000;
  SHGFI_LARGEICON         = [=12=]0000000;
  SHGFI_LINKOVERLAY       = [=12=]0008000;
  SHGFI_OPENICON          = [=12=]0000002;
  SHGFI_OVERLAYINDEX      = [=12=]0000040;
  SHGFI_PIDL              = [=12=]0000008;
  SHGFI_SELECTED          = [=12=]0010000;
  SHGFI_SHELLICONSIZE     = [=12=]0000004;
  SHGFI_SMALLICON         = [=12=]0000001;
  SHGFI_SYSICONINDEX      = [=12=]0004000;
  SHGFI_TYPENAME          = [=12=]0000400;
  SHGFI_USEFILEATTRIBUTES = [=12=]0000010;

  //https://msdn.microsoft.com/en-us/library/windows/desktop/bb762205(v=vs.85).aspx
  SHGSI_ICONLOCATION = 0;
  SHGSI_ICON = SHGFI_ICON;
  SHGSI_SYSICONINDEX = SHGFI_SYSICONINDEX;
  SHGSI_LINKOVERLAY = SHGFI_LINKOVERLAY;
  SHGSI_SELECTED = SHGFI_SELECTED;
  SHGSI_LARGEICON = SHGFI_LARGEICON;
  SHGSI_SMALLICON = SHGFI_SMALLICON;
  SHGSI_SHELLICONSIZE = SHGFI_SHELLICONSIZE;

  //https://msdn.microsoft.com/en-us/library/windows/desktop/bb762542%28v=vs.85%29.aspx
  SIID_DOCNOASSOC         = 0;
  SIID_DOCASSOC           = 1;
  SIID_APPLICATION        = 2;
  SIID_FOLDER             = 3;
  SIID_FOLDEROPEN         = 4;
  SIID_DRIVE525           = 5;
  SIID_DRIVE35            = 6;
  SIID_DRIVEREMOVE        = 7;
  SIID_DRIVEFIXED         = 8;
  SIID_DRIVENET           = 9;
  SIID_DRIVENETDISABLED   = 10;
  SIID_DRIVECD            = 11;
  SIID_DRIVERAM           = 12;
  SIID_WORLD              = 13;
  SIID_SERVER             = 15;
  SIID_PRINTER            = 16;
  SIID_MYNETWORK          = 17;
  SIID_FIND               = 22;
  SIID_HELP               = 23;
  SIID_SHARE              = 28;
  SIID_LINK               = 29;
  SIID_SLOWFILE           = 30;
  SIID_RECYCLER           = 31;
  SIID_RECYCLERFULL       = 32;
  SIID_MEDIACDAUDIO       = 40;
  SIID_LOCK               = 47;
  SIID_AUTOLIST           = 49;
  SIID_PRINTERNET         = 50;
  SIID_SERVERSHARE        = 51;
  SIID_PRINTERFAX         = 52;
  SIID_PRINTERFAXNET      = 53;
  SIID_PRINTERFILE        = 54;
  SIID_STACK              = 55;
  SIID_MEDIASVCD          = 56;
  SIID_STUFFEDFOLDER      = 57;
  SIID_DRIVEUNKNOWN       = 58;
  SIID_DRIVEDVD           = 59;
  SIID_MEDIADVD           = 60;
  SIID_MEDIADVDRAM        = 61;
  SIID_MEDIADVDRW         = 62;
  SIID_MEDIADVDR          = 63;
  SIID_MEDIADVDROM        = 64;
  SIID_MEDIACDAUDIOPLUS   = 65;
  SIID_MEDIACDRW          = 66;
  SIID_MEDIACDR           = 67;
  SIID_MEDIACDBURN        = 68;
  SIID_MEDIABLANKCD       = 69;
  SIID_MEDIACDROM         = 70;
  SIID_AUDIOFILES         = 71;
  SIID_IMAGEFILES         = 72;
  SIID_VIDEOFILES         = 73;
  SIID_MIXEDFILES         = 74;
  SIID_FOLDERBACK         = 75;
  SIID_FOLDERFRONT        = 76;
  SIID_SHIELD             = 77;
  SIID_WARNING            = 78;
  SIID_INFO               = 79;
  SIID_ERROR              = 80;
  SIID_KEY                = 81;
  SIID_SOFTWARE           = 82;
  SIID_RENAME             = 83;
  SIID_DELETE             = 84;
  SIID_MEDIAAUDIODVD      = 85;
  SIID_MEDIAMOVIEDVD      = 86;
  SIID_MEDIAENHANCEDCD    = 87;
  SIID_MEDIAENHANCEDDVD   = 88;
  SIID_MEDIAHDDVD         = 89;
  SIID_MEDIABLURAY        = 90;
  SIID_MEDIAVCD           = 91;
  SIID_MEDIADVDPLUSR      = 92;
  SIID_MEDIADVDPLUSRW     = 93;
  SIID_DESKTOPPC          = 94;
  SIID_MOBILEPC           = 95;
  SIID_USERS              = 96;
  SIID_MEDIASMARTMEDIA    = 97;
  SIID_MEDIACOMPACTFLASH  = 98;
  SIID_DEVICECELLPHONE    = 99;
  SIID_DEVICECAMERA       = 100;
  SIID_DEVICEVIDEOCAMERA  = 101;
  SIID_DEVICEAUDIOPLAYER  = 102;
  SIID_NETWORKCONNECT     = 103;
  SIID_INTERNET           = 104;
  SIID_ZIPFILE            = 105;
  SIID_SETTINGS           = 106;
  SIID_DRIVEHDDVD         = 132;
  SIID_DRIVEBD            = 133;
  SIID_MEDIAHDDVDROM      = 134;
  SIID_MEDIAHDDVDR        = 135;
  SIID_MEDIAHDDVDRAM      = 136;
  SIID_MEDIABDROM         = 137;
  SIID_MEDIABDR           = 138;
  SIID_MEDIABDRE          = 139;
  SIID_CLUSTEREDDRIVE     = 140;
  SIID_MAX_ICONS          = 175;

function SHGetStockIconInfo(siid: SHSTOCKICONID; uFlags: UINT; var psii: TSHStockIconInfo): HRESULT; stdcall;

implementation

const
  SHELL32 = 'shell32.dll';

function SHGetStockIconInfo; external SHELL32 name 'SHGetStockIconInfo';

end.