MFC函数

void AFXAPI AfxInitThread()
{
    if (!afxContextIsDLL)
    {
        // set message filter proc
        _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
        ASSERT(pThreadState->m_hHookOldMsgFilter == NULL);
        pThreadState->m_hHookOldMsgFilter = ::SetWindowsHookEx(WH_MSGFILTER,
            _AfxMsgFilterHook, NULL, ::GetCurrentThreadId());

#ifndef _AFX_NO_CTL3D_SUPPORT
        // intialize CTL3D for this thread
        _AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState;
        if (pCtl3dState->m_pfnAutoSubclass != NULL)
            (*pCtl3dState->m_pfnAutoSubclass)(AfxGetInstanceHandle());

        // allocate thread local _AFX_CTL3D_THREAD just for automatic termination
        _AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread;
        pTemp;  // avoid unused warning
#endif
    }
}

LRESULT CALLBACK _AfxMsgFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
    CWinThread* pThread;
    if (afxContextIsDLL || (code < 0 && code != MSGF_DDEMGR) ||
        (pThread = AfxGetThread()) == NULL)
    {
        return ::CallNextHookEx(_afxThreadState->m_hHookOldMsgFilter,
            code, wParam, lParam);
    }
    ASSERT(pThread != NULL);
    return (LRESULT)pThread->ProcessMessageFilter(code, (LPMSG)lParam);
}

BOOL CWinThread::ProcessMessageFilter(int code, LPMSG lpMsg)
{
    if (lpMsg == NULL)
        return FALSE;   // not handled

    CFrameWnd* pTopFrameWnd;
    CWnd* pMainWnd;
    CWnd* pMsgWnd;
    switch (code)
    {
    case MSGF_DDEMGR:
        // Unlike other WH_MSGFILTER codes, MSGF_DDEMGR should
        //  never call the next hook.
        // By returning FALSE, the message will be dispatched
        //  instead (the default behavior).
        return FALSE;

    case MSGF_MENU:
        pMsgWnd = CWnd::FromHandle(lpMsg->hwnd);
        if (pMsgWnd != NULL)
        {
            pTopFrameWnd = pMsgWnd->GetTopLevelFrame();
            if (pTopFrameWnd != NULL && pTopFrameWnd->IsTracking() &&
                pTopFrameWnd->m_bHelpMode)
            {
                pMainWnd = AfxGetMainWnd();
                if ((m_pMainWnd != NULL) && (IsEnterKey(lpMsg) || IsButtonUp(lpMsg)))
                {
                    pMainWnd->SendMessage(WM_COMMAND, ID_HELP);
                    return TRUE;
                }
            }
        }
        // fall through...

    case MSGF_DIALOGBOX:    // handles message boxes as well.
        pMainWnd = AfxGetMainWnd();
        if (afxData.nWinVer < 0x333 && pMainWnd != NULL && IsHelpKey(lpMsg))
        {
            pMainWnd->SendMessage(WM_COMMAND, ID_HELP);
            return TRUE;
        }
        if (code == MSGF_DIALOGBOX && m_pActiveWnd != NULL &&
            lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST)
        {
            // need to translate messages for the in-place container
            _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
            if (pThreadState->m_bInMsgFilter)
                return FALSE;
            pThreadState->m_bInMsgFilter = TRUE;    // avoid reentering this code
            MSG msg = *lpMsg;
            if (m_pActiveWnd->IsWindowEnabled() && PreTranslateMessage(&msg))
            {
                pThreadState->m_bInMsgFilter = FALSE;
                return TRUE;
            }
            pThreadState->m_bInMsgFilter = FALSE;    // ok again
        }
        break;
    }

    return FALSE;   // default to not handled
}
extern CThreadSlotData* _afxThreadData;
void AFXAPI AfxTermThread(HINSTANCE hInstTerm)
{
    try
    {
#ifdef _DEBUG
        // check for missing AfxLockTempMap calls
        if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
        {
            TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
                AfxGetModuleThreadState()->m_nTempMapLock);
        }
#endif
        AfxLockTempMaps();
        AfxUnlockTempMaps(-1);

        // cleanup thread local tooltip window
        if (hInstTerm == NULL)
        {
            _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetDataNA();
            if ((pThreadState != NULL) &&
                (pThreadState->m_pToolTip != NULL))
            {
                pThreadState->m_pToolTip->DestroyWindow();
                delete pThreadState->m_pToolTip;
                pThreadState->m_pToolTip=NULL;
            }
        }

        // cleanup the rest of the thread local data
        if (_afxThreadData != NULL)
            _afxThreadData->DeleteValues(hInstTerm, FALSE);
    }
    catch( CException* e )
    {
        e->Delete();
    }
}

posted on 2011-09-01 08:43  我要穿越  阅读(333)  评论(0编辑  收藏  举报

导航