StaticLink.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 // StaticLink.cpp : implementation file
00023 //
00024 
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027 #include "StaticLink.h"
00028 
00029 
00030 // CStaticLink
00031 
00032 COLORREF CStaticLink::g_colorUnvisited = RGB(0,0,255);         // blue 
00033 COLORREF CStaticLink::g_colorVisited   = RGB(128,0,128);         // purple 
00034 
00035 HCURSOR    CStaticLink::g_hCursorLink = NULL; 
00036 
00037 IMPLEMENT_DYNAMIC(CStaticLink, CStatic) 
00038 
00039 BEGIN_MESSAGE_MAP(CStaticLink, CStatic) 
00040     ON_WM_NCHITTEST() 
00041     ON_WM_CTLCOLOR_REFLECT() 
00042     ON_WM_LBUTTONDOWN() 
00043     ON_WM_SETCURSOR() 
00044 END_MESSAGE_MAP() 
00045 
00047 // Constructor sets default colors = blue/purple. 
00048 // bDeleteOnDestroy is used internally by PixieLib in CPixieDlg. 
00049 // 
00050 CStaticLink::CStaticLink(LPCTSTR lpText, BOOL bDeleteOnDestroy) 
00051 { 
00052     m_link = lpText;                                // link text (NULL ==> window text) 
00053     m_color = g_colorUnvisited;                // not visited yet 
00054     m_bDeleteOnDestroy = bDeleteOnDestroy;    // delete object with window? 
00055 } 
00056 
00058 // Normally,    a static control does not get mouse events unless it has 
00059 // SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer 
00060 // lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor 
00061 // because Windows doesn't send WM_CTLCOLOR to bitmap static controls. 
00062 // 
00063 LRESULT CStaticLink::OnNcHitTest(CPoint point) 
00064 { 
00065     return HTCLIENT; 
00066 } 
00067 
00069 // Handle reflected WM_CTLCOLOR to set custom control color. 
00070 // For a text control, use visited/unvisited colors and underline font. 
00071 // For non-text controls, do nothing. Also ensures SS_NOTIFY is on. 
00072 // 
00073 HBRUSH CStaticLink::CtlColor(CDC* pDC, UINT nCtlColor) 
00074 { 
00075     ASSERT(nCtlColor == CTLCOLOR_STATIC); 
00076     DWORD dwStyle = GetStyle(); 
00077      
00078     HBRUSH hbr = NULL; 
00079     if ((dwStyle & 0xFF) <= SS_RIGHT) { 
00080 
00081         // this is a text control: set up font and colors 
00082         if (!(HFONT)m_font) { 
00083             // first time init: create font 
00084             LOGFONT lf; 
00085             GetFont()->GetObject(sizeof(lf), &lf); 
00086             lf.lfUnderline = TRUE; 
00087             m_font.CreateFontIndirect(&lf); 
00088         } 
00089 
00090         // use underline font and visited/unvisited colors 
00091         pDC->SelectObject(&m_font); 
00092         pDC->SetTextColor(m_color); 
00093         pDC->SetBkMode(TRANSPARENT); 
00094 
00095         // return hollow brush to preserve parent background color 
00096         hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH); 
00097     } 
00098     return hbr; 
00099 } 
00100 
00102 // Handle mouse click: navigate link 
00103 // 
00104 void CStaticLink::OnLButtonDown(UINT nFlags, CPoint point) 
00105 { 
00106     if (m_link.IsEmpty()) { 
00107         // no link: try to load from resource string or window text  
00108         m_link.LoadString(GetDlgCtrlID()) || (GetWindowText(m_link),1); 
00109         if (m_link.IsEmpty()) 
00110             return; 
00111     } 
00112 
00113     // Call ShellExecute to run the file. 
00114     // For an URL, this means opening it in the browser. 
00115     // 
00116     HINSTANCE h = m_link.Navigate(); 
00117     if ((UINT)h > 32) {                         // success! 
00118         m_color = g_colorVisited;             // change color 
00119         Invalidate();                             // repaint  
00120     } else { 
00121         MessageBeep(0);        // unable to execute file! 
00122         TRACE(_T("*** WARNING: CStaticLink: unable to navigate link %s\n"), 
00123             (LPCTSTR)m_link); 
00124     } 
00125 } 
00126 
00128 // Set "hand" cursor to cue user that this is a link. If app has not set 
00129 // g_hCursorLink, then try to get the cursor from winhlp32.exe, 
00130 // resource 106, which is a pointing finger. This is a bit of a kludge, 
00131 // but it works. 
00132 // 
00133 BOOL CStaticLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
00134 { 
00135     if (g_hCursorLink == NULL) { 
00136         static BOOL bTriedOnce = FALSE; 
00137         if (!bTriedOnce) { 
00138          CString windir; 
00139          GetWindowsDirectory(windir.GetBuffer(MAX_PATH), MAX_PATH); 
00140          windir.ReleaseBuffer(); 
00141          windir += _T("\\winhlp32.exe"); 
00142          HMODULE hModule = LoadLibrary(windir); 
00143             if (hModule) { 
00144                 g_hCursorLink = 
00145                     CopyCursor(::LoadCursor(hModule, MAKEINTRESOURCE(106))); 
00146             } 
00147             FreeLibrary(hModule); 
00148             bTriedOnce = TRUE; 
00149         } 
00150     } 
00151     if (g_hCursorLink) { 
00152         ::SetCursor(g_hCursorLink); 
00153         return TRUE; 
00154     } 
00155     return FALSE; 
00156 } 
00157 
00159 // Normally, a control class is not destoyed when the window is; 
00160 // however, CPixieDlg creates static controls with "new" instead of 
00161 // as class members, so it's convenient to allow the option of destroying 
00162 // object with window. In applications where you want the object to be 
00163 // destoyed along with the window, you can call constructor with 
00164 // bDeleteOnDestroy=TRUE. 
00165 // 
00166 void CStaticLink::PostNcDestroy() 
00167 { 
00168     if (m_bDeleteOnDestroy) 
00169         delete this; 
00170 } 
00171 

Generated on Tue Dec 13 14:47:04 2005 for guliverkli by  doxygen 1.4.5