Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

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

I am creating a remote file manager. The server side application gets the list of drivers, directories and files in the computer, saves it as stream and send it to me in the current computer where I am. Everything works fine.

In the current computer, first I use the "OnCreate" event to fill a TListImage with shell icons (from the same current computer) and link it with the ListView where the file list will be showed. So, once received the list, I use this funcion below to show the generic file icon in the 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;

With file name/extension I can get the correct shell icon, even in a different computer. But I also need to show the correct drive type icon. For example, on remote computer "D:" is a local fixed drive, but on current computer "D:" is a CD/DVD drive, so I cannot use the drive letter to get this icon. I need a way to get a "generic" drive type icon index from remote computer (fixed drive) and send it to the current computer.

For example, my goal is to obtain a default icon for a local hard dive, a default icon for a remote disk, a CD/DVD device and so on...

Sorry about mistakes, english is not my native language. I did my best to try to explain.

Maybe what I need is impossible, just let me know please...

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You definitely have to use the SHGetStockIconInfo function:

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

The siid parameter of type SHSTOCKICONID is used to identify which stock system icon to retrieve.

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;

You may call the above like this GetDefaultSystemIcon(SIID_DRIVECD) to get the default CDROM drive icon index.


From the Microsoft documentation:

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

Older ShellAPI units may not have the SHGetStockIconInfo declaration: in this case the following unit must be added to the Delphi project.

Please notice that the use of the unit below is restricted to the availability of the SHGetStockIconInfo function in the shell32.dll system library - i.e. the library is required to export the function.

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       = $000000020;
  SHGFI_ATTR_SPECIFIED    = $000020000;
  SHGFI_ATTRIBUTES        = $000000800;
  SHGFI_DISPLAYNAME       = $000000200;
  SHGFI_EXETYPE           = $000002000;
  SHGFI_ICON              = $000000100;
  SHGFI_ICONLOCATION      = $000001000;
  SHGFI_LARGEICON         = $000000000;
  SHGFI_LINKOVERLAY       = $000008000;
  SHGFI_OPENICON          = $000000002;
  SHGFI_OVERLAYINDEX      = $000000040;
  SHGFI_PIDL              = $000000008;
  SHGFI_SELECTED          = $000010000;
  SHGFI_SHELLICONSIZE     = $000000004;
  SHGFI_SMALLICON         = $000000001;
  SHGFI_SYSICONINDEX      = $000004000;
  SHGFI_TYPENAME          = $000000400;
  SHGFI_USEFILEATTRIBUTES = $000000010;

  //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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...