> それと、AAA.binの内容はバイナリーの情報である事を付け加えておきます。
> つまり、.dfmファイルとは異なります。
ReadComponentメソッドを検索していたら、こんなページに出くわしました。
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_TStream_ReadComponent.html
その中の Delphi Examples に超超ステキな手続きがありました。
コードを実行してみたら、.dfmファイルに出力される物と同じ?と思われる
文字列がMemoに得られました。
それを参考にして以下のようなコードを作成して試しました。
Button3でStringGridを動的に生成します。
ExamplesではFormCreateで行われる内容です。
Button1でそれをテキスト化します。Memoに文字列が表示されます。
MemoはScrollBarsをssBothにしておいてください。
Button2でStringGridをFreeした後、Memoのテキストから
コンポーネントを生成します。
----------------------------------
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
published
procedure MyEvent(Sender: TObject);
end;
var
Form1: TForm1;
StringGrid1 : TStringGrid;
LMethod : TMethod;
implementation
{$R *.dfm}
function ComponentToStringProc(Component: TComponent): string;
var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free;
end;
finally
BinStream.Free
end;
end;
function StringToComponentProc(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result:= BinStream.ReadComponent(nil);
finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;
// コンポーネントを文字列化
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(StringGrid1) then Memo1.Text := ComponentToStringProc(StringGrid1);
end;
// 文字列からコンポーネント生成
procedure TForm1.Button2Click(Sender: TObject);
begin
if Length(Memo1.Text) <= 10 then exit;
if Assigned(StringGrid1) then StringGrid1.Free;
StringGrid1 := (StringToComponentProc(Memo1.Text) as TStringGrid);
StringGrid1.Parent := Form1;
StringGrid1.Visible := true;
StringGrid1.Repaint;
sleep(1000);
StringGrid1.Top := 200;
//------ やはりここでイベントを登録しないとダメみたい
{
LMethod.Data := Self;
LMethod.Code := Self.MethodAddress('MyEvent');
if Assigned(LMethod.Code) then begin
StringGrid1.OnClick := TNotifyEvent(LMethod);
end;
}
//--------------------------------------
end;
// テスト対象のStringGridを動的に生成
procedure TForm1.Button3Click(Sender: TObject);
begin
if Assigned(StringGrid1) then begin
showmessage('既に存在しています。');
exit;
end;
StringGrid1 := TStringGrid.Create(Form1);
StringGrid1.Parent := Form1;
StringGrid1.Name := 'Ojisan'; // 名前は英数のみ有効
StringGrid1.Top := 70;
StringGrid1.Left := 330;
StringGrid1.Options := StringGrid1.Options + [goRowSizing,goColSizing,goEditing];
StringGrid1.Cells[2,2] := 'データ';
StringGrid1.ColWidths[2] := 100;
//------- イベントの登録
LMethod.Data := Self;
LMethod.Code := Self.MethodAddress('MyEvent');
if Assigned(LMethod.Code) then begin
StringGrid1.OnClick := TNotifyEvent(LMethod);
end;
end;
// 実行されるイベント
procedure TForm1.MyEvent(Sender: TObject);
begin
ShowMessage('Clicked !!');
end;
initialization
RegisterClass(TStringGrid);
// 文字入力を行うとInplaceEditを使うのでここに登録する
// 登録しないと 'クラスTInplaceEditが見つかりません'のエラーが出る
RegisterClass(TInplaceEdit);
end.
----------------------------------
結果は形状(セルの幅とか高さ)、OptionsなどはText化されますが、
セル内のデータとイベントは保存されないようです。
でも.dfmファイルには[OnClick = Button1Click]のようなイベントに
関連した文字列があるので、どこかにあるんでしょうね。
|