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);
}
AFX_STATIC BOOL AFXAPI IsHelpKey(LPMSG lpMsg)
// return TRUE only for non-repeat F1 keydowns.
{
return lpMsg->message == WM_KEYDOWN &&
lpMsg->wParam == VK_F1 &&
!(HIWORD(lpMsg->lParam) & KF_REPEAT) &&
GetKeyState(VK_SHIFT) >= 0 &&
GetKeyState(VK_CONTROL) >= 0 &&
GetKeyState(VK_MENU) >= 0;
}
AFX_STATIC inline BOOL IsEnterKey(LPMSG lpMsg)
{ return lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_RETURN; }
AFX_STATIC inline BOOL IsButtonUp(LPMSG lpMsg)
{ return lpMsg->message == WM_LBUTTONUP; }
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 (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();
ENSURE(pThreadState);
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
}
/////////////////////////////////////////////////////////////////////////////
// Access to m_pMainWnd & m_pActiveWnd
CWnd* CWinThread::GetMainWnd()
{
if (m_pActiveWnd != NULL)
return m_pActiveWnd; // probably in-place active
// when not inplace active, just return main window
if (m_pMainWnd != NULL)
return m_pMainWnd;
return CWnd::GetActiveWindow();
}
/////////////////////////////////////////////////////////////////////////////
// CWinThread implementation helpers
BOOL CWinThread::PumpMessage()
{
return AfxInternalPumpMessage();
}
/////////////////////////////////////////////////////////////////////////////
// CWinThread diagnostics
#ifdef _DEBUG
void CWinThread::AssertValid() const
{
CCmdTarget::AssertValid();
}
void CWinThread::Dump(CDumpContext& dc) const
{
CCmdTarget::Dump(dc);
_AFX_THREAD_STATE *pState = AfxGetThreadState();
dc << "m_pThreadParams = " << m_pThreadParams;
dc << "\nm_pfnThreadProc = " << (void*)m_pfnThreadProc;
dc << "\nm_bAutoDelete = " << m_bAutoDelete;
dc << "\nm_hThread = " << (void*)m_hThread;
dc << "\nm_nThreadID = " << m_nThreadID;
dc << "\nm_nDisablePumpCount = " << pState->m_nDisablePumpCount;
if (AfxGetThread() == this)
dc << "\nm_pMainWnd = " << m_pMainWnd;
dc << "\nm_msgCur = {";
dc << "\n\thwnd = " << (void*)pState->m_msgCur.hwnd;
dc << "\n\tmessage = " << (UINT)pState->m_msgCur.message;
dc << "\n\twParam = " << (UINT)pState->m_msgCur.wParam;
dc << "\n\tlParam = " << (void*)pState->m_msgCur.lParam;
dc << "\n\ttime = " << pState->m_msgCur.time;
dc << "\n\tpt = " << CPoint(pState->m_msgCur.pt);
dc << "\n}";
dc << "\nm_pThreadParams = " << m_pThreadParams;
dc << "\nm_pfnThreadProc = " << (void*)m_pfnThreadProc;
dc << "\nm_ptCursorLast = " << pState->m_ptCursorLast;
dc << "\nm_nMsgLast = " << pState->m_nMsgLast;
dc << "\n";
}
#endif
IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget)
评论0