Delphi 和 48x48(或更大)图像列表 - 有解决方法吗?

发布于 2024-10-14 19:42:16 字数 290 浏览 8 评论 0原文

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

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

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

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

谢谢!

I'm getting the system imagelist (with SHGetFileInfo and SHGFI_LARGEICON), adding two of my own icons and attaching it to a TListView.

The problem is that if the user's icon size isn't set to 32x32 (like it's set to 48x48 for example) the Delphi7 TImageList fails with an "Invalid image size" error.

Does anyone know if a workaround is available? I've tried using TPngImageList but it leads to other issues.

Also, please note that I'd like to preserve the Alpha channel of the icons. Normal 1-bit transparency is not enough, as icons tend to look ugly that way.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Bonjour°[大白 2024-10-21 19:42:16

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

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

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

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

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

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

48px icon from image list

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

I'm not aware of any limitation on the size of images that TImageList can hold. It sounds to me that your problem is that you have icons of different sizes and you can't hold icons of different sizes in the same image list.

If you are working with icons of different sizes then you are going to need to grow the smaller ones in size. You'll have to build it up in code, using a bitmap. You fill the bitmap with pure transparent alpha channel and then blt the smaller icon onto the centre of the bitmap.

Another option would be to maintain two separate image lists but if you need to draw the icons into the same list view then I think that won't get the job done. My guess is that you'll need to grow the small icons.

For alpha, you're going to need to create the image list handle yourself because the ColorDepth property doesn't exist in D7. Because of this, a vanilla D7 TImageList simply cannot support icons with alpha channels.

You work around this limitation by calling ImageList_Create, passing ILC_COLOR32 and assigning the result to ImageList.Handle. Do this before you add any images. You'll have to populate the list at run time rather than design time, but it sounds like you are already doing that.

Here's a screen shot of a 48x48 tool button with a 32bpp icon with alpha transparency:

48px icon from image list

It's true that I made this in D2010, but my above workaround will work for D7 – I used that mechanism until quite recently with D6. I'm just showing this to prove that the image list can hold 48px icons. Since TImageList is just a wrapper around the system image list component, I believe what you are attempting should be perfectly feasible.

甜点 2024-10-21 19:42:16

就在我准备放弃这个页面时,我找到了解决方案:
http://delphihaven.wordpress.com/2010/ 09/06/custom-drawing-on-glass-2/

显然,如果你尝试在 Delphi7 中向 timagelist 添加一个大于 32x32 的图标,VCL 会给你一个“无效的图像大小”错误而它可以简单地调用 hisagelist 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;

Just when I was about to give up this page led me to the solution:
http://delphihaven.wordpress.com/2010/09/06/custom-drawing-on-glass-2/

Apparently, if you try to add an icon that is bigger than 32x32 to a timagelist in Delphi7, the VCL will give you an "Invalid image size" error while it could simply call the himagelist API - which can easily handle it.

Here is the complete solution:

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.

And the code for adding icons to the system imagelist:

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;
养猫人 2024-10-21 19:42:16

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

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

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

TImageList raises an "Invalid image size" error under only 2 conditions:

1) The TImageList's Height or Width property is less than 1, or the Height property is greater than 32768, when the TImageList is initially created via the CreateSize() constructor (there are no such limitations imposed by the Height and Width property setters).

2) you try to add/insert a new TBitmap or TIcon whose dimensions do not fit within TImageList's internal image.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文