1
votes

I'm calling AfxBeginThread and using CWinThread to spin up a UI thread in my MFC app.

I've noticed that if my main thread tries to PostThreadMessage() to my new thread before the CWinThread::InitInstance() function returns, then PostThreadMessage() will return the error: invalid thread handle.

My guess is that the message pump on the new thread isn't setup until after InitInstance returns. The example code I've seen for AfxBeginThread and the documentation I've read don't do a good job of explaining this behavior, or show a pattern to wait for the thread to be initialized.

What's the best way of blocking my main thread until InitInstance has returned and the thread's message pump is ready to receive messages?

2

2 Answers

4
votes

You don't really need to wait for the message pump. You just need to wait for the message queue to be created. That way, the message pump will receive all posted messages when it finally starts. Here's a way I think you could do it (error checking omitted):

CEvent myEvent;

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

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

myThread->Resume();

WaitForSingleObject( myEvent, INFINITE );

In windows, as soon as a thread starts, it runs any queued user APCs before calling its entry point. So this lets you sneak in some code on the new thread before the MFC framework takes over. Your APC callback would look something like this:

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();
}
1
votes

Peter's answer is good in that he recognized that "you just need to wait for the message queue to be created". That revelation caused the following link to show up in the related answers: WaitForSingleObject returns wait failed due to invalid handle, which demonstrates an easier way to do what Peter suggests.