2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
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 GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 // StaticLink.cpp : implementation file
27 #include "StaticLink.h"
32 COLORREF
CStaticLink::g_colorUnvisited
= RGB(0,0,255); // blue
33 COLORREF
CStaticLink::g_colorVisited
= RGB(128,0,128); // purple
35 HCURSOR
CStaticLink::g_hCursorLink
= NULL
;
37 IMPLEMENT_DYNAMIC(CStaticLink
, CStatic
)
39 BEGIN_MESSAGE_MAP(CStaticLink
, CStatic
)
41 ON_WM_CTLCOLOR_REFLECT()
47 // Constructor sets default colors = blue/purple.
48 // bDeleteOnDestroy is used internally by PixieLib in CPixieDlg.
50 CStaticLink::CStaticLink(LPCTSTR lpText
, BOOL bDeleteOnDestroy
)
52 m_link
= lpText
; // link text (NULL ==> window text)
53 m_color
= g_colorUnvisited
; // not visited yet
54 m_bDeleteOnDestroy
= bDeleteOnDestroy
; // delete object with window?
58 // Normally, a static control does not get mouse events unless it has
59 // SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer
60 // lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
61 // because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
63 LRESULT
CStaticLink::OnNcHitTest(CPoint point
)
69 // Handle reflected WM_CTLCOLOR to set custom control color.
70 // For a text control, use visited/unvisited colors and underline font.
71 // For non-text controls, do nothing. Also ensures SS_NOTIFY is on.
73 HBRUSH
CStaticLink::CtlColor(CDC
* pDC
, UINT nCtlColor
)
75 ASSERT(nCtlColor
== CTLCOLOR_STATIC
);
76 DWORD dwStyle
= GetStyle();
79 if ((dwStyle
& 0xFF) <= SS_RIGHT
) {
81 // this is a text control: set up font and colors
83 // first time init: create font
85 GetFont()->GetObject(sizeof(lf
), &lf
);
86 lf
.lfUnderline
= TRUE
;
87 m_font
.CreateFontIndirect(&lf
);
90 // use underline font and visited/unvisited colors
91 pDC
->SelectObject(&m_font
);
92 pDC
->SetTextColor(m_color
);
93 pDC
->SetBkMode(TRANSPARENT
);
95 // return hollow brush to preserve parent background color
96 hbr
= (HBRUSH
)::GetStockObject(HOLLOW_BRUSH
);
102 // Handle mouse click: navigate link
104 void CStaticLink::OnLButtonDown(UINT nFlags
, CPoint point
)
106 if (m_link
.IsEmpty()) {
107 // no link: try to load from resource string or window text
108 m_link
.LoadString(GetDlgCtrlID()) || (GetWindowText(m_link
),1);
109 if (m_link
.IsEmpty())
113 // Call ShellExecute to run the file.
114 // For an URL, this means opening it in the browser.
116 HINSTANCE h
= m_link
.Navigate();
117 if ((UINT
)h
> 32) { // success!
118 m_color
= g_colorVisited
; // change color
119 Invalidate(); // repaint
121 MessageBeep(0); // unable to execute file!
122 TRACE(_T("*** WARNING: CStaticLink: unable to navigate link %s\n"),
128 // Set "hand" cursor to cue user that this is a link. If app has not set
129 // g_hCursorLink, then try to get the cursor from winhlp32.exe,
130 // resource 106, which is a pointing finger. This is a bit of a kludge,
133 BOOL
CStaticLink::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
135 if (g_hCursorLink
== NULL
) {
136 static BOOL bTriedOnce
= FALSE
;
139 GetWindowsDirectory(windir
.GetBuffer(MAX_PATH
), MAX_PATH
);
140 windir
.ReleaseBuffer();
141 windir
+= _T("\\winhlp32.exe");
142 HMODULE hModule
= LoadLibrary(windir
);
145 CopyCursor(::LoadCursor(hModule
, MAKEINTRESOURCE(106)));
147 FreeLibrary(hModule
);
152 ::SetCursor(g_hCursorLink
);
159 // Normally, a control class is not destoyed when the window is;
160 // however, CPixieDlg creates static controls with "new" instead of
161 // as class members, so it's convenient to allow the option of destroying
162 // object with window. In applications where you want the object to be
163 // destoyed along with the window, you can call constructor with
164 // bDeleteOnDestroy=TRUE.
166 void CStaticLink::PostNcDestroy()
168 if (m_bDeleteOnDestroy
)