我想让用户创建同一表单的多个实例(让我们称之为Form1,这是一个MDI子表单).所以我有两个这样的程序,我创建表单.
procedure MyProcedure1; // procedure 2 is similar. it also has a var called MyFrm
var MyFrm: TFrm1;
begin
...
MyFrm:= TFrm1.create(MainForm);
MyFrm.BringToFront;
MyFrm.LoadFromFile(someFile);
end;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,MyFrm是本地变量.这对我来说没问题,因为我创建它之后不需要以编程方式访问表单.没有其他名为Frm1的全局变量.在MyFrm的OnClose事件中,我有Action:= caFree;
什么可能导致上述错误?用户发送了该错误.它只发生一次,我无法重现它.
编辑:
该错误出现在"MyFrm:= TFrm1.create"行中.
有些人建议我需要以编程方式为动态创建的表单指定唯一的名称.我也想知道自己在创建表单时所采用的名称,因此我在调用MyProcedure1过程时进入了代码.
Delphi自动提供唯一的名称,如
MyFrm.name = MyFrm,然后是
MyFrm.name = MyFrm_1,
MyFrm.name = MyFrm_2,
MyFrm.name = MyFrm_3,依此类推.
LoadFromFile中未更改MyFrm.Name.我在程序MyProcedure1的末尾检查了(断点)'MyFrm.Name'的值; 在LoadFromFile之后.这个名字很独特.
正如一些人建议的那样,我重写了SetName过程并检查了TMyFrm的名称.确实,每个表格都有一个独特的名称
procedure TMyFrm.SetName(const Value:TComponentName);
开始
ShowMessage(Value);
遗传;
结束;
我在这个应用程序中有许多表单,但只有MainForm是自动创建的.
我不使用线程.无论如何,这是不相关的,因为表单是由用户创建的(因此多线程是无关紧要的,除非用户可以同时创建2个表单).
将MainForm作为TFrm1.Create中的所有者将在MainForm的组件列表中包含新创建的表单.组件确保此列表不包含具有相同非空名称的任何两个组件(否则FindComponent将不起作用).当组件更改其名称时,此机制也适用.
只要您没有在TFrm1.Create中指定名称,它很可能是由LoadFromFile方法设置的,这意味着除非您更改文件的内容,否则对名称的影响不大.
一个有效的解决方法是使用nil作为所有者创建表单,从文件加载表单,将名称更改为唯一值或更改为空字符串,最后调用MainForm.InsertComponent.
procedure MyProcedure1;
var MyFrm: TFrm1;
begin
...
MyFrm:= TFrm1.create(nil);
MyFrm.BringToFront;
MyFrm.LoadFromFile(someFile);
MyFrm.Name := ''; // or some unique name
MainForm.InsertComponent(MyFrm);
end;
Run Code Online (Sandbox Code Playgroud)
导致该消息是因为每个表单必须唯一命名.
在两次创建表单时,需要确保每个实例都具有唯一的名称,或者将Name设置为空字符串.后者也是使用数据模块的多个实例时的技巧,因此数据感知控件的自动链接不会总是使用第一个实例.
加
MyFrm.Name := MyFrm.Name + <something unique>;
Run Code Online (Sandbox Code Playgroud)
MyFrm.Name := '';
Run Code Online (Sandbox Code Playgroud)
在Create调用之后,你应该没问题
归档时间: |
|
查看次数: |
13035 次 |
最近记录: |