2009-08-09 8 views
4

Application.ProcessMessagesコマンドはよく知られており、長いプロセスで使用してプログラムがコンピュータを拘束しないようにします。DelphiでProcessMessagesを防止する方法

しかし、私はファイルのビューをバッファリングしているかなり簡単な処理セットを持っています。バッファリング手順の間に、いくつかのシステムメッセージが送信される(例えば、再描画またはスクロールバー移動または他のイベント)。バッファリングが完了するまでProcessMessagesで処理されないようにしたい。

は、いずれかの方法はあります:

  1. 防止Application.ProcessMessages私の手続きが完了するまで、またはすべての私の手続きの際に生成されたメッセージ、およびないが、年末までにそれらを解放

  2. トラップです手順。

+0

あなたの質問を読み直す、私は実際にそれを理解していない - クイック実行の手順を持っていて、この中には全く 'Application.ProcessMessages'を呼び出すなぜ' Application.ProcessMessages'は、任意の歓迎されないメッセージを処理しない場合手順? – mghie

+0

mghie:明示的に呼び出すのではありませんが、メッセージが処理された場合に実行されるいくつかのイベントをキューに追加します(スクロールバーの位置など)。あなたのプロシージャ内であれば、あなたが明示的に何も**イベントが処理されません。** 'Application.ProcessMessages'呼び出さない限り:私は保留中のイベントが – lkessler

+0

を実行していないしかし、それがポイントだ得ることを、単にこのコードの間に確保する必要があります。それらはキューに追加され、後で処理されますが、それだけです。あなたが望んでいない限り、メッセージはどのように処理されますか? – mghie

答えて

5

ProcessMessagesが、それはあなたが問題として分類すべきではないしたくないメッセージを送信した場合でも継続させることができます。少しのコードリファクタリングでは、バッファリングメソッドを別のスレッドに移動してそこから移動することができます。

あなたがファイルにコントロールの「映像コンテンツ」をコピーしようとしている場合は、子供が

  • てみビットマップに自分自身を描画するために制御できますWM_PRINT(XXX)メッセージで

    • 外観あなたがする必要があり、単にメッセージごとに「真」を返す場合は、あなたのコントロールクラス、あるいは、親クラスのWndProc/DefaultWndProc方法
    • オーバーライドそのコントロールにすべてのペイントメッセージをオフにしますLockWindowUpdateのWin32 APIのメソッド呼び出しは、
    • を送りましたコントロールクラス、あるいは親に(例えば、「スクロールバーが移動する」として、「 OnPaint」、「 OnPaintBackground」など)の
    • オーバーライド具体的な制御方法と、あなたのバッファリングが進行
    • に上書き

    であれば、単純に何もしませんWndProcまたはDefaultWndProcとなり、各メッセージのtrueを返すだけでは実質的に「オフ」になります。ProcessMessagesしかしコントロールが正しく機能するには1つ以上のメッセージを処理する必要があるためです。

    ProcessMessagesをオフにすることはできません(メッセージ処理用のVCLコードを書き換えずに)。これはVCLフォームのメッセージループの構築方法の一部であるためです。

  • +0

    LockWindowUpdateは私が探していたようです。あなたの他のアイデアも良いです。ありがとう。 – lkessler

    +4

    LockWindowUpdate()APIは、レイモンド・チェンによると、使用すべきではありません。http://blogs.msdn.com/oldnewthing/archive/2007/02/23/1747713.aspx少なくとも、それはあなたが望むもののために使用すべきではありませんそれを使用する:http://blogs.msdn.com/oldnewthing/archive/2007/02/22/1742084.aspx – mghie

    +0

    うーん。ありがとうmghie。あなたの警告は尊重されます。しかし、マイクは、正しい方向に私を導くための処理について、まだ多くの情報を私にくれました。 – lkessler

    2

    プロシージャ中に生成されたすべてのメッセージをトラップし、手順の最後まで を解放しないでください。

    あなたが行うことができます汚いハック(あなたがより良い方法を考え出すことができない場合のみ)があります:

    あなたはWin32 Hooksを使用して(トラップ)すべてのメッセージを見ることができます。
    具体的には、idHook値としてWH_CALLWNDPROCを指定してSetWindowsHookExを使用してください。
    あなたはその後、記録それらのリスト/キュー内としたいときにそれらを再送信することができます。

    +0

    これはうまくいくと思います。 Mikeのアイデアよりも少しは機能しますが、完全にコントロールできます。ありがとう。 – lkessler

    1

    は、私は帰りのWindows 2でのWindowsメッセージは、あなたがそれらを期待していない時期に起こるだろうということを学びました。ライブラリのどの部分でも、アプリケーションのメッセージ処理が行われる可能性があります。潮を握るのではなく、あなたのコードを状況に対して頑強にする。これは、BeginUpdate/EndUpdateのペアを使用するか、より複雑な(一時的なものを使用して最後に最終更新を行うなど)簡単な場合があります。

    +0

    これは私が探しているものです:作業が完了するまですべてのWindowsイベントを防ぐBeginUpdate/EndUpdateのペア。しかし、これらは、再塗りつぶしを防ぐためにのみ機能すると信じています。 – lkessler

    0

    知識をひけらかすレベルでは、あなたがApplication.ProcessMessagesを「防ぐ」方法は

    1. モーダルダイアログが表示されていることを任意のコードを呼び出すしないことです独自のローカルメッセージループ
    2. を実行します
    3. のSendMessageを呼び出します(ローカルメッセージループである)
    4. 呼び出しのApplication.ProcessMessages

    あなたはノーを行うループを記述する場合数値計算やファイルI/Oを使用すると、メッセージが処理されていないためループを終了するまでUIはフリーズします。

    未知の任意のコード(第三者のライブラリ)を長時間実行している間にUIを反応させたいが、その間に特定の種類のアクションが発生しないようにするには、それは別の問題ですそれは再入国を防ぐことです。特定のアクティビティが進行中にコードの一部が使用されないようにしたいとします。たとえば、モーダルダイアログは、モーダルダイアログ自体を除くすべてのアプリケーションのトップレベルウィンドウを無効にすることによって、ダイアログの下にあるアプリケーションウィンドウとやりとりするのを防ぎます。

    関連する問題