あなたのメッセージはそこに届きます。PostMessageが機能することが保証されていない理由はわかりませんが、機能します。(編集:PostMessage()がTRUEを返すと仮定します!戻りコードを確認してください!)
スレッド間でデータを通信するためにキューを使用することは避けたいと考えています。両方のスレッドがアクセスするキューはすべて保護する必要があります。両側にハードロックを追加すると、アプリケーションがシリアル化されます。
代わりに、を使用してヒープ上にデータnewを含むデータ構造を作成し、他のスレッドに「データがあります。これがあります」と伝えます。次に、受信スレッドはそのデータポインターの所有権を取得し、それを実行deleteする責任があります。このようにすると、ハードロックは発生しません。
今、唯一のトリックは「他のスレッドに教える」部分を理解することですが、それも簡単です。
ワーカースレッドからメインスレッドにデータを送信する場合は、次を使用しますPostMessage()。
worker_thread_proc()
{
// ..
// Create the data object you're going to pass to the MT
MyData* data = new MyData;
data->some_value_ = "foo";
// Pass it:
PostMessage(main_wnd, WM_YOU_HAVE_DATA, reinterpret_cast<WPARAM>(data), 0);
}
...メインスレッドはこれを処理してから、データを削除します。
MainWnd::OnYouHaveData(WPARAM wp, LPARAM)
{
std::auto_ptr<MyData> data(reinterpret_cast<MyData*>(wp));
my_widget->set_text(data->some_value_); // you get the idea
}
外部アプリのカスタムメッセージが自分のものにぶつかるのが心配な場合は、RegisterWindowsMessage()を使用してWindowsに一意のメッセージIDを与えることができます。ここでの唯一の課題は、メッセージの正しい名前を選択することです。
メインスレッドからワーカースレッドにデータを送信する場合は、上記と同じようにPostMessage()実行できますが、壁を越えてデータを送信する代わりに、 QueueUserAPC()を使用できます(ワーカーの広告がアラート可能であることを確認してください)待機状態-リンクされたドキュメントの注釈を読んでください)またはPostThreadMessage()。
編集:
OPでのコメントによると、PostMessage()が機能しないことを心配している理由がわかりました。
はい、Windowsメッセージキューのサイズには厳しい制限があります。デフォルトでは、キューに含めることができるメッセージは4,000件のみです。(レジストリ設定では、これを最大10,000まで調整できます)。
キューがいっぱいにPostMessage()なると、への呼び出しはすべてエラーコードで失敗します。GetLastError()をチェックすると(現在どのエラーコードが返されるかは覚えていません)、メッセージキューがいっぱいであることが明らかになります。
母鶏のように聞こえるわけではありませんが、API呼び出しからの戻り値を実際に確認する必要があります。しかし、それを超えて、メッセージキューの上限で実行している場合は、とにかくアプリケーションが壊れていると思います。キューがいっぱいになると、アプリケーションは呼吸できなくなります。画面がペイントされず、実行する処理が古くなり、あらゆる種類の悪いことが起こります。これが現在の状況である場合は、その理由を調べる必要があるかもしれません。