如何获取驱动器、设备或文件的默认系统图标
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.
我正在创建一个远程文件管理器。服务器端应用程序获取计算机中的驱动程序、目录和文件列表,将其保存为流并在我当前所在的计算机中将其发送给我。一切正常。
在当前计算机中,首先我使用 "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.