关于动态生成控件的问题(很难!很难!!!) (100分)

  • 主题发起人 主题发起人 BlueWin
  • 开始时间 开始时间
不会,看看
 
版主 :我为什么看不见问题的具体内容啊!!!
 
Myaction:=TAction.Create(aowner);
^^^^^^^
{1}{这个参数一定要用Aowner,如果用Self就没问题了,但那不是我要的结果}
会不会是Aowner是 Tcomponent类型的,不能作为属主吧,因为它不可视
 
to plane822
不是的,因为self也是tcomponent类型的。呵呵
 
Myaction:=TAction.Create(aowner);
Myaction.Name:='aHookPlay';
这样的代码如果实现时在同一个Form上你是绝对不可以放两个这样的组件的。
因为Myaction的拥有者是当前的Form,而同一个组件不能用用两个同名的子组件。所以行不通。
方案一:
Myaction:=TAction.Create(Self);
Myaction.Name:='aHookPlay';
方案二:用计数器来解决,MyAction大家共用。
unit glMyAction;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, ActnList;

type
gltest = class(TComponent)
private
MyAction: TAction;
FParent: TComponent;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
end;

procedure Register;

implementation

uses glMyAction;

var
CompCount : Integer; //定义一个计数器

procedure Register;
begin
RegisterComponents('SelfControl', [gltest]);
end;

{ gltest }

constructor gltest.Create(AOwner: TComponent);
begin
inherited;
fparent := AOwner;
// if csDesigning in self.ComponentState then
// begin
Myaction :=fparent.FindComponent('aHookPlay');//如果Myaction存在了就直接指过去
if Myaction= nil then
begin
Myaction := TAction.Create(aowner);
{1}{这个参数一定要用Aowner,如果用Self就没问题了,但那不是我要的结果}
Myaction.Name := 'aHookPlay';
{2}{Name一定要赋值!}
end;
Inc(CompCount);//计数器加一
Myaction.Caption := '结束播音';
// end;
end;

destructor gltest.Destroy;
begin
Dec(CompCount);//计数器减一
if CompCount = 0 then //等与0也就是没有人用了,才释放掉
MyAction.Free;
inherited Destroy;
end;

initialization
CompCount := 0;

end.



 
to wr960204:
谢谢你的回答,
其实我的form上并没有两个相同的组件。
我只是新建一个form,再放上我的控件就会出问题。
你的代码我试过了,也是会出现这个问题。

我后来猜测:
可能是在设计期使用MyAction.Create(owner)后,运行时Owner会自动创建MyAction;
而MyTest也创建了MyAction,所以就产生了冲突,
但使用fparent.FindComponent('aHookPlay');为什么找不到呢?
可能是Mytest先创建了MyAction,而错误是在Owner创建Myaction时发生的。
(这也是为什么你写的那个代码也会出现类似错误的原因吧)

我用
if (csDesigning in self.ComponentState)and(not (csLoading in fparent.ComponentState)) then
替代if csDesigning in self.ComponentState then
后程序就正常了,这也证实了我的猜测。

修改后
private
MyAction: TAction;
的myaction在运行期的值就成了Nil了。
(在Create事件中用fparent.FindComponent('aHookPlay'))可能得不到对应的控件。

麻烦你再指点一下了。
 
在DESTROY中不要FREE掉你的MYACTION,因为你的MYACTION是属于FORM的而不属于你的控件,FORM会自动FREE到MYACTION
 
如果不Free掉,下一次Create的时候还是有问题啊。
 
在CREATE前,判别一下是否存在呀
 
我上面已经讲的很清楚了,在Create中无法判断它是否存在,因为控件的Create事件
早于Form的Create事件。
 
我是说CREATE MYACTION前判别一下 MYACTION的存在与否
 
前面已经有人提示过了,用
property Action : TAction read MyAction;

试试.

TAction不是一个独立的类,它必须要与TActionManager打交道,你的方法可能不行.
 
各位能不能看完所有的答复再判断啊
To bluebridge:
其实property Action : TAction read MyAction;
跟Public Action : TAction;并没有区别。
至于你说的
> TAction不是一个独立的类,它必须要与TActionManager打交道,你的方法可能不行.
我上面也说过了,改成其他控件也是一样的。

 
使用 DesignForm 关键词讨论可能才是出路!
 
我觉得可以研究一下FreeNotification和RemoveFreeNotification有用。
 
放太久了。结吧。我要转行学Java了,请大家支持。
 
你都给NAME属性强制赋固定值了,当然再次创建就提示已存在,用
NAME := 名字 + 计数器
的方法试试
 
后退
顶部