组件开发的Create事件(200分)

  • 主题发起人 主题发起人 xinglong
  • 开始时间 开始时间
X

xinglong

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的源码只是一个举例,大家看一看下面的源码对吗?
我希望明白组件开发里的Create事情能不能马上调用其事件
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
unit MyComp;

interface

uses
Windows, SysUtils, Classes, Dialogs;
Type
TFsXaudioSitus = (fsWindows, fsSystem, fsProgram);//这里定义我的枚举类型
TMyComp = Class(TComponent)
private
FsDelXaudio:Boolean;
FsXaudioSitus:TFsXaudioSitus;
procedure SetsDelXaudio(Value: Boolean);
procedure SetsXaudioSitus(Value: TFsXaudioSitus);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property sDelXaudio:Boolean read FsDelXaudio write SetsDelXaudio;
property sXaudioSitus:TFsXaudioSitus read FsXaudioSitus write SetsXaudioSitus;
end;


procedure Register;

implementation

procedure Register;
begin
RegisterComponents('MyVCL', [TMyComp]);
end;

constructor TMyComp.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if not(csDesigning in ComponentState) then//防止在设计期调用下面的过程
case FsXaudioSitus of//我在设计期已经把sXaudioSitus设为了fsSystem或fsProgram
fsWindows: //问题是这时的FsXaudioSitus值还是默认的第一个fsWindows
begin //是不是TMyComp还没有创建就不能马上调用?
//我的事件
end;
fsSystem:
begin
//我的事件
end;
fsProgram:
begin
//我的事件
end;
end;
end;

destructor TMyComp.Destroy;
begin
inherited Destroy;
end;

procedure TMyComp.SetsDelXaudio(Value: Boolean);
begin
if FsDelXaudio <> Value then FsDelXaudio := Value;
end;

procedure TMyComp.SetsXaudioSitus(Value: TFsXaudioSitus);
begin
if FsXaudioSitus <> Value then FsXaudioSitus := Value;
end;
end.
 
建议重载CreateWnd,在CreateWnd中放置你上面的代码
protected
procedure CreateWnd;override;
 
To VeryCoolBoy
>TMyComp = Class(TComponent)
我的是非可视元件起点的“TComponent”,“CreateWnd”是Tcustom...相关的,
不能用。
 
对不起,没注意看,不过我感觉这样好像不行吧。可以通过另外一种方法解决

Type
TFsXaudioSitus = (fsWindows, fsSystem, fsProgram);
TMyComp = Class(TComponent)
private
FsDelXaudio:Boolean;
FOwnerCreate:TNotifyEvent; //用于记录所在窗体的onCreate事件
FsXaudioSitus:TFsXaudioSitus;
procedure SetsDelXaudio(Value: Boolean);
procedure SetsXaudioSitus(Value: TFsXaudioSitus);
procedure OwnerCreateEvent(sender:TObject);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property sDelXaudio:Boolean read FsDelXaudio write SetsDelXaudio;
property sXaudioSitus:TFsXaudioSitus read FsXaudioSitus write SetsXaudioSitus;
end;

implementation

{ TMyComp }

constructor TMyComp.Create(AOwner: TComponent);
begin
inherited;
FOwnerCreate:=TForm(AOwner).OnCreate; //截拦组件所在窗体的ONCreate事件
TForm(AOwner).OnCreate:=OwnerCreateEvent;
end;

destructor TMyComp.Destroy;
begin
TForm(AOwner).OnCreate:=FOwnerCreate; //将事件句柄还原
inherited;
end;

procedure TMyComp.OwnerCreateEvent(sender: TObject);
begin
//你的事件代码
if Assigned(FOwnerCreate) then FOwnerCreate(Sender); //转回执行所在窗体的ONCreate事件
end;
 
To VeryCoolBoy
你的方法是行得通的,但是
destructor TMyComp.Destroy;
begin
TForm(AOwner).OnCreate:=FOwnerCreate; //这里编译通不过。
如果不要这一段的话编译能通过。我的事件也能正常运行
这一段要不要有什么影响吗?能解释一下其作用吗?
inherited;
end;
 
应该是TForm(Owner).OnCreate:=FOwnerCreate; 我上面写错了,
因为在组件创建时截拦了窗体的ONCREATE事件,并换成了自己的方法:
FOwnerCreate:=TForm(AOwner).OnCreate;
TForm(AOwner).OnCreate:=OwnerCreateEvent;
所以在它析构时,必须将该原始的ONCREATE归还给窗体

BTW:
由于ONCREATE事件的特殊性(ONCREATE只在窗体创建时调用一次),所以这里要不要
这句话都不会出错,但应该保持一种良好的编程习惯。
 
To VeryCoolBoy
destructor TMyComp.Destroy;
begin
TForm(Owner).OnCreate:=FOwnerCreate;
要这一段的话,程序在关闭时会出现Delphi类型的错误。如:
"Exception EAccessViolation in module PROJECT1.exe at 0043D67......Read of address FFFFFFFFF."
关闭项目也会出现程序包的错误。
我想会不会是,组件所在的Form的OnCreate有自己的代码,这样赋值的话就有问题了?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
而且
constructor TMyComp.Create(AOwner: TComponent);
begin
if not(csDesigning in ComponentState) then//我发现这里要加入这一段,
不然打开项目时组件所在的Form的OnCreate事情就会去掉,但是代码还在。
begin
FOwnerCreate:=TForm(AOwner).OnCreate;
TForm(AOwner).OnCreate:=OwnerCreateEvent;
end;
end;
 
To VeryCoolBoy,
用这也没用if not(csDesigning in ComponentState) then
destructor TMyComp.Destroy;里用
TForm(AOwner).OnCreate:=FOwnerCreate;
就出现我说的
"Exception EAccessViolation in module PROJECT1.exe at 0043D67......Read of address FFFFFFFFF."
只是没出现包的错误。是不是赋值不对呢?
反正问题也解决得差不多了,我看一看有没有更好的办法或其他人的方法,我会给你加分的。

 
兄弟,变通一下嘛,我那只是给你的关键代码,你同样也得测试它是不是在设计模式
destructor TMyComp.Destroy;
begin
if not(csDesigning in ComponentState) then
TForm(Owner).OnCreate:=FOwnerCreate;
inerited;
end;
 
我测试了一下
由于ONCreate特殊性,组件Destroy处的事件赋值代码应该不要,因为Form的Destroy已经发生了
 
你能不能上Oicq,我在线上啊,QQ:9319795
 
什么就我们两个讨论这个问题?本来想集思广益的。但能解决问题还是要感谢你!
 

Similar threads

后退
顶部