【问题标题】:Delphi and 48x48 (or bigger) imagelists - is there a workaround?Delphi 和 48x48(或更大)图像列表 - 有解决方法吗?
【发布时间】:2011-01-28 18:50:26
【问题描述】:

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

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

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

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

谢谢!

【问题讨论】:

    标签: delphi delphi-7 imagelist timagelist tpngimagelist


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您的评论,我已经设法找到了解决方案。
    【解决方案2】:

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

    显然,如果您尝试在 Delphi7 中将大于 32x32 的图标添加到 timagelist 中,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;
    

    【讨论】:

    • 您确定要将图像添加到系统图像列表中吗?
    • 您链接到的 Chris 的文章并未讨论 >32px 图像。它是大约 32bpp 颜色深度图像。您在这里所做的只是调整图像大小。
    【解决方案3】:

    TImageList 仅在 2 种情况下引发“图像大小无效”错误:

    1) TImageList 的 Height 或 Width 属性小于 1,或者 Height 属性大于 32768,当 TImageList 最初是通过 CreateSize() 构造函数创建时(Height 和 Width 属性没有这样的限制二传手)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-08
      • 2011-03-12
      • 1970-01-01
      • 2015-12-07
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多