MDIアプリケーションにおいて単一フォームを作るには

解決


電解コンデンサ  2004-03-19 18:09:30  No: 7746

MDIアプリケーションを作っています。
その中で、Dialogでなく、MDIChildフォームで1個しか生成しない単一フォームを作りたいのです。

//単一フォームCreate
if not Assigned(SingleForm) then
    SingleForm := TSingleForm.Create(Application);
SingleForm.Show;

そして、このフォームのCloseイベントで、
Action := caFree;
SingleForm := nil;

としました。しかし、1個しか生成しないのは良かったのですが、1回閉じてまた開く時にエラーが発生してしまうのです。
どうもSingleFormがnilになってないようで…

もし良いアドバイスをいただける方がおられましたら、どうかよろしくお願いします。


ふぐちゃん  2004-03-19 18:45:38  No: 7747

具体的にどんなエラーなのかわかりませんので、
間違っているかもわかりませんが、
SingleForm := nil;
をOnDestroyに記述してみてはいかがでしょう。
私はいつもそうしているのですが、これでエラーに
なったことはないようです。


にしの  2004-03-19 18:55:56  No: 7748

こちらでは出来てます。
他に原因はありませんか?
バージョンが問題かも。
こちらはDelphi7Proです。
質問時には、環境を書いた方が早く解決できることが多いです。

また、現象を、最小のソースで再現できるか確認してみてください。


にしの  2004-03-19 18:57:14  No: 7749

「このフォーム」って、MDIChildの事ですよね?
まさかとは思いますが。
もちろん、MDI親フォームのOnCloseではダメです。


電解コンデンサ  2004-03-19 18:58:03  No: 7750

ふぐちゃんさん、回答ありがとうございます。

ご指摘の通りOnDestroyイベントに記述したのですが、やはりエラーが出てしまいました。
エラーは、EAccessViolationです。
1回閉じて、2回目にフォームを開くコードに入った時、SingleFormがnilになっていないみたいで、Create文に入らすShowしてしまってます。

エラーになったことは無いのですか…もっと違うバグがあるのかな?


電解コンデンサ  2004-03-19 19:04:41  No: 7751

にしのさん、回答ありがとうございます。

バージョンは、にしのさんと全く同じです。
記述しているのはもちろん、MDIChild側のOnCloseイベントです。

>また、現象を、最小のソースで再現できるか確認してみてください。

これをよく怠るんです…今からやってみます。アドバイスありがとうございました。


電解コンデンサ  2004-03-19 19:19:59  No: 7752

にしのさんへ

今、作ってやってみたのですが、自分のはやはり2回目に開く時にエラーになってしまいます…
しかし、今度はAbstractエラーと出ました。

自分の弱い頭では原因が見当たらないです…


jok  2004-03-19 20:13:21  No: 7753

> if not Assigned(SingleForm) then

これを使わずに、親フォームの  MDIChildCount と MDIChildren[] をつかって
is 演算子で TSingleForm クラスが生きているかどうかを確認すると nil を
代入する必要が無くなるのでよいと思います。


電解コンデンサ  2004-03-19 20:39:41  No: 7754

以下のようにしたらうまくいきました。

unit Unit1;

    ・
    ・
    ・

type
  TForm1 = class(TForm)
    ・
    ・
    ・

  public
    procedure SingleFormNil;
end;

var
  Form1: TForm1;
  SingleForm: TSingleForm;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    if not Assigned(SingleForm) then
        SingleForm := TSingleForm.Create(Application);

    SingleForm.Show;
end;

procedure TForm1.SingleFormNil;
begin
    SingleForm := nil;
end;

end.

そして、SingleFormのDestroyイベントで、SingleFormNilを実行しました。

書きながら思ったのですが、変数名をUnit1とUnit2で同じにしたのがマズかったのでしょうか…?


にしの  2004-03-19 21:17:58  No: 7755

名前空間を使わない場合、
unit1のSingleFormは、unit1.SingleForm
unit2のSingleFormは、unit2.SingleForm
を指定したことになります。
たぶん、unit2側で、unit1.SingleForm := nil;とすれば動きますよ。


jok  2004-03-19 22:06:26  No: 7756

およよー

インスタンス変数の可視性の問題だったのですね?
unit2 の TSingleForm でデフォルトで宣言されているのを使うべきだと思いますよ。
二つあれば混乱するのは当たり前です。


電解コンデンサ  2004-03-19 22:55:03  No: 7757

jokさん

言われる通りです。unit1でもなぜかTSingleFormの変数宣言してるのがマズかったです。
基本がなってませんね、はぁ・・・


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

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






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