TButton 和 TBitBtn,继承和 ImageList 支持

TButton and TBitBtn, inheritance and ImageList support

下面的问题讨论了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 子类发布那些相同的属性。属性现在在对象检查器中可见。我可以 select 图像列表组件,甚至可以从可用图像中选择图像索引。

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

编辑:

这 link 提到 TBitBtn 故意禁用 ImageList 的使用以支持其自己的绘图:

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

尽管如此,关于如何尽可能顺利地完成上述从 bmp 图标到 png 图标的“婴儿步骤”迁移,有什么建议吗?

版本信息:10.3.1

谢谢!

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

起初,我想到了一个插入器 class 没有发布 ImageIndex 和图像。这甚至不是必需的。 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.

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

有趣的事实:

Did you know that in older versions of Delphi basic TButton didn't support showing any icons at all. So in the past if you wanted to have button with an icon on it you had to use TBitBtn instead.

现在查看 Delphi 10.4 的文档,似乎 TCustomButton class 有重大变化,它引入了额外的属性来确定不同按钮状态的图像索引,本质上允许任何按钮为多个状态提供多个图像。 Delphi 10.4.

中的标准 TButton 也是如此

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

上得到完全支持

因此,无论您在当前版本中采取什么“初始步骤”,请注意,当您决定迁移到 Delphi 10.4 或更高版本时,它们可能会被破坏。

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

我正在使用 Delphi XE5,在我的例子中,我尝试使用这段代码并且它有效:

ImageList1.GetBitmap(0, BitBtn1.Glyph);