- ベストアンサー
Delphi動的なフォーム生成について
- Delphiにおける動的なフォーム生成についての疑問です。
- フォームのインスタンスを作成する際、古いインスタンスはどうなるのか、また、フォームを再作成する際にはどのようにすれば良いのかについて教えてください。
- 実際にフォームを再作成しようとした際、アクセス違反のエラーが発生しました。このエラーの原因と対処方法についても教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 メインのForm2にButtonを1つを置き、プロジェクトのオプションでForm1の自動作成を「選択可能」へ写して、Form2のButton1のClickイベントに procedure TForm2.Button1Click(Sender: TObject); var Frm : TForm1; begin Frm := TForm1.Create(Application); try Self.Hide; Frm.ShowModal; finally Self.Show; Frm.Release; end; end; とかやってみました。 こんなイメージでしょうか?
その他の回答 (3)
- papayuka
- ベストアンサー率45% (1388/3066)
こんにちは。 > どうやらフォーム上で用いたオブジェクトの解放の方法に問題があったようです。 この場合フォームに動的に作成して配置したTImageはフォームが破棄される時に自動的に破棄されると認識してますが、、、
お礼
TImageのほかに元々Formに乗っていたDirectX関係のオブジェクトが原因でした。 簡単に説明しようとして端折りすぎてしまいました。Image生成時に落ちていたので、てっきりImageのせいだと思っていたので・・・申し訳ないですm(_ _)m
- papayuka
- ベストアンサー率45% (1388/3066)
こんにちは。 不具合の再現できる最小限のソースを提示されてはどうでしょう? Form1 のUses に ExtCtrls, ClipBrd, StdCtrls を追加して、 procedure TForm1.FormCreate(Sender: TObject); begin if Clipboard.HasFormat(CF_TEXT) then begin with TMemo.Create(Self) do begin Parent := Self; Align := alClient; Lines.Add(Clipboard.AsText); end; end else if Clipboard.HasFormat(CF_PICTURE) then begin with TImage.Create(Self) do begin Parent := Self; Align := alClient; AutoSize := True; Picture.Assign(Clipboard); end; end; end; ペイントなどから画像をクリップボードにコピーしてから実行すると Form1 に画像が表示され、文字だとメモが表示されます。こちらでは何回呼んでもアクセス違反は発生しないようです。
お礼
最小限まで削ってみたのですが、削っていくとEAccessViolationがEAbstractErrorになったり、全く無関係の場所を削っただけでエラーが出なくなったりと、手に負えなくなってしまいました。それで今日、TImageの親をForm1からForm2あるいはSelfにしたところ、生成時のエラーが出なくなり、フォームの再生成ができるようになりました。ただし、今度は2回目にReleaseしようとするとアクセス違反になってしまいましたが・・・。 何度も申し訳ありません。もう少し調べてみます。
補足
すみません、「発生原因が不明のエラー」ですが、どうやらフォーム上で用いたオブジェクトの解放の方法に問題があったようです。 今まで、想定しうる最大の個数ぶんを解放する命令を書いていまして・・・実際に作ったインスタンスの個数を越えて解放しようとしており、矛盾が起きていたようでした。 いろいろとありがとうございました。お騒がせして申し訳ありません。
- papayuka
- ベストアンサー率45% (1388/3066)
こんにちは。 具体的にはどんなソースを書かれていますか? 提示されても解決出来るかは解りませんが、、、
補足
お答えありがとうございます。Form2がメインフォームで、メニュー画面になっています。内容を選択すると、それに沿った内容でForm1のデザインが変わるようになっています。Form1と、それに配置されるコンポーネントは選択に応じてその都度生成されます。いままでは、Form1を終了させるとアプリケーションが終了するようしていたのですが、メニューに戻る必要が生じて、Form1を閉じるときに自身を破棄し、Formメニューから選択すると再び生成・・・ということがやりたいのです。 Form1に属するメンバを全て廃棄すれば良いんだと思っているのですが、上手くいかなくて・・・。(汗
お礼
ありがとうございます。この方法で行けると思ったのですが、アクセス違反が発生してしまいました。 TForm1.Create(Application); としてから、Form1.OnCreate内にて Timage.create(form1); をしているのですが、一度破棄して再度imageを作ろうとするとコケるようです。メモリリークも確認しましたが、していないようです・・・。