2011-06-22 32 views
1

私はAfxBeginThreadを呼び出し、CWinThreadを使用してMFCアプリケーションのUIスレッドをスピンアップします。AfxBeginThread/CWinThreadメッセージポンプがアクティブになるのを待ちますか?

メインスレッドがCWinThread :: InitInstance()関数が返される前に新しいスレッドにPostThreadMessage()を実行しようとすると、PostThreadMessage()はエラーを返します:無効なスレッドハンドルです。

私の推測では、新しいスレッドのメッセージポンプは、InitInstanceが返されるまでセットアップされません。 AfxBeginThreadと私が読んだドキュメントで見たサンプルコードは、この振る舞いを説明したり、スレッドを初期化するのを待つパターンを示したりするのにはうまくいきません。

InitInstanceが返され、スレッドのメッセージポンプがメッセージを受信する準備が整うまで、メインスレッドをブロックする最善の方法は何ですか?

答えて

1

ピーターの答えは、彼は「あなただけのメッセージキューが作成されるのを待つ必要がある」という認識という点で良いです。その啓示により、関連する回答には次のようなリンクが表示されました:WaitForSingleObject returns wait failed due to invalid handleこれはPeterが示唆していることを実行する簡単な方法を示しています。

+0

あなたは正しいです、私の答えは複雑すぎます。私はCWinThreadクラスをもう少し詳しく調べて答える必要がありました。キーポイントは、イベントを通知する前に新しいスレッドでPeekMessage()を呼び出すことです。 InitInstance、OnIdle、およびRunは、これを行うためのすべてのもっともらしい場所です。 –

3

メッセージポンプを待つ必要はありません。メッセージキューが作成されるのを待つだけです。これにより、メッセージポンプは最終的に開始されたときに投稿されたすべてのメッセージを受信します。ここで私はあなたがそれ(エラーチェックは省略)を行うことができると思う方法です:Windowsで

CEvent myEvent; 

CWinThread * myThread = AfxBeginThread(..., CREATE_SUSPENDED); 

QueueUserAPC(MyCallback, *myThread, reintepret_cast<ULONG_PTR>(&myEvent)); 

myThread->Resume(); 

WaitForSingleObject(myEvent, INFINITE); 

、とすぐにスレッドが起動すると、それがどのはそのエントリポイントを呼び出す前に、ユーザーのAPCをキューに入れ実行します。これにより、MFCフレームワークが継承される前に、新しいスレッドのコードに潜入することができます。あなたのAPCコールバックは、次のようになります

VOID CALLBACK MyCallback(ULONG_PTR param) 
{ 
    // Call peek message to force the creation of the thread's message queue. 
    MSG dummy; 

    PeekMessage(&dummy, NULL, 0, 0, PM_NOREMOVE); 

    CEvent * pEvent = reinterpret_cast<CEvent *>(param); 

    pEvent->SetEvent(); 
} 
+0

yikes。私は明日これを試してみるよ。 – Erik

関連する問題