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そのようなものは必要ありません。OnChangeにアクセスする前に、ペンとブラシのイベントが実際に発生するまで待機するためですFChange

ところで、あなたのコードで、基礎となるフィールドを変更するPen1およびのプロパティ セッターを追加するのは間違いです。Brush1それは漏れやあらゆる種類の混乱につながります。また、ペンとブラシをパブリック プロパティとして公開すると、クライアントがイベントTGridObjを変更できるようになることに注意してください。OnChangeそして、それは転覆しTGridObj.OnChangeます。

于 2012-09-03T16:37:26.893 に答える
1

OnLoaded は、コンポーネントがフォーム リソース (dfm ファイル) からロードされた場合にのみ実行されます。

コンポーネントが実行時にコードのみで作成された場合、コンポーネントは実行されません。

アップデート:

実行時にも作成および構成できるようにコンポーネントを設計することをお勧めします。つまり、OnLoaded をオーバーライドすることは避けます。利点は、パッケージのインストール/コンポーネントの登録が必要ないことです。

于 2012-09-03T16:36:58.703 に答える