2011-06-22 41 views
1

我打电话给AfxBeginThread并使用CWinThread在我的MFC应用程序中创建一个UI线程。我注意到如果我的主线程在CWinThread :: InitInstance()函数返回之前试图将PostThreadMessage()传递给我的新线程,那么PostThreadMessage()将返回错误:无效的线程句柄。等待AfxBeginThread/CWinThread消息泵处于活动状态?

我的猜测是,直到InitInstance返回后,新线程上的消息泵才会设置。我见过的关于AfxBeginThread的示例代码和我读过的文档没有很好地解释这种行为,或者显示了一个模式来等待线程被初始化。

在InitInstance返回并且线程的消息泵准备好接收消息之前阻塞我的主线程的最好方法是什么?

回答

1

彼得的回答是,他认识到,“你只需要等待要创建的消息队列”好。这个启示导致下面的链接出现在相关的答案中:WaitForSingleObject returns wait failed due to invalid handle,这表明了一种更简单的方式来做彼得建议。

+0

你说得对,我的回答太复杂了。在回答之前,我应该多研究一下CWinThread类。关键点是在发信号通知事件之前在新线程上调用PeekMessage()。 InitInstance,OnIdle和Run都是可行的。 –

3

你并不需要等待消息泵。你只需要等待消息队列的创建。这样,消息泵在终于启动时将收到所有发布的消息。这里有一个方式,我认为你可以做到这一点(检查省略错误):

CEvent myEvent; 

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

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

myThread->Resume(); 

WaitForSingleObject(myEvent, INFINITE); 

在Windows中,只要一个线程启动时,它运行调用它的入口点之前任何排队的用户装甲运兵车。所以这可以让你在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

相关问题