怎样得到构件所在窗体的OnCreate事件.(100分)

  • 主题发起人 主题发起人 delphisky
  • 开始时间 开始时间
D

delphisky

Unregistered / Unconfirmed
GUEST, unregistred user!
我的目的是:当我的构件所在窗体建立时我要执行一段构件内的代码.
 
我想正确的做法就是在Form的Create过程中
执行你的构件的这段代码,
能解释一下不能这样做的原因吗?
 
在你的构件中替换掉原form的Oncreate.
type
TMyComponent = class(TComponent)
private
FFormOnCreate: TNotifyEvent;
public
Constructor Create(AOwner: TComponent);override;
Destructor Destroy;override;
procedure NewFormOnCreate(Sender: TObject);
end;

implimentation

constructor TMyComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFormOnCreate:=TForm(AOwner).OnCreate;
TForm(AOwner).OnCreate:=NewFormOnCreate;
end;

destructor TMyComponent.Destroy;
begin
TForm(Owner).OnCreate:=FFormOnCreate;
inherited;
end;

procedure TMyComponent.NewFormOnCreate(Sender: TObject);
begin
// your codes here
FFormOnCreate(Sender);
// or your codes here
end;

end.
 
Hmmm...,不好意思,上面那个帖子正好写反了。

我想应该在你的构件的Create过程中执行这段代码
 
dwwang, 也许delphisky的构件需要用到form上其他控件的某些属性呢?
只有在form.oncreate时才能保证form中所有构件都已经建立了呀
 
override 窗口的CreateWnd函数

 
override窗口的CreateWnd?
CreateWnd调用时窗体中的控件可一个都还没建立呢(窗体本身也没建立)!
怎么能执行自己控件的"一段构件内的代码"( 如果这段代码用到该构件的任何内存变
量)?
 
这样吧,在Oncreate里设置一个Bool变量为False

在Onactivate判断
if false then
begin
set bool to true //防止多次调用,仅在create后调用一次
//your code here

end;



 
构件所在的窗体一般来说是它的Owner, 静态建立的控件都是如此Form类除外;
一个窗体的OnClick事件是否存在是通过Assigned函数检测的;
调用Form的OnClick事件可以用Self.FormCreate(self);

例如:
1. 新建一个APP
2. 放上两个Button, 令Button1.caption:='Assign'
3. 写一个FormCreate过程
4. 创建Button1, Button2的OnClick事件(其中的self可以用)
TForm(Button1.Owner)代替; 代码如下:

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
showmessage('Hi DelphiSky!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(Self.OnCreate) then
begin
Self.OnCreate:=nil;
Button1.Caption:='Assign'
end
else
begin
Self.OnCreate:=FormCreate;
Button1.Caption:='UnAssign';
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if Assigned(Self.OnCreate) then
Self.OnCreate(self)
else
showmessage('Please use Button1 to assign'+
' the OnClick to the form, then try this button again');
end;
 
私有数据,类外无法访问.公有数据,随时可以访问.

要实现封装,又想在类外访问,只有保护类型.

将你的构件的代码设为保护类型.
在需要的单元中继承一下.如:
TmyClass=class(...)
...
protected
procedure ss;
...
end;

在你需要该代码的单元中:
Type
TMySubClass=class(TMyClass);
TForm1=class(TForm);
v : TmyClass;
...
end;
var
form1 : TForm1;

procedure Tform1.FormCreate(Sender: TObject);
begin
...

TMySubClass(v).ss;
...
end;

这些是否对你有所帮助呢?
 
Hehe,越弄越复杂了 :)
我猜测 delphisky 的意思,是不是可以重载 procedure loaded.
该过程是控件初被创建后立即执行的.
TMyComponent = class(TComponent)
...
proctected
procedure loaded; override;
...
end;
 
虽说越来越复杂,但这个问题还是很有意思 :)
现在就等Delphisky来解释一下他的具体意思
和目的了。
 
?? 题目: 怎样得到构件所在窗体的OnCreate事件
?? 目的: 当我的构件所在窗体建立时我要执行一段构件内的代码

很矛盾的主体, 创建窗体时要执行一段构件的代码, 而不知道窗体的OnCreate事件
 
动态建立(或者做成控件), 当然不一定知道form.OnCreate到底是什么东西.
form可能是别人写的, 他只是把你的控件放进去而已 :)
 
我就遇到过这种情况, 比如在你的控件中需要保存form里所有其它控件的位置.
而只有当所有其它控件都已经建立之后你保存的内容才有意义, 而你不能肯定你的
控件是在form中最后一个建立的(天晓得别人设计时把你的控件做为第几个控件放到
form上的?). 这时截取form.OnCreate是最好的办法(form调用OnCreate时所有控件
都已经建立了). 在form.OnCreate中加上自己控件里保存其它控件位置的代码就行
了. 方法就是我上回说的, 先保存原先的form.OnCreate, 然后把form.OnCreate
替换成自己控件中的一个方法即可.
 
动态建立的Form还需要OnCreate事件吗? 需要干什么直接变程就是了; 还是等提问者
详细解释一下吧
 
我也曾经被这个问题困扰。我的解决方案是,重载控件的WMCreate:
procedure WMCreate(var Msg : TWMCreate); message WM_Create;
这个过程在控件的窗口(这要求控件要带一个窗口)被创建的时候调用。
 
Some body finish it, please!
 
好象有些问题。必须先弄清楚主次关系。
首先,控件得放在窗体上,那么必须先有窗体,才能有控件。也就是说窗体先Create,然后控件才能Create。
如果控件是动态创建的有何解?
弄不懂为何要实现这一功能?这不符合控件设计的一般要求,与其这样,还不如写个UNIT算了。
 
后退
顶部