Delphi:使用来自动态表单的 public 程序
Delphi: Use public procedures from a dynamic form
我有一个 Delphi XE+ 应用程序,其中包含 3 个表单,其中 2 个是动态创建的,如下所示:
form_main
正在触发 form_equip
form_equip
正在触发 form_certif
form_main
-> form_equip
-> form_certif
第 1:打开 form_equip
procedure Tform_main.button_equip_addClick(Sender: TObject);
var
form_equip: Tform_equip;
begin
form_equip:= Tform_equip.Create(Self);
form_equip.equip_id:= 0;
form_equip.ShowModal;
FreeAndNil(form_equip);
end;
在 form_equip
我有一个 public procedure has_changes
第 2 次:打开 form_certif
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(Self);
form_certif.index:= 0;
form_certif.ShowModal;
FreeAndNil(form_certif);
end;
现在,当我从 form_certif
按下确定按钮时
procedure Tform_certif.button_okClick(Sender: TObject);
begin
//do something...
form_equip.has_changes; //this public procedure from form_equip is not visible because form was created as local var on form_main
end;
问题是,如何将 sender/parent 名称传输到 form_certif
,这样我才能从 form_equip
中看到 public 过程和变量?
一个简单的方法是在 unit_equip
内部声明为全局:
var
form_equip: Tform_equip
但我避免这样做,因为 form_equip
可以在多个 windows 中以不同的名称动态打开...
在构造函数中将信息作为参数传递。像这样声明构造函数:
constructor Create(AOwner: TComponent; const ParentName: string);
在构造函数的实现中,记下传递的名称。
将所有需要的信息从 form_equip
传递到 form_certif
。这样 form_certif
就与 form_equip
.
的任何依赖关系解耦了
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(nil);
try
form_certif.index:= 0;
// Pass all other needed variable values to form_certif
// including callback methods
form_certif.Has_Changes_Method := Self.Has_Changes();
if form_certif.ShowModal = mrOk then
begin
// take care of changes
end;
finally
FreeAndNil(form_certif);
end;
end;
这就是 form_certif
单元中的样子:
type
THas_Changes_Method = procedure of Object;
TForm_Certif = class(TForm)
...
private
FIndex: Integer;
FHasChanges: THas_Changes_Method;
public
property Index: Integer read FIndex write FIndex;
property Has_Changes_Method: THas_Changes_Method read fHasChanges write fHasChanges;
end;
由于您是在代码中创建表单,因此您可以向表单添加自定义构造函数并将其他表单作为参数传递。
Tform_certif = class(TForm)
...
protected
form_equip: Tform_equip;
public
constructor Create(AOwner: TComponent; Aform_equip: Tform_equip); reintroduce;
end;
constructor Tform_certif.Create(AOwner: TComponent; Aform_equip: Tform_equip);
begin
inherited Create(AOwner);
form_equip := Aform_equip;
end;
所以现在您可以调用 form_equip.has_changes
,因为它是您在构造 Tform_certif
表单期间初始化的字段,它指向创建此表单的 Tform_equip
的特定实例Tform_certif
.
的特定实例
procedure Tform_certif.button_okClick(Sender: TObject);
begin
//do something...
// test whether form_equip is assigned to avoid AV by calling methods on nil object
if Assigned(form_equip) then form_equip.has_changes;
end;
要创建您的 Tform_certif
,您将使用以下代码
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(Self, Self);
form_certif.index:= 0;
form_certif.ShowModal;
FreeAndNil(form_certif);
end;
上面的构造函数代码还有一种变体,只需要传一个参数,然后在构造函数中测试AOwner
是否是Tform_equip
类型,不需要改button_certif_addClick
中的代码用于使用那种解决方案。
Tform_certif = class(TForm)
...
protected
form_equip: Tform_equip;
public
constructor Create(AOwner: TComponent); override;
end;
constructor Tform_certif.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is Tform_equip then form_equip := Tform_equip(AOwner);
end;
我有一个 Delphi XE+ 应用程序,其中包含 3 个表单,其中 2 个是动态创建的,如下所示:
form_main
正在触发form_equip
form_equip
正在触发form_certif
form_main
-> form_equip
-> form_certif
第 1:打开 form_equip
procedure Tform_main.button_equip_addClick(Sender: TObject);
var
form_equip: Tform_equip;
begin
form_equip:= Tform_equip.Create(Self);
form_equip.equip_id:= 0;
form_equip.ShowModal;
FreeAndNil(form_equip);
end;
在 form_equip
我有一个 public procedure has_changes
第 2 次:打开 form_certif
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(Self);
form_certif.index:= 0;
form_certif.ShowModal;
FreeAndNil(form_certif);
end;
现在,当我从 form_certif
procedure Tform_certif.button_okClick(Sender: TObject);
begin
//do something...
form_equip.has_changes; //this public procedure from form_equip is not visible because form was created as local var on form_main
end;
问题是,如何将 sender/parent 名称传输到 form_certif
,这样我才能从 form_equip
中看到 public 过程和变量?
一个简单的方法是在 unit_equip
内部声明为全局:
var
form_equip: Tform_equip
但我避免这样做,因为 form_equip
可以在多个 windows 中以不同的名称动态打开...
在构造函数中将信息作为参数传递。像这样声明构造函数:
constructor Create(AOwner: TComponent; const ParentName: string);
在构造函数的实现中,记下传递的名称。
将所有需要的信息从 form_equip
传递到 form_certif
。这样 form_certif
就与 form_equip
.
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(nil);
try
form_certif.index:= 0;
// Pass all other needed variable values to form_certif
// including callback methods
form_certif.Has_Changes_Method := Self.Has_Changes();
if form_certif.ShowModal = mrOk then
begin
// take care of changes
end;
finally
FreeAndNil(form_certif);
end;
end;
这就是 form_certif
单元中的样子:
type
THas_Changes_Method = procedure of Object;
TForm_Certif = class(TForm)
...
private
FIndex: Integer;
FHasChanges: THas_Changes_Method;
public
property Index: Integer read FIndex write FIndex;
property Has_Changes_Method: THas_Changes_Method read fHasChanges write fHasChanges;
end;
由于您是在代码中创建表单,因此您可以向表单添加自定义构造函数并将其他表单作为参数传递。
Tform_certif = class(TForm)
...
protected
form_equip: Tform_equip;
public
constructor Create(AOwner: TComponent; Aform_equip: Tform_equip); reintroduce;
end;
constructor Tform_certif.Create(AOwner: TComponent; Aform_equip: Tform_equip);
begin
inherited Create(AOwner);
form_equip := Aform_equip;
end;
所以现在您可以调用 form_equip.has_changes
,因为它是您在构造 Tform_certif
表单期间初始化的字段,它指向创建此表单的 Tform_equip
的特定实例Tform_certif
.
procedure Tform_certif.button_okClick(Sender: TObject);
begin
//do something...
// test whether form_equip is assigned to avoid AV by calling methods on nil object
if Assigned(form_equip) then form_equip.has_changes;
end;
要创建您的 Tform_certif
,您将使用以下代码
procedure Tform_equip.button_certif_addClick(Sender: TObject);
var
form_certif: Tform_certif;
begin
form_certif:= Tform_certif.Create(Self, Self);
form_certif.index:= 0;
form_certif.ShowModal;
FreeAndNil(form_certif);
end;
上面的构造函数代码还有一种变体,只需要传一个参数,然后在构造函数中测试AOwner
是否是Tform_equip
类型,不需要改button_certif_addClick
中的代码用于使用那种解决方案。
Tform_certif = class(TForm)
...
protected
form_equip: Tform_equip;
public
constructor Create(AOwner: TComponent); override;
end;
constructor Tform_certif.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is Tform_equip then form_equip := Tform_equip(AOwner);
end;