MFC教程(13)-MFC工具条和状态栏(2)
2007-10-04 20:11:26 来源:WEB开发网核心提示:对于工具条,当用户选中某个按钮时(鼠标左键弹起,MFC教程(13)-MFC工具条和状态栏(2)(4),消息是WM_LBUTTONUP),工具条窗口接收到WM_LBUTTONUP消息,在状态条显示工具栏按钮的提示if (((m_dwStyle & CBRS_FLYBY) ||message == WM_LBUTTONDO
对于工具条,当用户选中某个按钮时(鼠标左键弹起,消息是WM_LBUTTONUP),工具条窗口接收到WM_LBUTTONUP消息,该消息不在CControlBar::WindowProc特别处理的消息范围内,于是进行缺省处理,也就是说,把该消息派发给控制条对应的Windows控制的窗口过程处理(即被MFC统一窗口过程所取代的原窗口过程),该窗口过程则把该消息转换成一条命令消息WM_COMMAND,命令ID就是选中按钮对应的ID,然后,发送该命令消息给拥有工具条的边框窗口,导致相应的命令处理函数被调用。
对于对话框工具条,当工具条的某个控制子窗口被选中之后,则产生一条命令通知消息WM_COMMAND,wParam是控制子窗口的ID。CControlBar::WindowProc处理该消息。WindowProc首先调用OnWndMsg把消息发送给对话框工具条或者对话框工具条的基类处理,如果没有被处理的话,则OnWndMsg返回FALSE。接着,WindowPoc把命令消息传递给父窗口(边框窗口)处理。由于工具条的控制窗口的ID对应的是命令ID,所以,这条WM_COMMAND消息传递给边框窗口时,被解释成一个命令消息,相应的命令处理函数被调用。
PreTranslateMessage
CControlBar覆盖PreTranslateMessage函数,主要是为了在光标落在工具条按钮上时显示FLYBY信息,并且让对话框工具条过滤Dialog消息。
BOOL CControlBar::PreTranslateMessage(MSG* pMsg)
{
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
//过滤Tooltip消息
if (CWnd::PreTranslateMessage(pMsg))
return TRUE; //是Tooltip消息,已经被处理
UINT message = pMsg->message;
//控制条的父窗口,对工具条和对话框工具条,总是创建它的边框窗口
CWnd* pOwner = GetOwner();
//必要的话,在状态条显示工具栏按钮的提示
if (((m_dwStyle & CBRS_FLYBY) ||
message == WM_LBUTTONDOWN || message == WM_LBUTTONUP) &&
((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) ||
(message >= WM_NCMOUSEFIRST &&
message <= WM_NCMOUSELAST)))
{
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
//确认鼠标在工具栏的哪个按钮上
CPoint point = pMsg->pt;
ScreenToClient(&point);
TOOLINFO ti; memset(&ti, 0, sizeof(TOOLINFO));
ti.cbSize = sizeof(TOOLINFO);
int nHit = OnToolHitTest(point, &ti);
if (ti.lpszText != LPSTR_TEXTCALLBACK)
free(ti.lpszText);
BOOL bNotButton =
message == WM_LBUTTONDOWN && (ti.uFlags & TTF_NOTBUTTON);
if (message != WM_LBUTTONDOWN && GetKeyState(VK_LBUTTON) < 0)
nHit = pThreadState->m_nLastStatus;
//更新状态栏的提示信息
if (nHit < 0 || bNotButton)
{
if (GetKeyState(VK_LBUTTON) >= 0 || bNotButton)
{
SetStatusText(-1);
KillTimer(ID_TIMER_CHECK);
}
}
else
{
if (message == WM_LBUTTONUP)
{
SetStatusText(-1);
ResetTimer(ID_TIMER_CHECK, 200);
}
else
{
if ((m_nStateFlags & statusSet) || GetKeyState(VK_LBUTTON) < 0)
SetStatusText(nHit);
else if (nHit != pThreadState->m_nLastStatus)
ResetTimer(ID_TIMER_WAIT, 300);
}
}
pThreadState->m_nLastStatus = nHit;
}
// don't translate dialog messages when in Shift+F1 help mode
CFrameWnd* pFrameWnd = GetTopLevelFrame();
if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
return FALSE;
//在IsDialogMessage之前调用边框窗口的PreTranslateMessage,
//给边框窗口一个处理快捷键的机会
while (pOwner != NULL)
{
// allow owner & frames to translate before IsDialogMessage does
if (pOwner->PreTranslateMessage(pMsg))
return TRUE;
// try parent frames until there are no parent frames
pOwner = pOwner->GetParentFrame();
}
//过滤给对话框的消息和来自子窗口的消息
return PreTranslateInput(pMsg);
}
函数PreTranslateMessage主要是针对工具栏的,用来处理工具栏的CBRS_FLYBY特征。
更多精彩
赞助商链接