为什么在TIcon中使用TCanvas.StretchDraw时,设计上存在问题导致其无法按预期工作?

3

最近我发现,在对象是TIcon实例的情况下,TCanvas.StretchDraw不会按预期工作(查看一下TIcon.DrawDrawIconEx方法就知道原因了)。Delphi 帮助文档也承认了这个问题。我知道解决方法,但我不知道VCL中为什么会有这样的设计决策。是否有人知道他们为什么决定在此事上保留TIcon不变?


2
我不会期望得到除了“这是设计如此”的答案之外的其他回答。 - TLama
1
这只是反映了底层API。如果你想要StretchDraw,把图像放在位图中,然后从那里进行操作。这不是Delphi的问题。所有标签都是你的,但实际上这是一个winapi问题。 - David Heffernan
2
@DavidHeffernan 我希望你在说这不是 Delphi 问题之前先看一下代码。@TLama 为什么要比较大小呢?为什么不直接调用 DrawIconEx(ACanvas.FHandle, Left, Top, Handle, Right - Left, Bottom - Top, 0, 0 , DI_NORMAL) 呢?至少不需要显式地将图标传递给临时位图。我展示的那行代码已经足够了。 - Wodzu
1
很明显我在胡说八道。抱歉。 - David Heffernan
1
简单的解决方法和答案。这是设计上的问题。此外,我认为它不会破坏现有的VCL代码库,因为为什么会明确地调用TIconStretchDraw,而实际上此时根本没有拉伸。是的,它可能会破坏某些人的代码,但我不认为它会影响VCL。 - TLama
显示剩余14条评论
1个回答

1
图标不是常规位图。这主要是由于历史设计和技术原因。
在图标小而且只有32x32像素大以及16种颜色的时代,图标永远不会在屏幕上被拉伸,这在当时是有意义的。
但也有一个“常识”技术原因。这样小的位图通常很难通过算法进行重新调整大小(默认的GDI伸展算法非常快,但在其他插值模式方面(例如GDI+可用)方面产生的结果也非常糟糕),因此决定将一组图标嵌入可执行文件中作为资源:每个尺寸一个图标。伸展过程受益于在设计时由图标设计师按像素级别完成。那时候,使用专门的图标并使用减少的调色板也消耗更少的资源。
由于您应该拥有一组具有预定义大小的图标,因此不需要使用StrechDraw,只需选择正确的图标进行显示。
如果您想显示指定大小的图标,请确保选择正确的大小,或者获取最大的图标并使用临时位图进行扩展,可以使用DrawIconEx()。或者,更好的方法是不使用图标,而是使用位图或矢量图形绘制,特别是当您需要巨大的图片尺寸时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接