Delphi 6使用构造函数创建新表单

时间:2013-11-03 07:33:34

标签: delphi

我是Delphi的新手,并且在动态创建新表单时遇到问题。我想用我制作的gui中的元素属性创建新表单。这是我想要动态创建的表单:

unit AddEmployeeF;

interface

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

type
  TAddEmployee = class(TForm)
    GroupBox1: TGroupBox;
    AddName: TLabel;
    AddDept: TLabel;
    AddPhone: TLabel;
    AddExtension: TLabel;
    AddDetails: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    procedure CancelButtonClick(Sender: TObject);
 private
    { Private declarations }
  public
    constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
  end;
var
  AddEmployee: TAddEmployee;

implementation

{$R *.dfm}
      constructor TAddEmployee.CreateNew(AOwner: TComponent; Dummy: Integer = 0; Detail : String);
begin
  inherited Create(AOwner);
  AddDetails.Caption := Detail;
end;


procedure TAddEmployee.CancelButtonClick(Sender: TObject);
begin
    self.Close;
end;

end.

我不想在构造函数中再次创建所有gui元素,只是为了修改元素的一些属性,比如标题,但保留gui定义中的位置和其他属性。这是可能的?以及如何从另一种形式创建表单,像这样? :

procedure TWelcome.SpeedButton1Click(Sender: TObject);
var
myForm :TAddEmployee;
begin
        myForm := TAddEmployee.CreateNew(AOwner, Dummy, Details);

     myForm.ShowModal;

end;

2 个答案:

答案 0 :(得分:8)

你覆盖了错误的构造函数。 TForm.CreateNew()构造函数绕过DFM流,因此不会在运行时创建所有设计时组件。更糟糕的是,重写的CreateNew()构造函数正在调用继承的TForm.Create()构造函数,它在内部调用CreateNew(),因此您将陷入无限循环,导致运行时出现堆栈溢出错误。

要执行您要求的操作,请改为覆盖TForm.Create()构造函数,或者在内部定义一个全新的构造函数,以调用TForm.Create()。根本不涉及TForm.CreateNew()

type
  TAddEmployee = class(TForm)
    ...
  public
    constructor Create(AOwner: TComponent); override; // optional
    constructor CreateWithDetail(AOwner: TComponent; Detail : String);
  end;

constructor TAddEmployee.Create(AOwner: TComponent);
begin
  CreateWithDetail(AOwner, 'Some Default Value Here');
end;

constructor TAddEmployee.CreateWithDetail(AOwner: TComponent; Detail : String);
begin
  inherited Create(AOwner);
  AddDetails.Caption := Detail;
end;

procedure TWelcome.SpeedButton1Click(Sender: TObject);
var
  myForm : TAddEmployee;
begin
  myForm := TAddEmployee.CreateWithDetail(AOwner, Details);
  myForm.ShowModal;
  myForm.Free;
end;

答案 1 :(得分:7)

像这样声明你的构造函数:

constructor Create(AOwner: TComponent; const Detail: string); reintroduce;

像这样实施:

constructor TAddEmployee.Create(AOwner: TComponent; const Detail: string);
begin
  inherited Create(AOwner);
  AddDetails.Caption := Detail;
end;

这样称呼:

myForm := TAddEmployee.Create(MainForm, Details);

我不确定你想要作为拥有者传递什么。可能是主要形式,也可能是其他形式。

您还应该删除名为AddEmployee的全局变量,因此强迫自己控制实例化表单。

我选择命名我的构造函数Create,因此隐藏该名称的继承构造函数,以强制该类的使用者提供Details参数,以便创建该类的实例。