在运行时,我想在特定的 MenuItem 中加载并显示特定 .EXE 文件的主图标。如果此特定 .EXE 文件无法执行此操作(例如,由于访问限制或类似原因),则应将 MenuItem 图标设置为特定 ImageList 中的特定图标(例如 MyMenuItem.ImageIndex := 7)。如何才能做到这一点?
问问题
1029 次
2 回答
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;
于 2013-05-20T19:09:58.310 回答
2
与可执行文件关联的图标是模块中的第一个图标。所以你可以像这样提取它:
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;
于 2013-05-20T19:55:34.173 回答