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"
26 static char THIS_FILE
[] = __FILE__
;
32 CHyperLink::CHyperLink()
34 m_hLinkCursor
= NULL
; // No cursor as yet
35 m_crLinkColor
= RGB( 0, 0, 238); // Blue
36 m_crHoverColor
= RGB(255, 0, 0); // Red
37 m_bOverControl
= FALSE
; // Cursor not yet over control
38 m_nUnderline
= ulHover
; // Underline the link?
43 CHyperLink::~CHyperLink()
45 m_UnderlineFont
.DeleteObject();
48 BOOL
CHyperLink::DestroyWindow()
50 KillTimer(m_nTimerID
);
52 return CStatic::DestroyWindow();
55 BOOL
CHyperLink::PreTranslateMessage(MSG
* pMsg
)
57 m_ToolTip
.RelayEvent(pMsg
);
58 return CStatic::PreTranslateMessage(pMsg
);
62 void CHyperLink::PreSubclassWindow()
64 // Enable notifications - CStatic has this disabled by default
65 DWORD dwStyle
= GetStyle();
66 ::SetWindowLong(GetSafeHwnd(), GWL_STYLE
, dwStyle
| SS_NOTIFY
);
68 // By default use the label text as the URL
69 if (m_strURL
.IsEmpty())
70 GetWindowText(m_strURL
);
73 GetWindowText(strWndText
);
74 if (strWndText
.IsEmpty())
76 SetWindowText(m_strURL
);
79 CFont
* pFont
= GetFont();
82 HFONT hFont
= (HFONT
)GetStockObject(DEFAULT_GUI_FONT
);
84 hFont
= (HFONT
) GetStockObject(ANSI_VAR_FONT
);
86 pFont
= CFont::FromHandle(hFont
);
88 ASSERT(pFont
&& pFont
->GetSafeHandle());
91 pFont
->GetLogFont(&lf
);
92 m_StdFont
.CreateFontIndirect(&lf
);
93 lf
.lfUnderline
= (BYTE
) TRUE
;
94 m_UnderlineFont
.CreateFontIndirect(&lf
);
96 SetDefaultCursor(); // try loading a "hand" cursor
101 m_ToolTip
.Create(this);
102 m_ToolTip
.AddTool(this, m_strURL
, rect
, TOOLTIP_ID
);
104 CStatic::PreSubclassWindow();
107 BEGIN_MESSAGE_MAP(CHyperLink
, CStatic
)
108 ON_WM_CTLCOLOR_REFLECT()
113 ON_CONTROL_REFLECT(STN_CLICKED
, OnClicked
)
117 void CHyperLink::OnClicked()
119 if(!m_strURL
.IsEmpty())
125 ::SendMessage(this->GetParent()->m_hWnd
,WM_COMMAND
,this->GetDlgCtrlID(),0);
129 HBRUSH
CHyperLink::CtlColor(CDC
* pDC
, UINT
/*nCtlColor*/)
132 pDC
->SetTextColor(m_crHoverColor
);
134 pDC
->SetTextColor(m_crLinkColor
);
137 pDC
->SetBkMode(TRANSPARENT
);
138 return (HBRUSH
)GetStockObject(NULL_BRUSH
);
141 void CHyperLink::OnMouseMove(UINT nFlags
, CPoint point
)
145 m_bOverControl
= TRUE
;
147 if (m_nUnderline
== ulHover
)
148 SetFont(&m_UnderlineFont
);
151 SetTimer(m_nTimerID
, 100, NULL
);
153 CStatic::OnMouseMove(nFlags
, point
);
156 void CHyperLink::OnTimer(UINT_PTR nIDEvent
)
158 CPoint
p(GetMessagePos());
163 if (!rect
.PtInRect(p
))
165 m_bOverControl
= FALSE
;
166 KillTimer(m_nTimerID
);
168 if (m_nUnderline
!= ulAlways
)
171 InvalidateRect(rect
);
174 CStatic::OnTimer(nIDEvent
);
177 BOOL
CHyperLink::OnSetCursor(CWnd
* /*pWnd*/, UINT
/*nHitTest*/, UINT
/*message*/)
181 ::SetCursor(m_hLinkCursor
);
187 BOOL
CHyperLink::OnEraseBkgnd(CDC
* pDC
)
191 pDC
->FillSolidRect(rect
, ::GetSysColor(COLOR_3DFACE
));
196 void CHyperLink::SetURL(CString strURL
)
200 if (::IsWindow(GetSafeHwnd()))
202 m_ToolTip
.UpdateTipText(strURL
, this, TOOLTIP_ID
);
206 CString
CHyperLink::GetURL() const
211 void CHyperLink::SetColors(COLORREF crLinkColor
, COLORREF crHoverColor
)
213 m_crLinkColor
= crLinkColor
;
215 if (crHoverColor
== -1)
216 m_crHoverColor
= ::GetSysColor(COLOR_HIGHLIGHT
);
218 m_crHoverColor
= crHoverColor
;
220 if (::IsWindow(m_hWnd
))
224 COLORREF
CHyperLink::GetLinkColor() const
226 return m_crLinkColor
;
229 COLORREF
CHyperLink::GetHoverColor() const
231 return m_crHoverColor
;
234 void CHyperLink::SetUnderline(int nUnderline
/*=ulHover*/)
236 if (m_nUnderline
== nUnderline
)
239 if (::IsWindow(GetSafeHwnd()))
241 if (nUnderline
== ulAlways
)
242 SetFont(&m_UnderlineFont
);
249 m_nUnderline
= nUnderline
;
252 int CHyperLink::GetUnderline() const
257 // The following appeared in Paul DiLascia's Jan 1998 MSJ articles.
258 // It loads a "hand" cursor from the winhlp32.exe module
259 void CHyperLink::SetDefaultCursor()
261 if (m_hLinkCursor
== NULL
)
263 // first try the windows hand cursor (not available on NT4)
265 # define OCR_HAND 32649
267 HCURSOR hHandCursor
= (HCURSOR
)::LoadImage(NULL
, MAKEINTRESOURCE(OCR_HAND
), IMAGE_CURSOR
, 0, 0, LR_DEFAULTSIZE
| LR_SHARED
);
270 m_hLinkCursor
= hHandCursor
;
273 // windows cursor not available, so try to load it from winhlp32.exe
275 GetWindowsDirectory(strWndDir
.GetBuffer(MAX_PATH
), MAX_PATH
); // Explorer can't handle paths longer than MAX_PATH.
276 strWndDir
.ReleaseBuffer();
278 strWndDir
+= _T("\\winhlp32.exe");
279 // This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
280 CAutoLibrary hModule
= LoadLibrary(strWndDir
);
282 HCURSOR hHandCursor2
= (HCURSOR
)::LoadImage(hModule
, MAKEINTRESOURCE(106), IMAGE_CURSOR
, 0, 0, LR_DEFAULTSIZE
);
284 m_hLinkCursor
= CopyCursor(hHandCursor2
);
289 HINSTANCE
CHyperLink::GotoURL(LPCTSTR url
)
291 return ShellExecute(NULL
, _T("open"), url
, NULL
,NULL
, SW_SHOW
);