2010-11-29 15 views
3

スレッドを大量に使用するサードパーティライブラリを使用しています。メインフォームを使用せずにスレッドからオブジェクトに直接メッセージを送信

スレッドからメインスレッドに返信するメッセージを使用し始めました。すべて動作していますが、SendMessageを使用すると、以下のように記述するのが面倒です。メインフォームがすべてのメッセージを送出しなければならないためです。メインフォームに依存せずにフレームまたはオブジェクトに直接メッセージを送信する方法はありますか?プログラム起動時に

MyMessageNumber1 := RegisterWindowMessage('MyUniqueID1'); 
MyMessageNumber2 := RegisterWindowMessage('MyUniqueID2'); 

任意のデータなしでメッセージを送信し、私が行います。要するに

procedure WndProc(var Message: TMessage); override; 
if (Message.Msg = MyMessageNumber1) 
    ... call a frame or other object's method that handles this particular message 
else if (Message.Msg = MyMessageNumber2) then 
    ... call another .... 
else 
    inherited; 

SendMessage(Application.MainForm.Handle, MyMessageNumber1) 

私のメインフォームには、これを持っています上記のWndProcは、私がすべてのメッセージとそれらを誰にディスパッチするかについて、私が好むよりはるかに多くを知る必要があります。

どのようにオブジェクトを受け取ることができる方法でスレッドから直接メッセージを送信できますか?

これらのメッセージにはすべて、関連付けられたデータがありません。 (私たちは、いくつかの他の日それを買ってあげる!):-)

TIA

+0

私は、WndProcがメッセージについてあまり知っていることができないという概念を受け入れるのは難しいと感じています。メッセージの処理はWndProcの**仕事**です。 –

+0

#Rob Kennedy - WndProcがメインフォーム(必要と思われるので、この質問)であれば、メインフォームは低レベルコードの詳細についてすべて知っていなければならないので、メッセージを送信できます。メイソンが指摘しているように、低レベルのコードがメッセージを明示的にキャッチできるときに、メインフォームがいくつかの低レベルコードの内部の詳細を知る必要があるのはなぜですか? – RobertFrank

答えて

2

他のフォームとフレームにもハンドルがあり、メッセージ処理メソッドを定義してからフォームまたはフレームにメッセージを直接投稿することができます。 (独自のカスタムコントロールを構築している場合は、コントロールする必要があります)

メッセージ処理メソッドの設定の概要については、http://docwiki.embarcadero.com/RADStudio/en/Declaring_a_New_Message-handling_Methodを参照してください。

+1

これには注意してください。 TWinControl.Handleプロパティはスレッドセーフではありません。メッセージの送信時にコントロールのHWNDが再作成されてビジー状態になると、スレッドの内部からコントロールのHandleプロパティを読み取ると重大な結果を招く可能性があります。 AllocateHWND()を使用して専用のHWNDを設定するのがベストです。 –

+0

@Remy Lebeau - どのようなコンテキストで、コントロールのHWNDが再作成中ですか?例えば、私のコントロールがメインフォーム上のアプリケーションのメインフォームの一部である場合、HWNDはプログラムの実行後に再作成されますか? – RobertFrank

+0

はい、できます。 TWinControlには公開RecreateWnd()メソッドがあります。多くのVCLプロパティーセッターは、新しいプロパティー値を既存のHWNDに適用する必要があるときに、RecreateWnd()を内部的に呼び出します。 HWND属性を操作するほとんどのVCLコントロールは、単にRecreateWnd()を呼び出し、CreateWnd()をオーバーライドして現在のプロパティ値を各HWNDに適用するだけです(より効率的で、HWNDを再作成する必要はありません)コントロールの存続期間中に作成されます。 –

4

はいすることができます。 AllocateHWNDを使用して、任意のオブジェクトにウィンドウハンドルを割り当てることができます。このハンドルは、にメッセージを送信するために使用できます。

しかし、問題はSendMessageにある可能性があります。 SendMessageの代わりにPostMessageを使用すると、呼び出しはただちに戻ります。 PostMessageはメッセージの処理を待機しません。したがって、メッセージの結果が不要で、スレッドデータへの参照を送信する必要がない場合は、PostMessageを使用できます。

+1

私は誰かがこの応答をdownvoted参照してください。これは、既にハンドルがあるFrameまたは他のWinControlのハンドルを作成する必要がないためです。ただし、オブジェクト*がメッセージを受信できるようにするには、そのオブジェクトにハンドルを渡す必要があります。 – GolezTrol

+0

PostMessageは、データを送信する必要がない場合でも、スレッド間通信の方が効率的です。 :) – GolezTrol

+0

これはコントロールにも適用されます。 TTimerは、AllocateWNDを使用してタイマーメッセージを受信するためのウィンドウを作成する非ウィンドウコントロールの優れた例です。 – GolezTrol

関連する問題