在运行时,我想加载并显示特定MenuItem中特定.EXE文件的主图标。如果此特定.EXE文件无法执行此操作(例如,由于访问限制或类似原因),则应将MenuItem图标设置为特定ImageList中的特定图标(例如,MyMenuItem.ImageIndex:= 7)。怎么办呢?
答案 0 :(得分:2)
我认为最简单的解决方案是使用ExtractIconEx
。这是一个非常简单的例子:
type
PHICON = ^HICON;
function ExtractIconEx(lpszFile: LPCWSTR; nIconIndex: Integer;
phiconLarge, phiconSmall: PHICON; nIcons: UINT): UINT; stdcall; external 'shell32.dll' name 'ExtractIconExW';
function GetSmallIconFromExecutableFile(const FileName: string): TIcon;
var
Icon: HICON;
ExtractedIconCount: UINT;
begin
Result := nil;
try
ExtractedIconCount := ExtractIconEx(
PChar(FileName),
0,
nil,
@Icon,
1
);
Win32Check(ExtractedIconCount=1);
Result := TIcon.Create;
Result.Handle := Icon;
except
Result.Free;
raise;
end;
end;
答案 1 :(得分:1)
与可执行文件关联的图标是模块中的第一个图标。所以你可以像这样提取它:
function EnumResNameProc(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPTSTR; lParam: LONG_PTR): BOOL; stdcall;
begin
HICON(Pointer(lParam)^) := LoadImage(
hModule,
lpszName,
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
0
);
Result := False;
end;
function GetFirstSmallIcon(hmod: HMODULE): HICON;
begin
Result := 0;
EnumResourceNames(hmod, RT_GROUP_ICON, @EnumResNameProc, NativeInt(@Result));
end;
function GetSmallIconFromExecutableFile(const FileName: string): TIcon;
const
LOAD_LIBRARY_AS_IMAGE_RESOURCE = $00000020;
var
hmod: HMODULE;
Icon: HICON;
begin
Result := nil;
try
hmod := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE or LOAD_LIBRARY_AS_DATAFILE);
Win32Check(hmod<>0);
try
Icon := GetFirstSmallIcon(hmod);
if Icon<>0 then begin
Result := TIcon.Create;
Result.Handle := Icon;
end;
finally
FreeLibrary(hmod);
end;
except
Result.Free;
raise;
end;
end;