Minor cleanup
[TortoiseGit.git] / src / Utils / MiscUI / Tooltip.cpp
blob06d78835549a9370f389c37c638b74421b661d46
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2011 - Sven Strickroth <email@cs-ware.de>
4 // Copyright (C) 2008-2012 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "stdafx.h"
22 #include "Tooltip.h"
25 BEGIN_MESSAGE_MAP(CToolTips, CToolTipCtrl)
26 ON_NOTIFY_REFLECT_EX( TTN_NEEDTEXT, &CToolTips::OnTtnNeedText )
27 END_MESSAGE_MAP()
31 BOOL CToolTips::OnTtnNeedText(NMHDR *pNMHDR, LRESULT *pResult)
33 if (pNMHDR->code == TTN_NEEDTEXTW)
35 LPNMTTDISPINFO lpnmtdi = (LPNMTTDISPINFO)pNMHDR;
36 UINT_PTR nID = pNMHDR->idFrom;
38 if (lpnmtdi->uFlags & TTF_IDISHWND)
40 // idFrom is actually the HWND of the tool
41 nID = ::GetDlgCtrlID((HWND)nID);
44 auto iterFind = toolTextMap.find((unsigned int)nID);
45 if (iterFind != toolTextMap.end())
47 lpnmtdi->lpszText = (LPTSTR)(LPCTSTR)iterFind->second;
48 lpnmtdi->hinst = AfxGetResourceHandle();
49 *pResult = 0;
50 return TRUE;
53 return FALSE;
56 BOOL CToolTips::AddTool(CWnd* pWnd, UINT nIDText, LPCRECT lpRectTool /* = NULL */, UINT_PTR nIDTool /* = 0 */)
58 CString sTemp = LoadTooltip(nIDText);
59 toolTextMap[::GetDlgCtrlID(pWnd->GetSafeHwnd())] = sTemp;
60 return CToolTipCtrl::AddTool(pWnd, LPSTR_TEXTCALLBACK, lpRectTool, nIDTool);
63 BOOL CToolTips::AddTool(CWnd* pWnd, LPCTSTR lpszText /* = LPSTR_TEXTCALLBACK */, LPCRECT lpRectTool /* = NULL */, UINT_PTR nIDTool /* = 0 */)
65 if (lpszText != LPSTR_TEXTCALLBACK)
66 toolTextMap[::GetDlgCtrlID(pWnd->GetSafeHwnd())] = CString(lpszText);
67 return CToolTipCtrl::AddTool(pWnd, lpszText, lpRectTool, nIDTool);
70 void CToolTips::AddTool(int nIdWnd, UINT nIdText, LPCRECT lpRectTool /* = NULL */, UINT_PTR nIDTool /* = 0 */)
72 AddTool(((CDialog*)m_pParentWnd)->GetDlgItem(nIdWnd), nIdText, lpRectTool, nIDTool);
75 void CToolTips::AddTool(int nIdWnd, CString sBalloonTipText, LPCRECT lpRectTool /* = NULL */, UINT_PTR nIDTool /* = 0 */)
77 AddTool(((CDialog*)m_pParentWnd)->GetDlgItem(nIdWnd), sBalloonTipText, lpRectTool, nIDTool);
80 void CToolTips::DelTool( CWnd* pWnd, UINT_PTR nIDTool /* = 0 */)
82 toolTextMap.erase(::GetDlgCtrlID(pWnd->GetSafeHwnd()));
83 return CToolTipCtrl::DelTool(pWnd, nIDTool);
86 void CToolTips::DelTool( int nIdWnd, UINT_PTR nIDTool /* = 0 */)
88 return DelTool(((CDialog*)m_pParentWnd)->GetDlgItem(nIdWnd), nIDTool);
91 BOOL CToolTips::ShowBalloon(CWnd *pWnd, UINT nIDText, UINT nIDTitle, UINT icon /* = 0 */)
93 CString sTemp = LoadTooltip(nIDText);
95 const HWND hwndTT = CreateWindow
97 TOOLTIPS_CLASS,
98 _T(""),
99 TTS_NOPREFIX|TTS_BALLOON|TTS_ALWAYSTIP|TTS_CLOSE,
100 CW_USEDEFAULT, CW_USEDEFAULT,
101 CW_USEDEFAULT, CW_USEDEFAULT,
102 pWnd->GetSafeHwnd(),
103 NULL,
104 NULL,
105 NULL
107 if (hwndTT == NULL)
108 return FALSE;
110 TOOLINFO ti = { 0 };
111 ti.cbSize = sizeof(ti);
112 ti.uFlags = TTF_TRACK | TTF_IDISHWND | TTF_PARSELINKS;
113 ti.hwnd = pWnd->GetSafeHwnd();
114 ti.lpszText = sTemp.GetBuffer();
115 ::SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM)&ti);
116 ::SendMessage(hwndTT, TTM_SETTITLE, icon, (LPARAM)(LPCTSTR)CString(MAKEINTRESOURCE(nIDTitle)));
117 ::SendMessage(hwndTT, TTM_SETMAXTIPWIDTH, 0, 800);
119 // Position the tooltip below the control
120 RECT rc;
121 ::GetWindowRect(pWnd->GetSafeHwnd(), &rc);
122 ::SendMessage(hwndTT, TTM_TRACKPOSITION, 0, MAKELONG(rc.left + 10, rc.bottom));
124 // Show the tooltip
125 ::SendMessage(hwndTT, TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti);
127 return TRUE;
130 void CToolTips::ShowBalloon(int nIdWnd, UINT nIdText, UINT nIDTitle, UINT icon /* = 0 */)
132 ShowBalloon(((CDialog*)m_pParentWnd)->GetDlgItem(nIdWnd), nIdText, nIDTitle, icon);
135 CString CToolTips::LoadTooltip( UINT nIDText )
137 CString sTemp;
138 sTemp.LoadString(nIDText);
139 // tooltips can't handle \t and single \n, only spaces and \r\n
140 sTemp.Replace('\t', ' ');
141 sTemp.Replace(_T("\r\n"), _T("\n"));
142 sTemp.Replace(_T("\n"), _T("\r\n"));
143 return sTemp;
146 void CToolTips::RelayEvent(LPMSG lpMsg, CWnd * dlgWnd)
148 if (lpMsg->message == WM_NULL)
149 return;
151 if(dlgWnd && ((lpMsg->message == WM_MOUSEMOVE) || (lpMsg->message == WM_NCMOUSEMOVE)) && (lpMsg->hwnd == dlgWnd->m_hWnd))
153 // allow tooltips for disabled controls
154 CRect rect;
155 POINT pt;
157 pt.x = LOWORD(lpMsg->lParam);
158 pt.y = HIWORD(lpMsg->lParam);
160 for (auto it = toolTextMap.cbegin(); it != toolTextMap.cend(); ++it)
162 CWnd * pWndCtrl = dlgWnd->GetDlgItem(it->first);
163 pWndCtrl->GetWindowRect(&rect);
164 if (lpMsg->message == WM_MOUSEMOVE)
165 dlgWnd->ScreenToClient(&rect);
167 if(rect.PtInRect(pt) )
169 // save the original parameters
170 HWND origHwnd = lpMsg->hwnd;
171 LPARAM origLParam = lpMsg->lParam;
173 // translate and relay the mouse move message to
174 // the tooltip control as if they were sent
175 // by the disabled control
176 lpMsg->hwnd = pWndCtrl->m_hWnd;
178 if (lpMsg->message == WM_MOUSEMOVE)
179 dlgWnd->ClientToScreen(&pt);
180 pWndCtrl->ScreenToClient(&pt);
181 lpMsg->lParam = MAKELPARAM(pt.x, pt.y);
183 __super::RelayEvent(lpMsg);
185 // restore the original parameters
186 lpMsg->hwnd = origHwnd;
187 lpMsg->lParam = origLParam;
188 return;
193 // Let the ToolTip process this message.
194 __super::RelayEvent(lpMsg);