2012-04-30 21 views
2

私はこの問題をうまく説明できることを願っています!Delphi TForm OnCreateが複数回呼び出される

私はReWireオーディオデバイスをDelphi .dllとして実装しようとしています。 ReWireが何であるかわからない場合は、心配しないでください。重要なのは、私のコードが.dllにコンパイルされ、ReWireシステムから.dllへの呼び出しが表示され、表示が開かれているかどうかを確認し、もう一度閉じます。私が起動するコールを取得すると

、私は次の操作を行います

if not Assigned(form) then 
    form := TMyForm.Create(nil); 
    form.Show; 

どこformは私のDelphiのライブラリの内部グローバル変数です(多分問題?)。私はMyFormOnCreateイベントを利用して、私が働きたいものの配列を準備するような面白いことをしました。

これまでのところすべてが有効です。私のフォームには、TOpenDialogを開く小さなボタンがあります。そのダイアログが閉じるとすぐに、何とかOnCreateイベントが私のフォームで再び発生していることがわかりました!

私はOnDestroyが呼び出されていないことを確認しました。なぜOnCreateが再び呼び出されるのかわかりません。

残念ながら私は、関連する情報は本当にわからないんだけど、ここでの呼び出しは(フォームが最初に設定されている)最初の頃スタックです:予想通り

First call stack

を、ReWireのが作っています私の.dllを呼び出してPanelアプリケーションを起動して、フォームを作成します。素晴らしい、ものはよく見ている。

私のフォームの中で、少しダイアログを開いてファイルを選択し、いくつかの操作を行います。左のフィールドのうち、OnCreateが再び呼び出され、ここでの呼び出しはその時間を積み重ねるですされています

Second call stack

それは呼び出しのクレイジーパーティです!私のアプリケーションをテストするために使用しているReWireホストのReaper(Reaperの下)は、私のコードではないので、スタックトレースの内部で何が起こっているのか分かりません。突然、イベントはちょうど私がそれがすべきだと思わないときに呼び出されます。OnDestroyは呼び出されていないからです。

私は考えることができる唯一の他の重要なことは、私はSenderのアドレスをプリントアウトした場合、それは異なる各時間ですので、それが何らかの形で再び作成さか何かが、私は私だけ呼んでいることをチェックしましたばかりだということです一度MyForm.Createを実行します。

どのようにこのようなことが起こるかについてのアイデアはありますか?

+1

これは機能しません。 2つのVCLインスタンスがあります。 1つはexeに、もう1つはDLLにあります。静的にすべて1つのexeにリンクします。または、パッケージを使用してください。 –

+0

まず、OnCreateロジックを削除して、まったく動作するかどうかを確認します。次に、OnShowハ​​ンドラにポストされているWM_USERメッセージハンドラの新しい関数にロジックを移動します。そうすれば、ユーザーはフォームを早期に見ることができ、セットアップが実行されている(遅延がない)ことが分かります。これにより、2つの部分を分離することができ、1つの部分のエラーを識別しやすくなります。 – mj2008

+0

みなさん、お世話になりました。答えは@Remy Lebeauが提案したものと似ていて、彼の反応の下にコメントで詳述されています。私は本当に皆様のご意見をお待ちしております!私はDavid Heffernanのコメントに少し心配しています。私はこのVCLのすべてに触れていないので、何かが狂ったら、VCLのインスタンスを1つに保つ方法を考えてみましょう! – aardvarkk

答えて

4

最初のスタックトレースでは、TCustomForm.Create()を呼び出す前にOnCreateが呼び出されますが、これは正しい動作です。 2番目のスタックトレースでは、代わりにTObject.Create()へのコールによってOnCreateコールが先行されますが、これは正しく動作しません。あなたのボタンOnClickイベントハンドラの何かが、悪いVMTを持つオブジェクトを構築しているか、そうでなければメモリが一般に壊れていて、ちょうどTFormクラスが占有しているコードに悪いジャンプを引き起こしていると思うようになります。いずれにしても、OnClickロジックでバグを再確認してください。

+0

これは、問題が明らかになったものにかなり近いです。私はそれを昨夜遅く発見しました(今朝の早い?)。私は 'my_obj:= TMyClass.Create'ではなく' my_obj:= my_obj.Create'というコードでオブジェクトをインスタンス化しました。愚かな間違い。残念ながら、それは明らかに*両方の有効な構文であり、実行時にエラー/例外を発生させませんでした。その結果、関数が初期化されていない変数で呼び出された後、あらゆる種類の狂気が起こっていました。正しい構文に切り替えると問題が解決しました。あなたの助けをありがとう! – aardvarkk

1

フォーム変数をnilに設定する場所を確認します。それは、それが指しているフォームを解放せずにnilに設定されている可能性があります。そのため、次に起動コードを呼び出すと、フォームの別のインスタンスが作成されます。

+0

良い提案。残念ながら、私はLaunchコールが一度だけ行われたことを確認しました。そして、変数は一度作成された後に 'nil'に戻されません。 – aardvarkk

関連する問題