查看源文件 Appcore.cpp Thrdcore.cpp

解决方案 »

  1.   

    CWinThread 有自己的消息循环, 和工作者线程不同
      

  2.   

    // simplified from CWinThread 
    while (GetMessage(...)) { 
        if (PreTranslateMessage(...)) { 
            // continue looping 
        } else { 
            TranslateMessage(...); 
            DispatchMessage(...); 
        }
      

  3.   

    CWinThread创建线程有自己的线程函数(如下),由该函数来调用类的各个虚函数,编程时自己重载相应的函数。
    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();
    pThread->m_pModuleState = pModuleState;
    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
    }