C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\thrdcore.cpp
UINT APIENTRY _AfxThreadEntry(void* pParam)
{
_AFX_THREAD_STARTUP* pStartup = (_AFX_THREAD_STARTUP*)pParam;
ASSERT(pStartup != NULL);
ASSERT(pStartup->pThreadState != NULL);
ASSERT(pStartup->pThread != NULL);
ASSERT(pStartup->hEvent != NULL);
ASSERT(!pStartup->bError);
CWinThread* pThread = pStartup->pThread;
CWnd threadWnd;
TRY
{
// inherit parent's module state
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
pThreadState->m_pModuleState = pStartup->pThreadState->m_pModuleState;
// set current thread pointer for AfxGetThread
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
#ifdef _AFXDLL
pThread->m_pModuleState = pModuleState;
#endif
AFX_MODULE_THREAD_STATE* pState = pModuleState->m_thread;
pState->m_pCurrentWinThread = pThread;
// forced initialization of the thread
AfxInitThread();
// thread inherits app's main window if not already set
CWinApp* pApp = AfxGetApp();
if (pApp != NULL &&
pThread->m_pMainWnd == NULL && pApp->m_pMainWnd->GetSafeHwnd() != NULL)
{
// just attach the HWND
threadWnd.Attach(pApp->m_pMainWnd->m_hWnd);
pThread->m_pMainWnd = &threadWnd;
}
}
CATCH_ALL(e)
{
// Note: DELETE_EXCEPTION(e) not required.
// exception happened during thread initialization!!
TRACE(traceAppMsg, 0, "Warning: Error during thread initialization!\n");
// set error flag and allow the creating thread to notice the error
threadWnd.Detach();
pStartup->bError = TRUE;
VERIFY(::SetEvent(pStartup->hEvent));
AfxEndThread((UINT)-1, FALSE);
ASSERT(FALSE); // unreachable
}
END_CATCH_ALL
// pStartup is invlaid after the following
// SetEvent (but hEvent2 is valid)
HANDLE hEvent2 = pStartup->hEvent2;
// allow the creating thread to return from CWinThread::CreateThread
VERIFY(::SetEvent(pStartup->hEvent));
// wait for thread to be resumed
VERIFY(::WaitForSingleObject(hEvent2, INFINITE) == WAIT_OBJECT_0);
::CloseHandle(hEvent2);
// first -- check for simple worker thread
DWORD nResult = 0;
if (pThread->m_pfnThreadProc != NULL)
{
nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);
ASSERT_VALID(pThread);
}
// else -- check for thread with message loop
else if (!pThread->InitInstance())
{
ASSERT_VALID(pThread);
nResult = pThread->ExitInstance();
}
else
{
// will stop after PostQuitMessage called
ASSERT_VALID(pThread);
nResult = pThread->Run();
}
// cleanup and shutdown the thread
threadWnd.Detach();
AfxEndThread(nResult);
return 0; // not reached
} |