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.
25 BEGIN_MESSAGE_MAP(CToolTips
, CToolTipCtrl
)
26 ON_NOTIFY_REFLECT_EX( TTN_NEEDTEXT
, &CToolTips::OnTtnNeedText
)
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
);
43 if (toolTextMap
.find((unsigned int)nID
) != toolTextMap
.end())
45 lpnmtdi
->lpszText
= (LPTSTR
)(LPCTSTR
)(CString
)toolTextMap
[(unsigned int)nID
];
46 lpnmtdi
->hinst
= AfxGetResourceHandle();
54 BOOL
CToolTips::AddTool(CWnd
* pWnd
, UINT nIDText
, LPCRECT lpRectTool
/* = NULL */, UINT_PTR nIDTool
/* = 0 */)
56 CString sTemp
= LoadTooltip(nIDText
);
57 toolTextMap
[::GetDlgCtrlID(pWnd
->GetSafeHwnd())] = sTemp
;
58 return CToolTipCtrl::AddTool(pWnd
, LPSTR_TEXTCALLBACK
, lpRectTool
, nIDTool
);
61 BOOL
CToolTips::AddTool(CWnd
* pWnd
, LPCTSTR lpszText
/* = LPSTR_TEXTCALLBACK */, LPCRECT lpRectTool
/* = NULL */, UINT_PTR nIDTool
/* = 0 */)
63 if (lpszText
!= LPSTR_TEXTCALLBACK
)
64 toolTextMap
[::GetDlgCtrlID(pWnd
->GetSafeHwnd())] = CString(lpszText
);
65 return CToolTipCtrl::AddTool(pWnd
, lpszText
, lpRectTool
, nIDTool
);
68 void CToolTips::AddTool(int nIdWnd
, UINT nIdText
, LPCRECT lpRectTool
/* = NULL */, UINT_PTR nIDTool
/* = 0 */)
70 AddTool(((CDialog
*)m_pParentWnd
)->GetDlgItem(nIdWnd
), nIdText
, lpRectTool
, nIDTool
);
73 void CToolTips::AddTool(int nIdWnd
, CString sBalloonTipText
, LPCRECT lpRectTool
/* = NULL */, UINT_PTR nIDTool
/* = 0 */)
75 AddTool(((CDialog
*)m_pParentWnd
)->GetDlgItem(nIdWnd
), sBalloonTipText
, lpRectTool
, nIDTool
);
78 void CToolTips::DelTool( CWnd
* pWnd
, UINT_PTR nIDTool
/* = 0 */)
80 toolTextMap
.erase(::GetDlgCtrlID(pWnd
->GetSafeHwnd()));
81 return CToolTipCtrl::DelTool(pWnd
, nIDTool
);
84 void CToolTips::DelTool( int nIdWnd
, UINT_PTR nIDTool
/* = 0 */)
86 return DelTool(((CDialog
*)m_pParentWnd
)->GetDlgItem(nIdWnd
), nIDTool
);
89 BOOL
CToolTips::ShowBalloon(CWnd
*pWnd
, UINT nIDText
, UINT nIDTitle
, UINT icon
/* = 0 */)
91 CString sTemp
= LoadTooltip(nIDText
);
93 const HWND hwndTT
= CreateWindow
97 TTS_NOPREFIX
|TTS_BALLOON
|TTS_ALWAYSTIP
|TTS_CLOSE
,
98 CW_USEDEFAULT
, CW_USEDEFAULT
,
99 CW_USEDEFAULT
, CW_USEDEFAULT
,
109 ti
.cbSize
= sizeof(ti
);
110 ti
.uFlags
= TTF_TRACK
| TTF_IDISHWND
| TTF_PARSELINKS
;
111 ti
.hwnd
= pWnd
->GetSafeHwnd();
112 ti
.lpszText
= sTemp
.GetBuffer();
113 ::SendMessage(hwndTT
, TTM_ADDTOOL
, 0, (LPARAM
)&ti
);
114 ::SendMessage(hwndTT
, TTM_SETTITLE
, icon
, (LPARAM
)(LPCTSTR
)CString(MAKEINTRESOURCE(nIDTitle
)));
115 ::SendMessage(hwndTT
, TTM_SETMAXTIPWIDTH
, 0, 800);
117 // Position the tooltip below the control
119 ::GetWindowRect(pWnd
->GetSafeHwnd(), &rc
);
120 ::SendMessage(hwndTT
, TTM_TRACKPOSITION
, 0, MAKELONG(rc
.left
+ 10, rc
.bottom
));
123 ::SendMessage(hwndTT
, TTM_TRACKACTIVATE
, TRUE
, (LPARAM
)&ti
);
128 void CToolTips::ShowBalloon(int nIdWnd
, UINT nIdText
, UINT nIDTitle
, UINT icon
/* = 0 */)
130 ShowBalloon(((CDialog
*)m_pParentWnd
)->GetDlgItem(nIdWnd
), nIdText
, nIDTitle
, icon
);
133 CString
CToolTips::LoadTooltip( UINT nIDText
)
136 sTemp
.LoadString(nIDText
);
137 // tooltips can't handle \t and single \n, only spaces and \r\n
138 sTemp
.Replace('\t', ' ');
139 sTemp
.Replace(_T("\r\n"), _T("\n"));
140 sTemp
.Replace(_T("\n"), _T("\r\n"));
144 void CToolTips::RelayEvent(LPMSG lpMsg
, CWnd
* dlgWnd
)
146 if(dlgWnd
&& ((lpMsg
->message
== WM_MOUSEMOVE
) || (lpMsg
->message
== WM_NCMOUSEMOVE
)) && (lpMsg
->hwnd
== dlgWnd
->m_hWnd
))
148 // allow tooltips for disabled controls
152 pt
.x
= LOWORD(lpMsg
->lParam
);
153 pt
.y
= HIWORD(lpMsg
->lParam
);
155 for (std::map
<UINT
, CString
>::iterator it
= toolTextMap
.begin(); it
!= toolTextMap
.end(); ++it
)
157 CWnd
* pWndCtrl
= dlgWnd
->GetDlgItem(it
->first
);
158 pWndCtrl
->GetWindowRect(&rect
);
159 if (lpMsg
->message
== WM_MOUSEMOVE
)
160 dlgWnd
->ScreenToClient(&rect
);
162 if(rect
.PtInRect(pt
) )
164 // save the original parameters
165 HWND origHwnd
= lpMsg
->hwnd
;
166 LPARAM origLParam
= lpMsg
->lParam
;
168 // translate and relay the mouse move message to
169 // the tooltip control as if they were sent
170 // by the disabled control
171 lpMsg
->hwnd
= pWndCtrl
->m_hWnd
;
173 if (lpMsg
->message
== WM_MOUSEMOVE
)
174 dlgWnd
->ClientToScreen(&pt
);
175 pWndCtrl
->ScreenToClient(&pt
);
176 lpMsg
->lParam
= MAKELPARAM(pt
.x
, pt
.y
);
178 __super::RelayEvent(lpMsg
);
180 // restore the original parameters
181 lpMsg
->hwnd
= origHwnd
;
182 lpMsg
->lParam
= origLParam
;
188 // Let the ToolTip process this message.
189 __super::RelayEvent(lpMsg
);