喫茶XRAYトップページ

[スレッド全体
]

[11171] Re6:Memo99は親ウィンドウを持っていません返信 削除
2017/5/2 (火) 10:46:12 taki
▼ Mr.XRAYさん
> > function StringToComponentProc(Value: string): TComponent;は
> > もったいないけど使えないな〜と思っています。
>
> う〜む.必ずしもそうとは言えないかも.


function StringToComponentProc(Value: string): TComponent;で使われている
Result:= BinStream.ReadComponent(nil);
は、メソッド内でコンポーネントがCreateされている事と、
TComponentはParentプロパティが設定できません。

問題はMemoのLinesの設定が存在することでエラーになるので、
Memo99を「空」の状態で文字列に保存することを考えました。

その結果、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, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  published

  end;

var
  Form1: TForm1;
  Memo99  : TMemo;

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
  Memo1.Text := ComponentToStringProc(Memo99);
end;

// 文字列からコンポーネントを生成
procedure TForm1.Button2Click(Sender: TObject);
begin

  if Assigned(Memo99) then Memo99.Free;
  Memo99 := (StringToComponentProc(Memo1.Text) as TMemo);
  Memo99.Parent := Form1;
  Memo99.Left := 200;
  Memo99.Visible := true;

end;

// 動的にコンポーネントを生成
procedure TForm1.Button3Click(Sender: TObject);
begin

  Memo99 := TMemo.Create(Self);
  Memo99.Parent := Self;
  Memo99.Name := 'Memo99';
  Memo99.Top := 100;
  Memo99.Left := 100;
  Memo99.Width := 200;
  Memo99.Height := 20;
  Memo99.Clear;   // <- これを追加 中身を空に

end;

initialization

  RegisterClass(TMemo);

end.

要するに、現状のコンポーネント(だけ)の保存&生成ですよ。
中身は後でセットしてね。と言う事ですか…。

しつこくてすみません。


[11172] Re7:Memo99は親ウィンドウを持っていません返信 削除
2017/5/2 (火) 11:05:33 taki
マスターすみません。

記事を読み直していたら

> Lines プロパティ,つまり TMemo に描画する文字列は描画するコントロール,
> つまり,TMemo がないと描画,表示できません.
>
>        Result:= BinStream.ReadComponent(nil);
>
> の段階では TMemo の親が決まっていませんから,そのエラーとなるのでは
>  ないかと思います.
> Lines プロパティの値が空であればエラーは発生しないですね.
> TListBox 等も同じです.


と、指摘が既にありました。
> Lines プロパティの値が空であればエラーは発生しないですね.
を見逃していました。m(_ _)m




[11173] Re8:Memo99は親ウィンドウを持っていません返信 削除
2017/5/2 (火) 17:55:31 Mr.XRAY
>しつこくてすみません

しつこさ,くどさが大切です.と私は思っています.

> > Lines プロパティの値が空であればエラーは発生しないですね.
> を見逃していました。m(_ _)m


こういうことの繰り返しです.人生は.
私がいい手本です.
ん ? よくはないか... ハハハッ


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82