如何创建从少数其他组件继承的 Delphi 组件?

Posted

技术标签:

【中文标题】如何创建从少数其他组件继承的 Delphi 组件?【英文标题】:How to create Delphi component inherited from few other components? 【发布时间】:2014-01-10 11:53:13 【问题描述】:

我发现有关如何创建 delphi 组件的教程很好,但它们仅使用现有组件之一作为对象来继承操作。像这样的

unit CountBtn;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, ExtCtrls;

type
 TCountBtn = class(TButton)
  private
  FCount: integer;
  protected
  procedure Click;override;
  public
  procedure ShowCount;
  published
  property Count:integer read FCount write FCount;
  constructor Create(aowner:Tcomponent); override;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents('Mihan Components', [TCountBtn]);
end;

constructor TCountBtn.Create(aowner:Tcomponent);
begin
 inherited create(Aowner);
end;

procedure Tcountbtn.Click;
begin
 inherited click;
 FCount:=FCount+1;
end;

procedure TCountBtn.ShowCount;
begin
 Showmessage('On button '+ caption+' you clicked: '+inttostr(FCount)+' times');
end;

end.

但是如果我需要使用很少元素的组件,我该怎么办?可以说,我得到了 ButtonEdit 字段。在按钮上单击编辑字段中的文本应该与按钮上的文本相同。我开始这样做,但似乎它不会像我想要的那样工作:

unit TestComp;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TUiCompU = class(TCustomControl)
  private
     Private declarations 
    FButton: TButton;
    FEdit: TEdit;

  protected
     Protected declarations 
    procedure Paint; override;
    //wrong!
    procedure FButton.Click;override
  public
     Public declarations 
    constructor Create(AOwner: TComponent); override;
  published
     Published declarations 
    //wrong!
     property ButtonText: String read FButton.Caption write FButton.Caption;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Ui', [TUiCompU]);
end;

 TUiCompU 

constructor TUiCompU.Create(AOwner: TComponent);
begin
  inherited;
  Width := 200;
  Height := 50;

  FButton := TButton.Create(Self);
  FButton.SetSubComponent(True);
  FButton.Parent := Self;
  FButton.Top := 8;
  FButton.Left := 50;
  FButton.Width := 35;
  FButton.Name := 'Button';

  FEdit := TEdit.Create(Self);
  FEdit.SetSubComponent(True);
  FEdit.Parent := Self;
  FEdit.Top := 8;
  FEdit.Left := 84;
  FEdit.Width := 121;
  FEdit.Name := 'Edit';
end;

procedure TUiCompU.Paint;
begin
  Canvas.Rectangle(ClientRect);
end;

end.

我应该如何在这里添加Click程序,这是真正的点击按钮?是否有关于如何使用其他人制作好的组件的好教程? (我需要创建类似幻灯片组件的东西)。 谢谢,对不起我的英语。

【问题讨论】:

试试海关集装箱和组件包。它是由 Borland 莫斯科办事处为 Delphi 4/5 创建的,作为一种将表单(所有组件放置在那里,事件,属性等)转换为全新复合组件的方法。这很酷,我认为这种方法(基于封装)比 Delphi 5 引入的TFrame 更好(并且没有封装)。我在 SourceForge 上听说有一个 CCCP 到 Delphi XE2 的端口,但我没有亲自尝试过。以及图片被剥离的旧方法:howtodothings.com/computers/… 一些与此主题相关的高级东西:***.com/questions/582903/… @user928177263 很高兴看到这个问题很有用并且大家检查一下 【参考方案1】:

您可以为子组件事件编写方法,但它有一个很大的弱点;如果您发布这些子组件,则可能有人会通过编写自己的方法来窃取您的此绑定:

type
  TUiCompU = class(TCustomControl)
  private
    FEdit: TEdit;
    FButton: TButton;
    procedure ButtonClick(Sender: TObject);
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

constructor TUiCompU.Create(AOwner: TComponent);
begin
  inherited;

  FButton := TButton.Create(Self);
  ...
  FButton.OnClick := ButtonClick;

  FEdit := TEdit.Create(Self);
  ...
  FEdit.OnKeyDown := EditKeyDown;
end;

procedure TUiCompU.ButtonClick(Sender: TObject);
begin
  // do whatever you want here
end;

procedure TUiCompU.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  // do whatever you want here
end;

【讨论】:

哦,谢谢你的回答!几乎几分钟前,我什至看到了你的一个答案!但是有没有办法避免这种绑定? 嗯,绑定是实现您要实现的目标的最简单方法,除了窃取事件处理程序的风险(如果您将这些子控件公开),它没有任何问题。据我所知,任何其他方式都需要破解这些子控件,例如通过覆盖它们的窗口过程或从它们的动态方法(如ClickKeyDown 等方法)中引入某种通知机制。

以上是关于如何创建从少数其他组件继承的 Delphi 组件?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 组件的编程

Delphi (CM_) 中的组件消息和自定义图形设计时组件

为 TCustomControl Delphi 捕获/创建 OnGetFocus/OnLostFocus 事件

Delphi如何访问父窗体

如何在 Delphi 中创建 TMS TAdvPage 的派生组件

Delphi如何检测表单上任何地方的点击事件,包括其他组件