Delphi XE2:在运行时将.EXE图标加载到MenuItem中

时间:2013-05-20 14:50:15

标签: delphi icons delphi-xe2

在运行时,我想加载并显示特定MenuItem中特定.EXE文件的主图标。如果此特定.EXE文件无法执行此操作(例如,由于访问限制或类似原因),则应将MenuItem图标设置为特定ImageList中的特定图标(例如,MyMenuItem.ImageIndex:= 7)。怎么办呢?

2 个答案:

答案 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;