Dropped auto_buffer
[TortoiseGit.git] / src / Utils / MiscUI / HyperLink.cpp
blob8188061f3a3c05b4434678ef9c1a47e415b32d69
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2006,2008, 2011 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "HyperLink.h"
21 #include "SmartHandle.h"
22 #include <atlconv.h>
24 #ifdef _DEBUG
25 #define new DEBUG_NEW
26 #undef THIS_FILE
27 static char THIS_FILE[] = __FILE__;
28 #endif
30 #define TOOLTIP_ID 1
33 CHyperLink::CHyperLink()
35 m_hLinkCursor = NULL; // No cursor as yet
36 m_crLinkColor = RGB( 0, 0, 238); // Blue
37 m_crHoverColor = RGB(255, 0, 0); // Red
38 m_bOverControl = FALSE; // Cursor not yet over control
39 m_nUnderline = ulHover; // Underline the link?
40 m_strURL.Empty();
41 m_nTimerID = 100;
44 CHyperLink::~CHyperLink()
46 m_UnderlineFont.DeleteObject();
49 BOOL CHyperLink::DestroyWindow()
51 KillTimer(m_nTimerID);
53 return CStatic::DestroyWindow();
56 BOOL CHyperLink::PreTranslateMessage(MSG* pMsg)
58 m_ToolTip.RelayEvent(pMsg);
59 return CStatic::PreTranslateMessage(pMsg);
63 void CHyperLink::PreSubclassWindow()
65 // Enable notifications - CStatic has this disabled by default
66 DWORD dwStyle = GetStyle();
67 ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
69 // By default use the label text as the URL
70 if (m_strURL.IsEmpty())
71 GetWindowText(m_strURL);
73 CString strWndText;
74 GetWindowText(strWndText);
75 if (strWndText.IsEmpty())
77 SetWindowText(m_strURL);
80 CFont* pFont = GetFont();
81 if (!pFont)
83 HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
84 if (hFont == NULL)
85 hFont = (HFONT) GetStockObject(ANSI_VAR_FONT);
86 if (hFont)
87 pFont = CFont::FromHandle(hFont);
89 ASSERT(pFont->GetSafeHandle());
91 LOGFONT lf;
92 pFont->GetLogFont(&lf);
93 m_StdFont.CreateFontIndirect(&lf);
94 lf.lfUnderline = (BYTE) TRUE;
95 m_UnderlineFont.CreateFontIndirect(&lf);
97 SetDefaultCursor(); // try loading a "hand" cursor
98 SetUnderline();
100 CRect rect;
101 GetClientRect(rect);
102 m_ToolTip.Create(this);
103 m_ToolTip.AddTool(this, m_strURL, rect, TOOLTIP_ID);
105 CStatic::PreSubclassWindow();
108 BEGIN_MESSAGE_MAP(CHyperLink, CStatic)
109 ON_WM_CTLCOLOR_REFLECT()
110 ON_WM_SETCURSOR()
111 ON_WM_MOUSEMOVE()
112 ON_WM_TIMER()
113 ON_WM_ERASEBKGND()
114 ON_CONTROL_REFLECT(STN_CLICKED, OnClicked)
115 END_MESSAGE_MAP()
118 void CHyperLink::OnClicked()
120 if(!m_strURL.IsEmpty())
122 GotoURL(m_strURL);
124 else
126 ::SendMessage(this->GetParent()->m_hWnd,WM_COMMAND,this->GetDlgCtrlID(),0);
130 HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
132 if (m_bOverControl)
133 pDC->SetTextColor(m_crHoverColor);
134 else
135 pDC->SetTextColor(m_crLinkColor);
137 // draw transparent
138 pDC->SetBkMode(TRANSPARENT);
139 return (HBRUSH)GetStockObject(NULL_BRUSH);
142 void CHyperLink::OnMouseMove(UINT nFlags, CPoint point)
144 if (!m_bOverControl)
146 m_bOverControl = TRUE;
148 if (m_nUnderline == ulHover)
149 SetFont(&m_UnderlineFont);
150 Invalidate();
152 SetTimer(m_nTimerID, 100, NULL);
154 CStatic::OnMouseMove(nFlags, point);
157 void CHyperLink::OnTimer(UINT_PTR nIDEvent)
159 CPoint p(GetMessagePos());
160 ScreenToClient(&p);
162 CRect rect;
163 GetClientRect(rect);
164 if (!rect.PtInRect(p))
166 m_bOverControl = FALSE;
167 KillTimer(m_nTimerID);
169 if (m_nUnderline != ulAlways)
170 SetFont(&m_StdFont);
171 rect.bottom+=10;
172 InvalidateRect(rect);
175 CStatic::OnTimer(nIDEvent);
178 BOOL CHyperLink::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/)
180 if (m_hLinkCursor)
182 ::SetCursor(m_hLinkCursor);
183 return TRUE;
185 return FALSE;
188 BOOL CHyperLink::OnEraseBkgnd(CDC* pDC)
190 CRect rect;
191 GetClientRect(rect);
192 pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
194 return TRUE;
197 void CHyperLink::SetURL(CString strURL)
199 m_strURL = strURL;
201 if (::IsWindow(GetSafeHwnd()))
203 m_ToolTip.UpdateTipText(strURL, this, TOOLTIP_ID);
207 CString CHyperLink::GetURL() const
209 return m_strURL;
212 void CHyperLink::SetColors(COLORREF crLinkColor, COLORREF crHoverColor)
214 m_crLinkColor = crLinkColor;
216 if (crHoverColor == -1)
217 m_crHoverColor = ::GetSysColor(COLOR_HIGHLIGHT);
218 else
219 m_crHoverColor = crHoverColor;
221 if (::IsWindow(m_hWnd))
222 Invalidate();
225 COLORREF CHyperLink::GetLinkColor() const
227 return m_crLinkColor;
230 COLORREF CHyperLink::GetHoverColor() const
232 return m_crHoverColor;
235 void CHyperLink::SetUnderline(int nUnderline /*=ulHover*/)
237 if (m_nUnderline == nUnderline)
238 return;
240 if (::IsWindow(GetSafeHwnd()))
242 if (nUnderline == ulAlways)
243 SetFont(&m_UnderlineFont);
244 else
245 SetFont(&m_StdFont);
247 Invalidate();
250 m_nUnderline = nUnderline;
253 int CHyperLink::GetUnderline() const
255 return m_nUnderline;
258 // The following appeared in Paul DiLascia's Jan 1998 MSJ articles.
259 // It loads a "hand" cursor from the winhlp32.exe module
260 void CHyperLink::SetDefaultCursor()
262 if (m_hLinkCursor == NULL)
264 // first try the windows hand cursor (not available on NT4)
265 #ifndef OCR_HAND
266 # define OCR_HAND 32649
267 #endif
268 HCURSOR hHandCursor = (HCURSOR)::LoadImage(NULL, MAKEINTRESOURCE(OCR_HAND), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
269 if (hHandCursor)
271 m_hLinkCursor = hHandCursor;
272 return;
274 // windows cursor not available, so try to load it from winhlp32.exe
275 CString strWndDir;
276 GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH); // Explorer can't handle paths longer than MAX_PATH.
277 strWndDir.ReleaseBuffer();
279 strWndDir += _T("\\winhlp32.exe");
280 // This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
281 CAutoLibrary hModule = LoadLibrary(strWndDir);
282 if (hModule) {
283 HCURSOR hHandCursor2 = (HCURSOR)::LoadImage(hModule, MAKEINTRESOURCE(106), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
284 if (hHandCursor2)
285 m_hLinkCursor = CopyCursor(hHandCursor2);
290 HINSTANCE CHyperLink::GotoURL(LPCTSTR url)
292 return ShellExecute(NULL, _T("open"), url, NULL,NULL, SW_SHOW);