実行時プロパティの保存をするには?

解決


きのこ  2003-06-02 19:04:10  No: 3671

みなさんおはようございます。
早速ですが質問させて下さい。
今回FormCreate時に動的にコンポーネントを作成
(コンポをたくさん配置しています)し、実行時に位置変更及びプロパティの変更
をします。そして、その値をFormClose時に保存し再度実行するとFormCreate時に
保存状態をプロパティにセットしたいのです。
その方法として、
1.WriteComponentResFileで保存しReadComponentResFileで読み込みをする。
2.TFileStreamを使う。
3.iniファイルに保存する。
色々調べてこの3つの方法がでてきたのですが、
上記のことをするとすればどの方法が一番いいですか?
また、他のやり方がありばそのやり方も教えてもらえるとうれしいです。
以上、御教授お願いします。


にしの  2003-06-02 19:17:37  No: 3672

セキュリティホールにならないのであれば、WriteComponentResFileでよいかと思います。

僕だったら(コンポーネントの量にもよりますが)INIファイルか、暗号化したバイナリファイルに書き込みます。


きのこ  2003-06-03 01:00:03  No: 3673

にしの様早速のレスありがとうございます。
まず、WriteComponentResFileでやってみようと思っています。
早速取りかかっているのですが早速つまずいてしまったので教えてください。
FormCreate時にReadComponentResFileで読み込みます。
ここまでは、うまくいくのですがボタンを使い今度は違うファイルを
ReadComponentResFileで読み込むとエラーが出てしまいます。
コンポーネントが残っているからダメだと思い全コンポーネントをFreeしてみたのですがそうすると押されたボタンもFreeしてしまうので再度エラーが出て
しまいます。どうすればうまく読み込めますか?
説明下手ですみませんが御教授お願いいたします。

以下テストプログラムです。
procedure TForm1.FormCreate(Sender: TObject);
var
  Bu : TButton;
begin
  ReadComponentResFile('test',self)
  Bu := FindComponent('Button1') as TCuteButton;
  Bu.OnClick := TestClick;
end;

procedure TForm1.TestClick(Sender: TObject);
var
  Cu : TCuteButton;
  i :Integer;
begin
  for i := ControlCount-1 downto 0 do
      Controls[i].Free;

  ReadComponentResFile('test1',self);
end;

initialization
  RegisterClasses([TButton,TEdit,TLabel,Tpanel]);


にしの  2003-06-03 03:15:41  No: 3674

ReadComponentResFileでもどすのであれば、最初の状態にコンポーネントがあってはいけません。
Form2: TForm;

Form2 := TForm.CreateNew(Application);
ReadComponentResFile('保存してあるdfmファイル', Form2);
とすれば、Form2にボタンなどが復元されます。

CreateNewをヘルプで調べてみてください。

初期状態(dfmがない状態)ではどうするかというと・・・自分で作成して貼り付けてやるしかないと思います。


きのこ  2003-06-03 21:59:40  No: 3675

にしの様レスありがとうございます。
なるほどCreateNewで新しくFormを作成してやればいいのですね。
もう少し教えてください。
表示はうまくいっているのですが何度もCreateNewで作成しCloseしていると
メモリが蓄積してしまいます。どうすれば開放できるのでしょうか?

以下テストプログラムです。
    { Public 宣言 }
    FrmNo :Integer;
    Frm1,Frm2:TForm;
    procedure FormChange(No: Integer);
    procedure TestClick(Sender: TObject);
  end;

var
  Form2: TForm2;

implementation

uses testHyozi;

{$R *.dfm}

procedure TForm2.FormChange(No: Integer);
var
  Cu : TButton
begin
    FrmNo := No;
    case FrmNo of
      1:begin
        Frm1 := TForm.CreateNew(Application);
        ReadComponentResFile('Unit1.dfm',Frm1);
        Frm1.Show;
        cu := Frm1.FindComponent('Button1') as TButton
        cu.OnClick := TestClick;
      end;
      2:begin
        Frm2 := TForm.CreateNew(Application);
        ReadComponentResFile('Unit2.dfm',Frm2);
        Frm2.Show;
        cu := Frm2.FindComponent('Button1') as TButton
        cu.OnClick := TestClick;
      end;
  end;
end;

procedure TForm2.TestClick(Sender: TObject);
begin
  if Form2.FrmNo = 1 then
  begin
    Form2.FormChange(2);
    Frm1.Close;
  end
  else
  begin
    Form2.FormChange(1);
    Frm2.Close;
  end;
end;

procedure TForm2.FormShow(Sender: TObject);
var
  Cu : TButton
begin
    FrmNo := 1;
    Frm1 := TForm.CreateNew(Application);
    ReadComponentResFile('Unit1.dfm',Frm1);
    Frm1.Show;
    cu := Frm1.FindComponent('Button1') as TButton
    cu.OnClick := TestClick;
end;


にしの  2003-06-04 00:14:27  No: 3676

Closeしても、メモリから解放されませんよ。
Releaseにしてみてはどうでしょう。


きのこ  2003-06-04 20:11:45  No: 3677

にしのさんレスありがとうございます。
すみませんがもう少しお付き合い下さい。
Formの表示はうまくいったのですが、プログラムは上記テストプログラム
のようにイベントなどを1つづつ入れていくしかないのですか?
ヘルプをみても具体的な事はかいていません。
度々すみませがお願い致します。


にしの  2003-06-04 21:30:36  No: 3678

Button1.OnClickに、Button1Clickイベントがあったとします。
TForm.CreateNewで作成した場合、Button1Clickメソッドはどこにあるのでしょうか。
単に、Button1Clickメソッドを参照できないから入らないだけだと思いますよ。

いくつかの例えです(内容はDelphiとは関係ありません)。
語弊があるかもしれませんが、イメージということで。

1.
猿が進化すると人間になる。
では、猿に服を着せれば、人間になりうるか。
# 諸処あるでしょうが、さらりと流してください

2.
ここに、2つの乗り物がある。
1つは飛行機で、もう1つは自動車である。
自動車に羽をつければ、飛行機になりうるか。

3.
ここに、PCの本体だけがある。
別の、すでに動いていたPCから、キーボード・マウス・ディスプレイ・電源ケーブルを持ってきて電源を入れた。
電源は入ったのだが、動かない。
原因は何か。
--
A1.なり得ない。猿にはない機能(知能など)があるから。
A2.なり得ない。自動車には飛行能力はない。
A3.本体の中身(CPU,マザーボード,ハードディスクなど)がない。あるいはOSがインストールされていない。

全て、中身の何かが足りないわけですね。

CreateNewするクラスの中に、Button1Clickがあれば、Button1.OnClickにButton1Clickが正常に実装されるはずです。
# もちろん、定義にbutton1Clickがあればですが。
詳しく調べていませんが、もしかしたら関数のメモリ上の位置も関係するかもしれませんので、保存元のFormクラスのインスタンスに読み込んでやれば確実です。


きのこ  2003-06-05 04:27:09  No: 3679

にしの様うまくいきました。
色々なアドバイスありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加