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

  • 主题发起人 主题发起人 BlueWin
  • 开始时间 开始时间
B

BlueWin

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个极其简单的控件,只是在这个控件中动态创建了另一个控件:

源代码如下:

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

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:=TAction.Create(aowner);
^^^^^^^
{1}{这个参数一定要用Aowner,如果用Self就没问题了,但那不是我要的结果}
Myaction.Name:='aHookPlay';
{2}{Name一定要赋值!}
Myaction.Caption:='结束播音';
// end;
end;

destructor gltest.Destroy;
begin
if assigned(myaction) then
begin
// myaction.RemoveFreeNotification(FParent);
fparent.RemoveComponent(myaction);//
Myaction.Free;//
end;
inherited;
end;

end.
//——————————————————————————————————————
其中有三个要求是必须的:
1.控件只能继承自TComponent。(不要建议我用Actionlist,compantlist等)
2.创建的控件的Create参数必须如下:
Myaction:=TAction.Create(aowner);
^^^^^^^
{这个参数一定要用Aowner,如果用Self就没问题了,但那不是我要的结果}
3.创建的控件必须有Name,如下:
Myaction.Name:='aHookPlay';
{Name一定要赋值!}

出现的问题:
1.将控件加到Form中,运行,会出现“控件名aHookPlay已经存到”的错误。
2.如果把Create中注释行加上,则运行正常,但退出工程(Close All)时出错。(该错误
会导致Delphi无法正常关闭!调试前请保存有用的项目)。

请各位高手帮我指点一下错误,谢谢!!
 
在destory里
也应该加上
if csDesigning in self.ComponentState then
being
//
end;
 
Applications do not usually create action objects explicitly. Actions are
created automatically when you add them to an action manager or action list
component at design time. When instantiating TAction at runtime, assign a
TActionList or TActionManager component to the new action's ActionList
property after calling Create.
你还得有个TActionList或TActionManange组件...
 
To:yanghaijun
我的英语不大好,但是好像你那段文字中也没有说必须要有ActionList的啊

以下是我测试用的一个控件,虽然这个Action在Form上没有图标,但是他的功能也都在,
而且使用也正常。因此问题不在于有没有ActionList,而是在于
[blue]通过Taction.create(aowner);创建的控件如何管理(如何避免重复创建和如何释放的)问题[/blue]


unit MyAction;

interface

uses
Windows, Messages, SysUtils, Classes, ActnList;

type
tMyAction = class(TAction)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

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

end.
 
我不是很懂你的意思,用这种方法来做,是不是想要代理什么功能呢?代理模式吗?
那样比较简单。那是想要有自己的Action吗?这是一个操作,可以说成一个Command
对象,想要做什么呢?命令UnDO ReDo?或者是序列化?如果你说你的目标,说不定
我们可以提供其它的解法[:)]好运!
 
说说我的想法吧:
我做的系统是要控制一些按钮的Enabled:
如“播音”,“结束播音”,“录音”,“结束录音”等(实际上有15个功能);
而每个功能都可能分布在多个Form上(如就有5个Form上有播音按钮)
我要用某种规则去控制这些按钮的Enabled(例:如果在录音,
那所有“播音”的按钮的Enabled都要等于False);
为此我想用Action是最好的办法了。但要做成一个控件,
由于某种限制,这个控件只能继承Tcompant,所以我就在这个控件的create中
动态创建了那些Action,我试过只有通过
Myaction:=TAction.Create(aowner);
Myaction.Name:='aHookPlay';
创建才行。
这个参数一定要用Aowner,如果用别的就没无法被其他控件(如button控件)引用了。
并打算在另一个过程中控制这些Action的Enabled。
可是没想到通过 Myaction:=TAction.Create(aowner);语句创建的控件会出现那些问题。
所以请各位帮忙解决一下。(如果没有Myaction.Name:='aHookPlay';这句也正常,真奇怪)。

 
我找到了,你看看下面的这段话:
ActionList indicates which action list or action manager contains the
action. Only contained actions (instances of TContainedAction or
its descendants) can appear in an action list or action manager.
An action list provides a visual interface for working with actions,
which are then available to be associated with client controls in the
application. An action manager uses the actions as an abstract
representation of user interface elements, which it generates dynamically
at runtime.

When creating an action dynamically at runtime, set the ActionList
property to add the action to an action list or action manager.

当你在运行时动态创建一个action时,要设置其ActionList属性来增加本action
到一个action list 或者action manager;[:)]

祝你好运!
 
不行啊,
我用
Myaction:TButton;

Myaction:=TButton.Create(aowner);(或Tcontrol等其他控件)
Myaction.Name:='aHookPlay';
也是不行的。
 
如果是这样,你可以不用那么麻烦,有一个消息,你重载一下就可以了(我也忘了是哪个)
 
真的吗?大家帮我一起找找看。
 
为什么一定要为MyAction的Name指定内容呢?你已经能够实例化这个Action了,
也就是说你一定能够得到这个实例的引用,用Name就没有意义了啊。
比如:
type
gltest = class(TComponent)
private
MyAction:TAction;
FParent:TComponent;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property Action : TAction read MyAction;
//在这里增加对你的Action的实例引用,下次用的时候就好了,如:
//Button.Action := glTest.Action;
//要控制这个Action,可以:
//glTest.Action.Enable := true;//false
//glTest.Action.OnEx..... := ..........//自己写,呵呵[:)]
published
end;
 
我的目标就是不要
Button.Action := glTest.Action;
这句话,我希望在button的Action属性中能够下拉选择到我创建的Action。
 
我想可能的原因是在form运行时,会自动创建属于它的所有控件,
所以在运行时form和我的控件都创建一个Action,就提示错误了。
我不懂FreeNotification和RemoveFreeNotification的用法,我想他们对
这个问题有所帮助。
 
// public
// property Action : TAction read MyAction; //Move to..
=>> published
=>> property Action : TAction read MyAction;
Did you tried?
 
高手在哪里啊?
有没有高手关注我得问题啊?
请关注我的有钱人说句话吧。
 
http://www.onlinedown.net/electricitydesigner.htm
 
不要乱插广告!!
 
不是广告

你看看这个东西是不是和你要求的符合?
 
对不起,我误会了.
不过要做的控件不是那样的,首先我要用一个udpp控件,里面有特殊的设置,无法用其他现成的控件了.
谢谢你回复.
 
后退
顶部