这几天写个小东西, 需要获取系统正在运行的程序图标, 一般来说32*32就足够了, 不过既然Win7能够支持超大图标(256*256), 咱们也需要与时俱进, 说不定什么时候遇到个变态客户就有这要求了
找了下以前的资料, 获取程序图标基本都是用SHGetFileInfo来获取, 这样只能得到最大32*32的
想获取超大的需要用SHGetImageList这个API, 不过很奇怪Delphi里面虽然有这个API, 可是调用出错, 只能从DLL里面重新加载了
网上相关资料很少, 但是还是能找到的, 不过不知道为什么, 找到的都是一样的代码, 相对下面的代码网上的资料都是这样获取图标句柄的
Result := ImageList_GetIcon(nImageList, Pred(ImageList_GetImageCount(nImageList)), ILD_NORMAL);
虽然执行结果一样, 但是很让人费解, 另外, 这样做如果在程序内多次获取多个程序的图标就会出现得到的都是一样的图标的问题(是一个BUG)
解决方法: SHGetFileInfo函数本来就是获取图标索引的, 直接使用得到的结果就行了
Result := ImageList_GetIcon(nImageList, nFileInfo.iIcon, ILD_NORMAL);
完整函数如下
uses ShellAPI, CommCtrl; const SHIL_LARGE = 0; {32x32} SHIL_SMALL = 1; {16x16} SHIL_EXTRALARGE = 2; {48x48} SHIL_SYSSMALL = 3; {16x16} SHIL_JUMBO = 4; {256x256} function GetFileIconEX(AFile: string; ASHIL_FLAG: Cardinal): HICON; function _X: Boolean; {判断是否符合系统版本} begin Result := False; if Win32MajorVersion < 5 then Exit; if (Win32MajorVersion = 5) and (Win32MinorVersion < 1) then Exit; Result := True; end; type _SHGetImageList = function (iImageList: Integer; const riid: TGUID; var ppvObj: Pointer): HResult; stdcall; var nHandle: THandle; nImageList: HIMAGELIST; nSHGetImageList: _SHGetImageList; nFileInfo: TSHFileInfo; const IID_IImageList: TGUID = '{46EB5926-582E-4017-9FDF-E8998DAA0950}'; begin Result := 0; nHandle:= LoadLibrary('Shell32.dll'); nImageList := 0; if nHandle <> S_OK then try nSHGetImageList := GetProcAddress(nHandle, PChar(727)); if Assigned(nSHGetImageList) and _X then nSHGetImageList(ASHIL_FLAG, IID_IImageList, Pointer(nImageList)); finally FreeLibrary(nHandle); end; if nImageList > 0 then begin SHGetFileInfo(PChar(AFile), FILE_ATTRIBUTE_NORMAL, nFileInfo, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX); Result := ImageList_GetIcon(nImageList, nFileInfo.iIcon, ILD_NORMAL); end; end;