是否可以告诉Unit1 Form1创建另一个自我,
Application.CreateForm(TForm1, Form1);
并通过第一个form1来分辨原始form1组件和第二个新form1组件之间的区别。
答案 0 :(得分:1)
简单的方法是定义另一个名为Form1Copy: TForm1
的全局变量,并在项目源中为Application.CreateForm
添加另一个Form1Copy
。
更好的方法是避免使用Application.CreateForm
,如果TForm1
是您拥有的唯一表单,或者它不是主表单并使用以下代码:
var
Form1, Form1Copy: TForm1;
...
procedure InitializeMyForms;
begin
Form1 := TForm1.Create(nil);
Form1Copy := TForm1.Create(nil);
... //Do extra stuff
Form1.Show;
Form1Copy.Show;
end;
答案 1 :(得分:1)
看,如果您允许表单在关闭时释放内存,则根本不需要变量....
第1步
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
第2步
TForm1.Create(Application);
TForm1.Create(Application);
TForm1.Create(Application);
第3步 接下来,要从程序的其他区域引用您的表单,有多种方法。您可以使用屏幕对象或application.components,如果它是MdiChildren,您可以使用MdiParents.MdiChildren属性......就像这样。
for i := 0 to Screen.FormCount - 1 do
begin
if Screen.Forms[i] is TForm1 then
TForm1(Screen.Forms[i]).MyPublicMethod;
end;
答案 2 :(得分:0)
面向对象的方法是创建Form1Factory并让Form1Factory创建和管理Form1实例。例如,如果您需要向所有Form1实例发送事件,或者处理表单关闭时发生的事件,如果必须通知相同类型的其他表单,那么这将是交给工厂对象的工作。 / p>
你可以创建一个TObjectList<TForm1>
,这样你就可以得到那些对象的列表,这可以让你不必像其他答案那样迭代Screen.Forms。 David H的评论确实是你答案的关键;您不需要该全局变量。从Form1.pas中取出,然后继续迭代和测试,直到找到解决方案。
不是让表单创建自己的另一个副本,为什么不让它通过委托(回调函数)告诉表单工厂这样做。之后您可以决定是否希望工厂对象从池中创建和重用表单对象,而不是始终构建新的表单对象。
答案 3 :(得分:0)
如果不采用所有面向对象并且不使用意大利面条的全局变量,这样做的简单方法是让控制另一个表单的表单保存对它需要控制的表单的引用。无论是相同形式还是其他形式类都无关紧要。虽然在后一种情况下,您需要将表单的单元添加到接口部分的uses子句中。
TForm1 = class(TForm)
private
FFormToControl: TForm2; // Class member so initialized to nil by the compiler.
end;
然后在代码中的某处,您需要实例化您想要控制的表单。
FFormToControl := TForm2.Create(<Owner>);
FFormToControl.Show;
您可以使用Application
,Self
或nil。这取决于您希望拥有者的身份,这取决于您希望控制FFormToControl
的生命周期的人。如果在应用程序关闭之前它会一直存在Application
就行了。如果在释放Form1时应释放它,请使用Self
或nil
。 Self将确保VCL的所有权系统能够解决问题。使用nil意味着你必须自己释放它。
之后您可以简单地调用方法并设置TForm2类的属性:
FFormToControl.DoSomethingCool;
FFormToControl.EditBackgroundColors := clRed;
如果第二种形式可以存在并在TForm1实例的生命周期内关闭,那么您需要在使用其任何方法和属性之前检查该表单是否已实例化:
if Assigned(FFormToControl) then begin
FFormToControl.DoSomethingCool;
FFormToControl.EditBackgroundColors := clRed;
end;
当FFormToControl在TForm1的构造函数(或OnCreate)之外的某个地方实例化并在TForm1的析构函数(或OnDestroy)之前释放时,你也应该这样做,因为你可以永远不确定FFormToControl是否被实例化。在这种情况下,你最好使用nil作为FFormToControl的所有者,你应该确保在释放FFormToControl时通知TForm1。例如,通过响应OnDestroy事件并在其处理程序中将FFormToControl设置为nil。
FFormToControl := TForm2.Create(<Owner>);
FFormToControl.OnDestroy := HandleForm2Destroy;
FFormToControl.Show;
procedure TForm1.HandleForm2Destroy(Sender: TObject);
begin
if Sender = FFormToControl then begin
FFormToControl := nil;
end;
end;
注意: 当您从自己的方法创建和使用表单时,您必须小心避免无限循环创建下一个实例。