1

私はマルチスレッドの Delphi 6 Pro アプリケーションを持っており、現在鋭意開発中です。メイン スレッド (VCL スレッド) のコンテキストで実行されるコードにブレークポイントを設定しても、問題はありません。ただし、他のスレッドのいずれかのコードでブレークポイントがトリガーされた場合、ブレークポイントからアプリケーションを続行した後、メイン スレッド (メイン フォームを含む) の VCL コンポーネントへのすべての再描画が行われなくなります。他のバックグラウンド コードが実行され続けているため、アプリケーションが死んでいるわけではなく、メイン スレッドだけです。Windows メッセージ ディスパッチャーが破損しているか、休止状態になっているようです。

このアプリケーションでは、登録された特定のメッセージをキャッチする必要があるため、メイン フォームの allocateHwnd() を介して独自の WndProc() を割り当てます。その WndProc() から、処理するカスタム メッセージをディスパッチし、現在のメッセージがコードで処理されない場合は、メイン フォームの継承された WndProc() を呼び出してメッセージを渡します。現在のメッセージを処理する場合は、メッセージが処理されたことをディスパッチャに伝えるために、Msg.Result を 1 に設定して WndProc() から返すだけです。独自の WndProc() を割り当てる代わりに、単に TForm WndProc() をオーバーライドすることはできません。何らかの理由で、Delphi VCL は Windows API の RegisterWindowMessage() 呼び出しでインスタンス化された登録済みメッセージを通過しないためです。

同様の状況でこれを経験した人はいますか? もしそうなら、それを修正するために何をしましたか?

-- ロシェル

4

2 に答える 2

2

を呼び出したので、別のウィンドウAllocateHWndを作成したことになります。そのウィンドウに宛てられたメッセージをそのままフォームのウィンドウに転送してはいけません。それを行うと、正確な方法はわかりませんが、プログラムで問題が発生することになります。塗装の問題はもっともらしく聞こえます。メインスレッドがまだ中断されているのではなく、実際にペイントの問題であることを確認する必要があります。デバッガーはそれを伝えることができるはずです。(自分で処理する準備ができていないメッセージを割り当てられたウィンドウで処理するには、 を呼び出す必要があります。また、1 を返しても、ディスパッチャには何も通知されません。ディスパッチャは気にしません。呼び出した人は誰でも結果を知りたがっています。)DefWindowProcSendMessage

フォームは、登録されたウィンドウ メッセージを完全に受信できることをお約束します。プロパティに新しい値をオーバーライドWndProcまたは割り当てWindowProcます (独自のメッセージを処理した後に呼び出すことができるように、古い値を保存することを忘れないでください)。問題の原因は別の場所にあります。

于 2010-07-26T04:26:08.663 に答える
0

更新:私が問題を乗り越えた方法が良い解決策であると言っているのではありません。Rob Kennedyのメモを取り、リファクタリングを行う必要があります。ただし、今のところ問題を回避するために、スレッドに独自のWindowとWndProc()を指定し、スレッドの実行ループの先頭に、TranslateMessage()とDispatchMessage()を呼び出すPeekMessage()whileループがあります。スレッドにブレークポイントを設定することに問題はなくなりましたが、明らかにこのWndProc()メソッドの複合は、コードの構造上の問題を示しています。ディスカッションに記入するために、この返信を追加したいと思いました。関連するフォーム、特にメインフォームでWndProc()メソッドをクリーンアップするときに、Robの提案が機能するようになったら、スレッドに追加したばかりのこの新しいWndProc()を削除できることを期待しています。

ロバート。

于 2010-07-27T04:52:54.953 に答える