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.
20 #include "HyperLink.h"
21 #include "SmartHandle.h"
27 static char THIS_FILE
[] = __FILE__
;
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?
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
);
74 GetWindowText(strWndText
);
75 if (strWndText
.IsEmpty())
77 SetWindowText(m_strURL
);
80 CFont
* pFont
= GetFont();
83 HFONT hFont
= (HFONT
)GetStockObject(DEFAULT_GUI_FONT
);
85 hFont
= (HFONT
) GetStockObject(ANSI_VAR_FONT
);
87 pFont
= CFont::FromHandle(hFont
);
89 ASSERT(pFont
->GetSafeHandle());
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
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()
114 ON_CONTROL_REFLECT(STN_CLICKED
, OnClicked
)
118 void CHyperLink::OnClicked()
120 if(!m_strURL
.IsEmpty())
126 ::SendMessage(this->GetParent()->m_hWnd
,WM_COMMAND
,this->GetDlgCtrlID(),0);
130 HBRUSH
CHyperLink::CtlColor(CDC
* pDC
, UINT
/*nCtlColor*/)
133 pDC
->SetTextColor(m_crHoverColor
);
135 pDC
->SetTextColor(m_crLinkColor
);
138 pDC
->SetBkMode(TRANSPARENT
);
139 return (HBRUSH
)GetStockObject(NULL_BRUSH
);
142 void CHyperLink::OnMouseMove(UINT nFlags
, CPoint point
)
146 m_bOverControl
= TRUE
;
148 if (m_nUnderline
== ulHover
)
149 SetFont(&m_UnderlineFont
);
152 SetTimer(m_nTimerID
, 100, NULL
);
154 CStatic::OnMouseMove(nFlags
, point
);
157 void CHyperLink::OnTimer(UINT_PTR nIDEvent
)
159 CPoint
p(GetMessagePos());
164 if (!rect
.PtInRect(p
))
166 m_bOverControl
= FALSE
;
167 KillTimer(m_nTimerID
);
169 if (m_nUnderline
!= ulAlways
)
172 InvalidateRect(rect
);
175 CStatic::OnTimer(nIDEvent
);
178 BOOL
CHyperLink::OnSetCursor(CWnd
* /*pWnd*/, UINT
/*nHitTest*/, UINT
/*message*/)
182 ::SetCursor(m_hLinkCursor
);
188 BOOL
CHyperLink::OnEraseBkgnd(CDC
* pDC
)
192 pDC
->FillSolidRect(rect
, ::GetSysColor(COLOR_3DFACE
));
197 void CHyperLink::SetURL(CString strURL
)
201 if (::IsWindow(GetSafeHwnd()))
203 m_ToolTip
.UpdateTipText(strURL
, this, TOOLTIP_ID
);
207 CString
CHyperLink::GetURL() const
212 void CHyperLink::SetColors(COLORREF crLinkColor
, COLORREF crHoverColor
)
214 m_crLinkColor
= crLinkColor
;
216 if (crHoverColor
== -1)
217 m_crHoverColor
= ::GetSysColor(COLOR_HIGHLIGHT
);
219 m_crHoverColor
= crHoverColor
;
221 if (::IsWindow(m_hWnd
))
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
)
240 if (::IsWindow(GetSafeHwnd()))
242 if (nUnderline
== ulAlways
)
243 SetFont(&m_UnderlineFont
);
250 m_nUnderline
= nUnderline
;
253 int CHyperLink::GetUnderline() const
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)
266 # define OCR_HAND 32649
268 HCURSOR hHandCursor
= (HCURSOR
)::LoadImage(NULL
, MAKEINTRESOURCE(OCR_HAND
), IMAGE_CURSOR
, 0, 0, LR_DEFAULTSIZE
| LR_SHARED
);
271 m_hLinkCursor
= hHandCursor
;
274 // windows cursor not available, so try to load it from winhlp32.exe
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
);
283 HCURSOR hHandCursor2
= (HCURSOR
)::LoadImage(hModule
, MAKEINTRESOURCE(106), IMAGE_CURSOR
, 0, 0, LR_DEFAULTSIZE
);
285 m_hLinkCursor
= CopyCursor(hHandCursor2
);
290 HINSTANCE
CHyperLink::GotoURL(LPCTSTR url
)
292 return ShellExecute(NULL
, _T("open"), url
, NULL
,NULL
, SW_SHOW
);