如何解决 Delphi 中 2 个或更多 Unit 之间的 CYCLIC 关系问题?
How to solve the CYCLIC relation issue between 2 or more Units in Delphi?
我在 Delphi 2010 年使用了 2 个单元:Unit1 有一个带有 TEdit
和 Button
的表格,这个 Button
将从 Unit2 调用过程(Unit2 没有表单)。那个程序会改变Unit1的TEdit
的'caption'属性,我试着把Unit2在 Unit1 "Uses" 中访问程序,并将 Unit1 放在 Unit2[ 的 "Uses" 中=29=] 访问 Unit1 中的 TEdit
,但这种关系是循环的。
我不确定我能做些什么来解决这个问题,有什么建议吗?
有很多方法可以做到这一点,哪一种最合适主要取决于具体情况,所以从技术上讲这个问题对于 Stack Overflow 来说太宽泛了,我怀疑。
方法一
不过,让我向您展示一种非常简单的方法。这可能不是一个好方法,但它接近于您正在尝试做的事情。
- 创建一个新的 VCL 应用程序。
- 在主窗体上拖放一个
TButton
和一个 TEdit
控件(Unit1
中的 TForm1
)。
创建一个新单元,Unit2:
unit Unit2;
interface
procedure SetCaption;
implementation
uses
Unit1;
procedure SetCaption;
begin
Unit1.Form1.Edit1.Text := 'Hello, World!';
end;
end.
在主窗体上,将此事件处理程序用于按钮的 OnClick
事件:
procedure TForm1.Button1Click(Sender: TObject);
begin
Unit2.SetCaption;
end;
在 implementation
部分的 uses
子句中添加 Unit2
之后。完整,
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Unit2.SetCaption;
end;
end.
注意如果仅在实施部分引用这些单元如何相互使用。另请注意,我们在 Unit1
中使用全局变量 Form1
来引用自动创建的 TForm1
实例。在许多(大多数)情况下,您不想使用自动创建的表单,但那是另一回事(我可以在这里写一本 100 页的 Delphi 教科书!)。
方法二
此外,让我重申一个事实,即有许多其他方法可以实现此结果。例如,这可以说是一种更好的方法:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Unit2.SetCaption(Edit1);
end;
end.
unit Unit2;
interface
uses
StdCtrls;
procedure SetCaption(AEdit: TCustomEdit);
implementation
procedure SetCaption(AEdit: TCustomEdit);
begin
AEdit.Text := 'Hello, World!';
end;
end.
方法三
可以说更好:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := Unit2.GetText;
end;
end.
unit Unit2;
interface
function GetText: string;
implementation
function GetText: string;
begin
Result := 'Hello, World!';
end;
end.
我在 Delphi 2010 年使用了 2 个单元:Unit1 有一个带有 TEdit
和 Button
的表格,这个 Button
将从 Unit2 调用过程(Unit2 没有表单)。那个程序会改变Unit1的TEdit
的'caption'属性,我试着把Unit2在 Unit1 "Uses" 中访问程序,并将 Unit1 放在 Unit2[ 的 "Uses" 中=29=] 访问 Unit1 中的 TEdit
,但这种关系是循环的。
我不确定我能做些什么来解决这个问题,有什么建议吗?
有很多方法可以做到这一点,哪一种最合适主要取决于具体情况,所以从技术上讲这个问题对于 Stack Overflow 来说太宽泛了,我怀疑。
方法一
不过,让我向您展示一种非常简单的方法。这可能不是一个好方法,但它接近于您正在尝试做的事情。
- 创建一个新的 VCL 应用程序。
- 在主窗体上拖放一个
TButton
和一个TEdit
控件(Unit1
中的TForm1
)。 创建一个新单元,Unit2:
unit Unit2; interface procedure SetCaption; implementation uses Unit1; procedure SetCaption; begin Unit1.Form1.Edit1.Text := 'Hello, World!'; end; end.
在主窗体上,将此事件处理程序用于按钮的
OnClick
事件:procedure TForm1.Button1Click(Sender: TObject); begin Unit2.SetCaption; end;
在
implementation
部分的uses
子句中添加Unit2
之后。完整,unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses Unit2; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Unit2.SetCaption; end; end.
注意如果仅在实施部分引用这些单元如何相互使用。另请注意,我们在 Unit1
中使用全局变量 Form1
来引用自动创建的 TForm1
实例。在许多(大多数)情况下,您不想使用自动创建的表单,但那是另一回事(我可以在这里写一本 100 页的 Delphi 教科书!)。
方法二
此外,让我重申一个事实,即有许多其他方法可以实现此结果。例如,这可以说是一种更好的方法:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Unit2.SetCaption(Edit1);
end;
end.
unit Unit2;
interface
uses
StdCtrls;
procedure SetCaption(AEdit: TCustomEdit);
implementation
procedure SetCaption(AEdit: TCustomEdit);
begin
AEdit.Text := 'Hello, World!';
end;
end.
方法三
可以说更好:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := Unit2.GetText;
end;
end.
unit Unit2;
interface
function GetText: string;
implementation
function GetText: string;
begin
Result := 'Hello, World!';
end;
end.