▼ Mr.XRAYさん
マスター ありがとうございます。
コンポーネントそのものに保存する機能はない。
TFileStream,TMemoryStreamのWriteComponent,ReadComponentメソッドを使う。
その時に保存される内容はAAA.binをメモ帳で見るとクラス名、位置、大きさ、
キャプション、タブオーダーまでで、イベントの設定の情報は無い。
オブジェクトインスペクタに表示されるButton1,Button2などは「設計時」の情報として
Unit1.dfmファイルに「OnClick = Button1Click」の記述がある。
'Button1Click'は多分Self.MethodAddress()で使われるのだろうと想像します。
ここまでは理解できます。
「//イベントを保存するには,TButtonの継承クラスを作成して,
そのイベントを作成する」
とのことですが、継承クラスを作成してキャストしなくてもMethodが代入できる?
みたいです。
追加した部分のコードで何か根本的な勘違いがありますでしょうか?
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
MyButton : TButton;
public
{ Public 宣言 }
published
procedure MyEvent(Sender: TObject);
end;
{
type
KeiButton = class(TButton); // 追加 継承クラス用
}
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
LMethod : TMethod;
LFileStream : TFileStream;
begin
MyButton := TButton.Create(Self);
MyButton.Parent := FindControl(Panel1.Handle);
MyButton.Top := 20;
MyButton.Left := 20;
MyButton.Caption := '私のボタン';
LMethod.Data := Self;
LMethod.Code := Self.MethodAddress('MyEvent');
if Assigned(LMethod.Code) then begin
MyButton.OnClick := TNotifyEvent(LMethod);
end;
//コンポーネントの保存
LFileStream := TFileStream.Create('AAA.bin', fmCreate);
try
LFileStream.WriteComponent(MyButton);
finally
FreeAndNil(LFileStream);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
LMethod : TMethod;
LFileStream : TFileStream;
LMyButton : TButton;
begin
//同名のコンポーネントは作成できないので別の名前にする
LMyButton := TButton.Create(Self);
//コンポーネントの読み込み
//イベント用のメソッドはTForm1のメンバなので保存はされていない
LFileStream := TFileStream.Create('AAA.bin', fmOpenRead);
try
LFileStream.ReadComponent(LMyButton);
//親(コンテナ)を設定しないと表示できないでエラー
//イベントを保存するには,TButtonの継承クラスを作成して,そのイベントを作成する
LMyButton.Parent := Panel1;
//------------- イベントを作成
LMethod.Data := Self;
LMethod.Code := Self.MethodAddress('MyEvent');
if Assigned(LMethod.Code) then begin
// KeiButton(LMyButton).OnClick := TNotifyEvent(LMethod); // KeiButtonでキャスト
LMyButton.OnClick := TNotifyEvent(LMethod); // 直接代入できちゃう?
end;
//-------------
LMyButton.Update; // .Top := 20; を表示するため
Sleep(1000);
LMyButton.Top := 100;
finally
FreeAndNil(LFileStream);
end;
end;
procedure TForm1.MyEvent(Sender: TObject);
begin
ShowMessage('Clicked !!');
end;
end.
|