德尔福和48x48(或更大)的图像列表 - 是否有解决方法?

时间:2011-01-28 18:50:27

标签: delphi delphi-7 imagelist timagelist tpngimagelist

我正在获取系统图像列表(使用SHGetFileInfo和SHGFI_LARGEICON),添加两个我自己的图标并将其附加到TListView。

问题是,如果用户的图标大小未设置为32x32(例如设置为48x48),则Delphi7 TImageList会因“图像大小无效”错误而失败。

有没有人知道是否有可用的解决方法?我尝试过使用TPngImageList但它会导致其他问题。

另外,请注意我想保留图标的Alpha通道。正常的1位透明度是不够的,因为图标往往看起来很丑陋。

谢谢!

3 个答案:

答案 0 :(得分:5)

我不知道TImageList可以容纳的图像大小有任何限制。听起来我的问题是你有不同大小的图标,你不能在同一图像列表中保存不同大小的图标。

如果您正在使用不同尺寸的图标,那么您将需要增大尺寸较小的图标。您必须使用位图在代码中构建它。您使用纯透明Alpha通道填充位图,然后将较小的图标blt到位图的中心。

另一种选择是维护两个单独的图像列表,但如果您需要将图标绘制到相同的列表视图中,那么我认为这不会完成工作。我的猜测是你需要增长小图标。

对于alpha,您需要自己创建图像列表句柄,因为D7中不存在ColorDepth属性。因此,香草D7 TImageList根本无法支持带alpha通道的图标。

您可以通过调用ImageList_Create,传递ILC_COLOR32并将结果分配给ImageList.Handle来解决此限制。在添加任何图像之前执行此操作。你必须在运行时填充列表而不是设计时间,但听起来你已经在做了。

这是一个48x48工具按钮的屏幕截图,带有带alpha透明度的32bpp图标:

48px icon from image list

确实,我在D2010中做到了这一点,但我的上述解决方法适用于D7 - 我使用该机制直到最近使用D6。我只是展示这个以证明图像列表可以容纳48px图标。由于TImageList只是系统映像列表组件的包装器,我相信你所尝试的应该是完全可行的。

答案 1 :(得分:3)

正当我即将放弃此页面时,我找到了解决方案: http://delphihaven.wordpress.com/2010/09/06/custom-drawing-on-glass-2/

显然,如果你试图在Delphi7中将一个大于32x32的图标添加到一个图像列表中,VCL会给你一个“无效的图像大小”错误,而它可以简单地调用himagelist API - 它可以轻松处理它。

以下是完整的解决方案:

unit ImageListFix;

interface

uses CommCtrl, Graphics, ImgList;

type
  TImageListFixer = class(TCustomImageList)
  public
    function AddIcon(Image: TIcon): Integer;
  end;

implementation

function TImageListFixer.AddIcon(Image: TIcon): Integer;
begin
  if Image = nil then
    Result := Add(nil, nil)
  else
  begin
    Result := ImageList_AddIcon(Handle, Image.Handle);
    Change;
  end;
end;

end.

将图标添加到系统图像列表的代码:

DocumentImgList:=TImageListFixer(GetSystemLargeIconsList);

IconToAdd:=TIcon.Create;
try
  IconToAdd.Handle := LoadImage(0, 'c:\Ico1.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
  DocumentImgList.AddIcon(IconToAdd);

  IconToAdd.Handle := LoadImage(0, 'c:\Ico2.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
  DocumentImgList.AddIcon(IconToAdd);
finally
  IconToAdd.Free;
end;

答案 2 :(得分:1)

TImageList仅在两个条件下引发“无效图像大小”错误:

1)当最初通过CreateSize()构造函数创建TImageList时,TImageList的Height或Width属性小于1,或者Height属性大于32768(高度和宽度属性没有强加这样的限制)设置器)。

2)您尝试添加/插入尺寸不适合TImageList内部图像的新TBitmap或TIcon。