关于窗体重用问题?(10分)

L

lcl_003

Unregistered / Unconfirmed
GUEST, unregistred user!
我在一个窗体里有个timer,代码如下:
procedure Tchartview.Timer1Timer(Sender: TObject);
var
i:integer;
begin
x1:=x1+datetimestep[dtOneMinute];
for i:=0 to 49 do
begin
series1.Add(valcom1[2,i]);
series2.Add(valload1[2,i]);
series3.Add(valdis1[2,i]);
end;
timer1.Enabled:=false;
end;
是让timer定时画三条曲线。有数据就画,画完就关闭timer
我创建这个窗体是动态创建的,没有判断窗体是否存在,因为允许用户打开多个这样的窗体。
form1:=Tform1.create(application);
form1.show;

但是问题出来了,我打开一个窗体没有问题,打开多个的话就只有最后打开的窗体才画线
其他窗体都不画。不清楚窗体重用到底该怎么做,有什么解决办法?
 
每次创建时窗体名不能一样。
这还不行的话,吧这封装为DLL该可以。
 
继承行么?? 我没试过。。给你个意见。。。
 
我创建窗体
form1:=Tform1.create(application);
form1.show;
关闭
action:=cafree;
没有判断窗体是否存在,这样每次创建的都应该是同一个窗体,这样不可以吗?
 
将创建改为
with Tform1.create(application) do
begin
show;
end;
不要用form1变量,否则前面创建的窗体句柄丢失
 
pengjinlongex, 不行啊:(
with Tchartview.Create(application) do
begin
chartview.Show;
with chartview do
begin
Height:=310;
Width:=450;
end;
end;
这样机器都死了:(
 
X1定义为什么?
定义为窗体的属性好了
 
做窗体数组啊,不是有动态数组吗?全是FORM1,会出问题的吧
 
哦,x1没用:)
能不能在说清楚一点啊,给点代码吧:)
 
晕:chartview这个变量删掉吧!
with Tchartview.Create(application) do
begin
Show;
Height:=310;
Width:=450;
end;

不过如果其他地方用到这个窗体可能就麻烦了.


>>>>>>>>>我创建这个窗体是动态创建的,没有判断窗体是否存在,因为允许用户打开多个这样的窗体。
这句不明白,多用户打开这个窗体,这就不能判断吗?这关多用户的事吗?
 
问题你需要在同一个应用程序创建这个窗体多个不同的实例吗?

如果需要的话,建议你用一个TList来保存这些窗体列表.
 
呵呵,aizb, 我发了帖子后就发现了,我把chartview删了也不行:(
>>>>>>>>>我创建这个窗体是动态创建的,没有判断窗体是否存在,因为允许用户打开多个这样的窗体。
>>>>>>>>>这句不明白,多用户打开这个窗体,这就不能判断吗?这关多用户的事吗?

具体是这样的:我用这个窗体里的chart画曲线,这个窗体里就一个chart,而要画的曲线是
多个通道的,就是打开一个窗体画一个通道的曲线,再打开一个窗体就画另外一个通道的曲线。
因为窗体的功能都是一样的,所以我才那么说:)不知道说明白了吗
 
想办法给每次创建的窗体赋上不同的变量.
 
如果你在其他地方不对这个窗体操作的话(我想应该不会,因为同一个窗体类有多个的话,你也无法知道操作哪一个),
你可以创建一个TList类的实例,把每一次创建的窗体加入到这个List中,在程序结束的时候再FreeTList中每一个节点。

var List:TList;

Procedure TMainForm.MainFormCreate(Sender:TObject);
begin
List:=TList.Create;
end;

Procedure TMainForm.Button1Click(Sender:TObject);
Var IDX:Integer;
begin
IDX:=List.Add(Tchartview.Create(application));
with Tchartview(List[IDX]) do
begin
Tag:=IDX;//记下索引是为了在Free的时候释放节点。
Height:=310;
Width:=450;
Show;
end;
end;

Procedure TMainForm.MainFormDestory(Sender:TObject);
Var i:Integer;
F:Tchartview;
begin
For i:=0 to List.Count-1 do
begin
F:=List;
if F<>nil then
begin
List:=nil;
F.Free;
end;
end;
List.Free;
end;

在Tchartview的OnDestory事件中加入
Procedure TMainForm.MainFormDestory(Sender:TObject);
begin
MainForm.List[Tag]:=nil;
end;
 
总之,你如果可以很熟练的利用TList这个东东,它可以帮你做很多其他方法很麻烦做到的事,比如快束排序,比如VB中的控件数组。
 
很可能是timer的ID相同,导致只有一个窗口能收到WM_TIMER消息
建议不用timer,用线程
 
那我每创建一个这样的窗体就创建了一个线程,不会出问题吗
 
把Timer删除,每动态生成一个Form,就动态为其添加一个Timer
 
顶部