BOOL CToolbarHelper::ProcessMessage(MSG* pMsg) { if (!IsWindowEnabled() || !m_pToolbar->IsWindowEnabled()) { return FALSE; } // see if key press matches any hotkey if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam != VK_MENU && Misc::KeyIsPressed(VK_MENU)) { int nKey = (int)pMsg->wParam; char cLower = 0, cUpper = 0; if (islower(nKey)) { cLower = (char)nKey; cUpper = (char)toupper(nKey); } else if (isupper(nKey)) { cUpper = (char)nKey; cLower = (char)tolower(nKey); } else { cUpper = cLower = (char)nKey; } // iterate the buttons the hard way POSITION pos = m_mapTHButtons.GetStartPosition(); while (pos) { THButton dm; UINT nCmdID = 0; m_mapTHButtons.GetNextAssoc(pos, nCmdID, dm); if (nCmdID && (dm.cHotKey == cLower || dm.cHotKey == cUpper)) { DisplayDropMenu(nCmdID, TRUE); return TRUE; } } } return FALSE; }
LRESULT CToolbarHelper::WindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_NOTIFY: { LPNMHDR pNMHDR = (LPNMHDR)lp; switch (pNMHDR->code) { case TBN_DROPDOWN: // check its our toolbar if (pNMHDR->hwndFrom == m_pToolbar->GetSafeHwnd()) { // load the menu LPNMTOOLBAR pNMTB = (LPNMTOOLBAR)pNMHDR; if (DisplayDropMenu((UINT)pNMTB->iItem)) return FALSE; // we handled it } break; #ifndef _UNICODE case TTN_NEEDTEXTA: #else case TTN_NEEDTEXTW: #endif { // to be thorough we will need to handle UNICODE versions of the message also !! TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR; // only handle this if it's not already been done if (pTTT->lpszText && *(pTTT->lpszText)) break; UINT nID = pNMHDR->idFrom; if (pTTT->uFlags & TTF_IDISHWND) // idFrom is actually the HWND of the tool nID = ::GetDlgCtrlID((HWND)nID); // get cursor pos CPoint point(::GetMessagePos()); m_pToolbar->ScreenToClient(&point); // get tip static CString sTipText; sTipText = GetTip(nID, &point); if (!sTipText.IsEmpty()) // will be zero on a separator { pTTT->lpszText = (LPTSTR)(LPCTSTR)sTipText; return TRUE; } } break; case TTN_SHOW: { CWnd* pTooltipCtrl = CWnd::FromHandle(pNMHDR->hwndFrom); ASSERT (pTooltipCtrl); pTooltipCtrl->SendMessage(TTM_SETMAXTIPWIDTH, 0, (m_bMultiline ? m_nMultilineWidth : UINT_MAX)); if (m_pShortcutMgr) { static UINT nIDLastShow = 0; UINT nCmdID = pNMHDR->idFrom; // prevent re-entrancy on same tip if (nCmdID != nIDLastShow) { TOOLINFO ti = { 0 }; ti.cbSize = sizeof(ti); ti.hwnd = *m_pToolbar; // restore callback on last shown item if (nIDLastShow) { ti.uId = nIDLastShow; pTooltipCtrl->SendMessage(TTM_GETTOOLINFO, 0, (LPARAM)&ti); ti.lpszText = LPSTR_TEXTCALLBACK; pTooltipCtrl->SendMessage(TTM_SETTOOLINFO, 0, (LPARAM)&ti); nIDLastShow = 0; } // append shortcut text to new item THButton dm = { 0 }; if (m_mapTHButtons.Lookup(nCmdID, dm)) { if (dm.nDefCmdID) nCmdID = dm.nDefCmdID; } CString sShortcut = m_pShortcutMgr->GetShortcutTextByCmd(nCmdID); if (!sShortcut.IsEmpty()) { // store original id immediately to prevent re-entrancy nIDLastShow = pNMHDR->idFrom; const int TIP_LEN = 80; TCHAR szTip[TIP_LEN] = { 0 }; ti.lpszText = szTip; ti.hwnd = *m_pToolbar; ti.uId = pNMHDR->idFrom; pTooltipCtrl->SendMessage(TTM_GETTEXT, TIP_LEN, (LPARAM)&ti); CString sTip; sTip.Format(_T("%s (%s)"), szTip, sShortcut); ti.lpszText = (LPTSTR)(LPCTSTR)sTip; pTooltipCtrl->SendMessage(TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); pTooltipCtrl->SendMessage(TTM_UPDATE); } } } } break; } } break; case WM_COMMAND: { HWND hCtrlFrom = (HWND)lp; // if m_pToolbar sent the command and we have a mapping for it then // change it to the default cmd for that button if (hCtrlFrom == *m_pToolbar) { THButton dm = { 0 }; UINT nCmdID = LOWORD(wp); if (m_mapTHButtons.Lookup(nCmdID, dm)) { // if we have an enabled default command then send it if (dm.nDefCmdID && IsCmdEnabled(dm.nDefCmdID)) { wp = MAKEWPARAM(dm.nDefCmdID, HIWORD(wp)); } else { BOOL bRes = DisplayDropMenu(nCmdID, TRUE); if (bRes) return 0L; // we handled it } } } } break; case WM_DESTROY: { // must call rest of chain first LRESULT lr = CSubclassWnd::WindowProc(hRealWnd, msg, wp, lp); HookWindow(NULL); return lr; } } return CSubclassWnd::WindowProc(hRealWnd, msg, wp, lp); }
LRESULT CToolbarHelper::WindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_NOTIFY: { LPNMHDR pNMHDR = (LPNMHDR)lp; switch (pNMHDR->code) { case TBN_DROPDOWN: // check its our toolbar if (pNMHDR->hwndFrom == m_pToolbar->GetSafeHwnd()) { // load the menu LPNMTOOLBAR pNMTB = (LPNMTOOLBAR)pNMHDR; if (DisplayDropMenu((UINT)pNMTB->iItem)) { return FALSE; // we handled it } } break; case TTN_NEEDTEXT: { // to be thorough we will need to handle UNICODE versions of the message also !! TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR; UINT nID = pNMHDR->idFrom; if (pTTT->uFlags & TTF_IDISHWND) // idFrom is actually the HWND of the tool { nID = ::GetDlgCtrlID((HWND)nID); } // get cursor pos CPoint point(::GetMessagePos()); m_pToolbar->ScreenToClient(&point); // get tip static CString sTipText; sTipText = GetTip(nID, &point); if (!sTipText.IsEmpty()) // will be zero on a separator { pTTT->lpszText = (LPTSTR)(LPCTSTR)sTipText; return TRUE; } } break; case TTN_SHOW: { CWnd* pTooltipCtrl = CWnd::FromHandle(pNMHDR->hwndFrom); ASSERT(pTooltipCtrl); pTooltipCtrl->SendMessage(TTM_SETMAXTIPWIDTH, 0, m_bMultiline ? m_nMultilineWidth : UINT_MAX); } break; } } break; case WM_COMMAND: { HWND hCtrlFrom = (HWND)lp; // if m_pToolbar sent the command and we have a mapping for it then // change it to the default cmd for that button if (hCtrlFrom == *m_pToolbar) { THButton dm; UINT nCmdID = LOWORD(wp); if (m_mapTHButtons.Lookup(nCmdID, dm)) { // if we have an enabled default command then send it if (dm.nDefCmdID && IsCmdEnabled(dm.nDefCmdID)) { wp = MAKEWPARAM(dm.nDefCmdID, HIWORD(wp)); } else { BOOL bRes = DisplayDropMenu(nCmdID, TRUE); if (bRes) { return 0L; // we handled it } } } } } break; case WM_KICKIDLE: break; case WM_DESTROY: { // must call rest of chain first LRESULT lr = CSubclassWnd::WindowProc(hRealWnd, msg, wp, lp); HookWindow(NULL); return lr; } } return CSubclassWnd::WindowProc(hRealWnd, msg, wp, lp); }