无法在 运行 时间添加到虚拟图像列表的菜单上显示图标
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;
比较笨拙,感觉一定有更好的方法...
我无法让图标出现在 运行 时添加的菜单项上。 我正在向主菜单添加一个菜单项,其图像 属性 链接到 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;
比较笨拙,感觉一定有更好的方法...