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