TMemoryStreamでイベントハンドラを別のオブジェクトにコピーするには?

解決


とっさん  2007-03-25 11:00:04  No: 25504  IP: 192.*.*.*

はじめまして。

TMemoryStreamでイベントハンドラを別のオブジェクトにコピーする方法をご存じありませんか?

DelFusaBlogの「コンポーネントをインストールせずに使う方法」(http://delfusa.blog65.fc2.com/blog-entry-40.html)で記載されている方法は、コンポーネントを手軽に作成して利用できる点でとても興味深いのですが、このページに記載されているCreateClone()でどうもイベントハンドラを引き継いでくれないようです。

どなたかご教示いただけないでしょうか?

# サンプルコードを作成したけど、どのように上げたらいいのでしょう?

編集 削除
ん?  2007-03-26 00:44:32  No: 25505  IP: 192.*.*.*

> CreateClone()でどうもイベントハンドラを引き継いでくれない

published のイベントですか?

編集 削除
とっさん  2007-03-26 06:50:26  No: 25506  IP: 192.*.*.*

> published のイベントですか?
はい。
TEdit.OnChange() を含め引き継がれたイベントはありません。
以下、ソースの抜粋をあげます。

type
  TMyEdit = class(TEdit)
  public
    constructor CreateClone(Original: TEdit);
  end;

constructor TMyEdit.CreateClone(Original: TEdit);
var
  MemStream: TMemoryStream;
begin
  Create(Original.Owner);
  Self.Parent := Original.Parent;

  MemStream := TMemoryStream.Create;
  try
    MemStream.WriteComponent(Original);
    Original.Free;
    MemStream.Position := 0;
    MemStream.ReadComponent(Self);
  finally
    MemStream.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1 := TMyEdit.CreateClone(Edit1);
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  Label1.Caption := Edit1.Text;
end;

編集 削除
Rootに入らずンば Eventを得ず  2007-03-26 20:46:39  No: 25507  IP: 192.*.*.*

Read/WriteComponentは、TFormやTDataModuleなど Rootなコンポーネントで
なければ、Eventはんどらを拾えないということで...ほなら...どうする?

procedure TForm1.Button1Click(Sender: TObject);
var
  TxtStream: TStringStream;
  BinStream: TStream;
  Reader: TReader;
  Writer: TWriter;
  Origin: TEdit;
  MyEdit: TMyEdit;
begin
  Origin := Edit1;
  MyEdit := TMyEdit.Create(Origin.Owner);
  BinStream := TMemoryStream.Create();
  try
    Writer := TWriter.Create(BinStream, $1000);
    try
      Writer.Root := Origin.Owner;
      Writer.WriteSignature;
      Writer.WriteComponent(Origin);
      Writer.WriteListEnd;
    finally
      Writer.Free;
    end;
    // 試しに保存内容をチェックしてミル
    TxtStream := TStringStream.Create('');
    BinStream.Position := 0;
    ObjectBinaryToText(BinStream, TxtStream);
    Memo1.Text := TxtStream.DataString;
    TxtStream.Free;

    Reader := TReader.Create(BinStream, $1000);
    try
      Reader.Root := Origin.Owner;
      Reader.Owner := Origin.Owner;
      Reader.Parent := Origin.Parent;
      Reader.Position := 0;

      Origin.Free;

      Reader.BeginReferences;
      try
        Reader.ReadSignature;
        Reader.ReadComponent(MyEdit);
        Reader.FixupReferences;
      finally
        Reader.EndReferences;
      end;
    finally
      Reader.Free;
    end;
  finally
    BinStream.Free;
  end;
end;

編集 削除
とっさん  2007-03-26 22:17:14  No: 25508  IP: 192.*.*.*

なるほど。
言われてみれば納得です。
提示頂いたコードでしっかり引き継がれました。
ありがとうございました。

編集 削除