2

我想知道为什么,但我不能简单地调试我的简单程序。加载的方法被忽略,它永远不会被执行。不知道为什么。看:

    TGridObj = class (TComponent)
private
  FPen1:TPen;
  FBrush1:TBrush;
  FChange:TNotifyEvent;

protected
  procedure Loaded; override;


public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property OnChange:TNotifyEvent read FChange write FChange;

  property Pen1:TPen read FPen1 write FPen1;
  property Brush1:TBrush read FBrush1 write FBrush1;
end;

. . .

constructor TGridObj.Create(AOwner: TComponent);
  begin
  inherited Create(AOwner);
  FPen1:=TPen.Create;
  FPen1.OnChange:=FChange;


  FBrush1:=TBrush.Create;
  FBrush1.OnChange:=FChange;
  end;


destructor TGridObj.destroy;
  begin
  FPen1.Free;
  FBrush1.Free;
  inherited;
  end;

procedure TGridObj.Loaded();
begin
  inherited Loaded;
  ShowMessage('');   // this is never executed;
  FPen1.OnChange:=FChange;
  FBrush1.OnChange:=FChange;
end;

. .

procedure TForm1.FormCreate(Sender: TObject);
begin
Grid:=TGridObj.Create(nil);
Grid.OnChange:=ev1.OnChange;
Form1.InsertComponent(Grid);
end;

谢谢

4

2 回答 2

8

Loaded仅当组件的属性从表单文件流式传输时才调用。由于您是在运行时创建它,因此Loaded不会被调用。这是设计使然。

无论如何,您的代码都需要一些工作以允许OnChange在运行时修改事件并将该更改过滤到笔和画笔。我会这样做:

TGridObj = class (TComponent)
private
  FPen1: TPen;
  FBrush1: TBrush;
  FChange: TNotifyEvent;
  procedure DoChange(Sender: TObject);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property OnChange: TNotifyEvent read FChange write FChange;
  property Pen1: TPen read FPen1;
  property Brush1: TBrush read FBrush1;
end;

constructor TGridObj.Create(AOwner: TComponent);
begin
  inherited;
  FPen1 := TPen.Create;
  FPen1.OnChange := DoChange;
  FBrush1 := TBrush.Create;
  FBrush1.OnChange := DoChange;
end;

destructor TGridObj.Destroy;
begin
  FBrush1.Free;
  FPen1.Free;
  inherited;
end;

procedure TGridObj.DoChange(Sender: TObject);
begin
  if Assigned(FChange) then
    FChange(Sender);
end;

现在没有必要Loaded或类似的东西。因为您要等到OnChangepen 和 Brush 的事件真正触发后才能访问FChange.

顺便说一句,在您的代码中添加属性设置器Pen1Brush1修改基础字段是错误的。这会导致泄漏和各种混乱。另外,请注意,将笔和画笔公开为公共属性允许客户端TGridObj更改OnChange事件。而那颠覆TGridObj.OnChange

于 2012-09-03T16:37:26.893 回答
1

只有从表单资源(dfm 文件)加载组件时才会执行 OnLoaded。

如果组件在运行时仅在代码中创建,则不会执行。

更新:

我建议设计组件,以便它们也可以在运行时创建和配置——这意味着我避免覆盖 OnLoaded。优点是不需要包安装/组件注册。

于 2012-09-03T16:36:58.703 回答