【问题标题】:TButton and TBitBtn, inheritance and ImageList supportTButton 和 TBitBtn,继承和 ImageList 支持
【发布时间】:2020-12-05 22:54:28
【问题描述】:

下面的问题讨论了 TButton 和 TBitBtn 之间的继承链是如何变化的,即引入了一个共同的祖先,TCustomButton。

What happened to TBitBtn and TButton inheritance chain?

过去,那些想要在按钮上显示图形的人会选择 TBitBtn,因为它提供了位图字形的使用。

在较新的 Delphi 版本中,标准 TButton 允许指定 TImageList 以支持 png / jpg,而 TBitBtn 则不允许。

我的(长期)按钮子类继承自 TBitBtn,更改它意味着潜在的应用程序范围的按钮重新设计。没时间了。我希望能够随着时间的推移逐步迁移事物,而无需删除和重新创建按钮(有可能错过属性或事件的迁移)。最好选择一个按钮,擦除其字形,将 png 放入其图像列表中。

查看 VCL.Buttons 和 VCL.StdCtrls 的源代码,ImageList、ImageIndex ... 的大部分工作都是在共同的祖先 TCustomButton 上完成的。 TButton 只发布那些在设计时使用的属性。

太好了,我可以简单地让我的 TBitBtn 子类发布这些相同的属性。这些属性现在在对象检查器中可见。我可以选择一个图像列表组件,甚至可以从可用图像中选择一个图像索引。

这就是事情停止工作的地方:所选图像不会在设计时显示,也不会在运行时显示。分配一个字形,它会毫无问题地显示出来。我尝试查看可能会干扰 png 绘制的其他属性(可能是某种透明度选项),但徒劳无功。

编辑:

此链接提到 TBitBtn 故意禁用 ImageList 的使用以支持其自己的绘图:

http://codeverge.com/embarcadero.delphi.graphics/tbitbtn-with-png-on-d2009/1077124

不过,对于如何尽可能顺利地实现上述从 bmp 图标到 png 图标的“婴儿步骤”迁移,有什么建议吗?

版本信息:10.3.1

谢谢!

【问题讨论】:

  • TBitBtnTButton 之间存在显着差异,这将使您的“婴儿步”变得非常困难。你看到的标准TButton 总是只显示一个图像TBitBton 实际上可以包含多达四个存储在同一个图像中的字形。这四个图像用于显示按钮的不同状态(Up、Disabled、Clicked、Down)。为了绘制所需的图像,它使用 ImageList 代码从提供的图像中提取所需的字形。这使得无法从图像列表加载图像到 TBitBtn。
  • 现在查看 Delphi 10.4 的文档,TCustomButton 类似乎发生了重大变化,它引入了额外的属性来确定不同按钮状态的图像索引,基本上允许任何按钮具有多个状态的多个图像.
  • 因此,无论您在当前版本中所做的“小步骤”如何,请注意,当您决定迁移到 Delphi 10.4 或更高版本时,它们可能会被破坏。在您的情况下,我会考虑在对您的自定义版本TButBtn 进行任何更改之前升级到最新版本的 Delphi。也许对TCustomButton 的新更改也将帮助您简化自定义按钮的代码。
  • 正确,因此迁移到 10.4 将有效地允许我一次更改一个按钮,而不会在整个应用程序中产生任何副作用。这似乎确实是最佳选择。现在,这是否使 TButton 和 TBitBtn 之间的区别成为历史区别,还是仍然有任何用例可以选择这个而不是那个?
  • 另外,如果你不介意把它写下来作为答案,我可以接受。谢谢!

标签: delphi vcl


【解决方案1】:

我用 Delphi 10.4.1 测试过,效果很好。

起初,我考虑了一个插入器类来发布 ImageIndex 和 Images。这甚至不是必需的。 Delphi 10.4.1 中的 TBitBtn 已经发布了这两个属性。我以前没有注意到这一点!

代码如下:

unit BitBtnInheritenceDemoMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons,
  System.ImageList, Vcl.ImgList;

type   
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    ImageList1: TImageList;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
    // Properties could also be assigned thru object inspector
    BitBtn1.Images     := ImageList1;
    BitBtn1.ImageIndex := 1;
end;

end.

【讨论】:

  • 我在 Delphi 10.3.1 中尝试过同样的方法,但没有成功。难道是在 10.4.1 中,TBitBtn 的 Images 属性在设计时可用,而不使用插入器类?
  • TBitBtn 和底层TCustomButton 以及在 Delphi 10.4 中引入的、在 Delphi 10.3 中不存在的重大更改。最值得注意的是能够自然地将TbitBtn 连接到外部图像列表,然后为每个按钮状态指定图像索引。这在 Delphi 10.3 或更早版本中不存在,其中TBitBtn 存储一个可以选择存储多个字形的图像。为了根据TBitBtn 状态呈现正确的字形,它会在内部使用ImageList 代码从存储的图像中提取所需的字形。
  • @SilverWarior 我明白了,所以以前仅供内部使用的 ImageList 已在 Delphi 10.4 中向用户公开。这与 fpiette 的回答一致。
  • @Khorkhe 我编辑了我的答案以删除插入器类。 TBitBtn 在 Delphi 10.4.1 中使用图像列表开箱即用。我之前写的interposer本质上是Delphi 10.4.1的noop。我建议你将你的 Delphi 升级到最新版本。
  • 这对 PNG 支持来说是个好消息。想知道此时这两个类是否可以互换(减去字形)
【解决方案2】:

TBitBtnTButton 之间存在显着差异,这将使您的“婴儿步”变得非常困难。您会看到与标准的 TButton 不同,它总是只显示一个图像 TBitBtn 实际上最多可以包含四个存储在同一图像中的 Glyphs。这四个图像用于显示按钮的不同状态(UpDisabledClickedDown)。为了绘制所需的图像TBitBtn 使用ImageList 代码从提供的图像中提取所需的Glyph。这使得无法从图像列表加载图像到TBitBtn

趣事:

你知道吗?在旧版本的 Delphi basic TButton 中没有 支持显示任何图标。所以在过去如果你想拥有 带有图标的按钮,您必须改用TBitBtn

现在查看 Delphi 10.4 的文档,TCustomButton 类似乎发生了重大变化,它引入了额外的属性来确定不同按钮状态的图像索引,基本上允许任何按钮具有多个状态的多个图像。 Delphi 10.4 中的标准 TButton 也是如此。

虽然这使标准的TButton 功能更接近于TBitBtn 的功能,但仍有很多情况下您更愿意使用TBitBtn。例如,标准TButton 的一个显着缺点是您不能像更改按钮文本的颜色那样完全更改其标题的字体属性。但是TBitBtn 完全支持这一点。


因此,无论您在当前版本中所做的“小步骤”如何,请注意,当您决定迁移到 Delphi 10.4 或更高版本时,它们可能会被破坏。

在您的情况下,我强烈建议您在对自定义版本的 TBitBtn 进行任何更改之前考虑升级到最新版本的 Delphi。也许对TCustomButton 以及随后对TBitBtn 本身的新更改也将帮助您简化自定义按钮的代码。

【讨论】:

  • 这证实了我们的按钮从 TBitBtn 子类化而不是 TButton 在过去的原因。正如@fpiette 在他的回答中所建议的那样,似乎在 10.4 中同时指定 bmp 和 png 会优先考虑图像列表。有了它,我应该能够轻松地一次更改一个按钮图标,而不会在整个应用程序中引入任何重大更改的风险。希望我能接受这两个答案,因为它们都添加了有价值的信息。
【解决方案3】:

我正在使用 Delphi XE5,就我而言,我尝试使用此代码并且它有效:

ImageList1.GetBitmap(0, BitBtn1.Glyph);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    相关资源
    最近更新 更多