无法在 运行 时间添加到虚拟图像列表的菜单上显示图标

Unable to display an Icon on a Menu added at run time to a Virtual Image List

我无法让图标出现在 运行 时添加的菜单项上。 我正在向主菜单添加一个菜单项,其图像 属性 链接到 TVirtualImageList,而 TVirtualImageList 又链接到 TImageCollection。所有固定图像都保存在虚拟图像列表中,在 运行 时间我添加了额外的菜单项,将每个图像作为图标添加到虚拟图像列表中。主菜单有一个附加菜单附加到的虚拟菜单项。

function LoadIconFromFile(FileName: String; Var Icon: TIcon): Integer;  overload;
var SHInfo: TSHFileInfo;
begin
  Result := -1;
  if not FileExists(FileName) then exit;
  SHGetFileInfo(PChar(FileName), 0, SHInfo, SizeOf(SHInfo), SHGFI_ICON OR SHIL_LARGE);
  Icon.Handle := SHInfo.hIcon;
  Icon.Transparent := true;
  result := 00;
end;    

TmpIcon := TIcon.Create;
LoadIconFromFile(FileName, TmpIcon);
MenuItem.ImageIndex := vilMenues.AddIcon(TmpIcon);
image1.Picture.Graphic := TmpIcon;
TmpIcon.Free;
MainMenu.BaseMenuItem.Add(MenuItem);

为了确保我实际上正确地拾取了图标,我还在 TImage 中显示。添加了附加菜单项,图标出现在 TImage 控件中,但从未出现在菜单上。我知道图像被添加到图像列表中是因为图像计数增加了。我曾尝试在更新之前从主菜单中分离图像列表并在之后重新附加,但这没有任何区别。我开始怀疑 TVirtualImageList 是否能够处理混合图像源?

谁能告诉我如何解决这个问题?

TImageCollection 不支持图标。

当您使用 AddIcon 方法时,TCustomImageList.AddIcon 会调用覆盖的方法 TVirtualImageList.DoChange,该方法会更新图像集合中的整个虚拟图像列表。

因此,如果您在虚拟图像列表中有 3 个图像并调用 AddIcon,它将 return 一个新的图像索引 3,现在列表中有 4 个图像。但是随后虚拟映像列表被重新创建并且其 Count 返回到 3.

我用下面的代码让它工作:

TmpIcon := TIcon.Create;
Strm := TMemoryStream.Create;
LoadIconFromFile(FileName, TmpIcon);// get icon from file
tmpIcon.SaveToStream(Strm);
s := 'X'+IntToStr(idx);  // Add a name for new item
ImageCollection1.Add(s, strm);  // Add to collection
idy:= ImageCollection1.Count -1;  // Get the index for it
vilMenues.Add(s,idy);  // Add it to virtual image list
MenuItem.ImageIndex := vilMenues.Count -1;
Strm.Free;
TmpIcon.Free;

比较笨拙,感觉一定有更好的方法...