控件动态产生的问题(100分)

  • 主题发起人 主题发起人 sundan
  • 开始时间 开始时间
S

sundan

Unregistered / Unconfirmed
GUEST, unregistred user!
第一步 定时动态create a control(eg.TImage),指定它的name
第二步 定时free it后, 同时再生成,系统说已存在name的控件
问题:1)如何free,才正确?
2)对于create的控件,在程序中如何方便地用name去引用?
THANKS.
 
1.if assigned(control) then control.free
2.var x:TControl;
x:=Tcontrol.create(..);
x.method ;
etc;
 
before u free the component, set the name to '';
after u free the component, set the variable to nil;

or

create a random name as ur component's name. eg. format('bmp%.5d',random(100000))
 
说的差不多了!
换一个思路,如果名字不重复就无问题!
control.name:='name'+inttostr(i);
inc(i);
i为全局变量!
 
我的问题阐述不够清晰,名字不重复不是问题,
因为create时不set name即可,可利用TAG或Hint去识别.

问题在于我定时产生50个控件(数组),再定时Free.
而且控件的名字来自数据库(即SET之后,用它来识别).

Another_eYes的方法也许可行,I WILL TRY.如果可行,
I will thank you with...
 
FindComponent indicates whether or not a given component, Aname, is owned by the component.

Function FindComponent(const Aname: string): Tcomponent;

Description

FindComponent returns the component in the Components array property with the name that matches the string in the Aname parameter. Use to find whether a given component is owned by another.
FindComponent is not case sensitive.
 
组件的查询,下面是我的一个例子可以找出任何有名字的组件,当然也可以引用,
修改一下即可
function TForm1.FindGlobalComp(const Name: String;
List: TComponentList): Boolean;
var
i,j,InitCount:Integer;
Form,Comp:TComponent;
begin

InitCount := List.Count;
for i :=0 to Screen.FormCount -1 do
begin
Form := Screen.Forms;
if CompareText(Name,Form.Name)=0 then
List.Add(Form);
for j :=0 to Form.ComponentCount -1 do
begin
Comp := Form.Components[j];
if CompareText(Name,Comp.Name)= 0 then
List.Add(Comp);
end;
end;

Result:=(List.Count-InitCount)>0;
end;

procedure TForm1.FindClick(Sender: TObject);
var
i: Integer;
Comp : TComponent;
List : TComponentList;
begin
ListBox1.Items.Clear;
List := TComponentList.Create;
try
if not FindGlobalComp(Edit1.Text,List) then
ListBox1.Items.Add('No Components Fount')
else
begin
showmessage(Format('Count is %d',[List.Count]));
for i :=0 to List.Count -1 do
begin
Comp := List.Items as TComponent;
ListBox1.Items.Add(Format(
'%s(%s): %s(%s)',
[Comp.Name,Comp.ClassName,
Comp.Owner.Name, Comp.Owner.ClassName]));
end;
end;
finally
List.Free;
end;
end;
2.free 的方法,和eYes有所不同
eg:
Form1.RemoveComponent(Button1);
Button1 := nil
可以一次删除
 
方法差不多,用NAME去查找,和判断!
 
谢谢各位的帮助!
但仍不能使我满意,我希望知道动态生成的控件,一旦设定一个名字,
这个名字就不能再复用.
Another_eyes的方法我TRY过,也不行.
 
???????????????????????
procedure TForm1.Button1Click(Sender: TObject);
var
x: TEdit;
i: integer;
begin
for i:=1 to 100 do
begin
x:=TEdit.create(form1);
x.parent:=form1;
x.Name:='aaaaaa';
x.free;
end;
end;

一切正常!
:(
 
also tried:
procedure TForm1.Button1Click(Sender: TObject);
var
x,y: TImage;
i: integer;
begin
x:=TImage.create(form1);
x.parent:=form1;
x.Name:='aaaaaa';
x.free;
y:=TImage.create(form1);
y.parent:=form1;
y.Name:='aaaaaa';
y.free;
end;

ALL OK.
??????????????????
 
我也试了,用timer没有问题!
 
具体的程序如下(main idea):
procedure DisplayImage;
var
IImage:Timage;
begin
try
IImage:=Timage.create(Self);
IImage.parent:=panel1;
IImage.name:='aaaa';
finally
IImage.free;
end;
end;

procedure Timer;
begin
...
Find control.name='aaaa';
control.free;
Display;
...
end;

请各位朋友帮助发现问题!
我害怕程序中存在累计资源问题.
 
image.free
image:=nil;试一试!
 
try
IImage:=Timage.create(Self);
....
这里的self比较可疑。你的DisplayImage是类的方法吗?(看定义不是)
如果不是类的方法,self该指向哪个类呢?(也许就成nil了)

你的 Find Control.name='aaaa';是一句注释吧?
如果是标准delphi代码,恕在下孤陋寡闻,没见过find 命令。
假设你是调用form.FindComponent方法来查找, 这肯定找不到的(因为建立时它的
owner不一定是你的form),这样就不会存在释放该控件了, 再建当然名称是存在的
了。

瞎猜了一通。总之,不能第二次用name就表示先前的控件并未free掉。你该从控件的
释放方面找原因。
 
对不起各位!我的语言表达能力太差,耽误大家时间
由于具体的程序较长,剪切麻烦,所以...

我设计的程序目的是刷新图象上一系列Image
定时调,定时清,再调进来...
FIND的那句是注释,但是可行的,从功能上程序运行良好,
但我总担心未释放掉,尽管FREE之后,Image刷新正常.

Image:=nil;没有起作用.

如果大家从原理上没有新的解释,讨论可以到此为止.为了
感谢大家,我会送分给各位.THANKS.
 
如果就事论事的话, 为什么要定时清除再重新生成?
用先前生成的image直接load第二个图象不行吗? 如果为了查找方便, 直接name=newname不就行了吗?
至少可以少掉内存管理上的不少系统开销。

如果说free然后重新create会出现你所说的错误的话, 我个人认为你free控件时存在
bug, 也就是没有free掉, 不然不会出现这种错误。
 
我觉得主要是要把COMPONENT := NIL
既然FREE又要CREATE太复杂了,而且名字一样,不如放着,反正95内存不锅会往
硬盘放:))
 
多人接受答案了。
 
后退
顶部