StatLink.cpp
上传用户:dgvc2008
上传日期:2021-01-21
资源大小:65k
文件大小:6k
源码类别:

RichEdit

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////
  2. // VCKBASE -- August 2000
  3. // Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
  4. // Download by http://www.codefans.net
  5. // CStaticLink implements a static control that's a hyperlink
  6. // to any file on your desktop or web. You can use it in dialog boxes
  7. // to create hyperlinks to web sites. When clicked, opens the file/URL
  8. //
  9. #include "StdAfx.h"
  10. #include "StatLink.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. COLORREF CStaticLink::g_colorUnvisited  = RGB(0,0,255);  // blue
  17. COLORREF CStaticLink::g_colorVisited    = RGB(128,0,128);  // purple
  18. COLORREF CStaticLink::g_colorOver = RGB(255,0,0);      // Red
  19. HCURSOR CStaticLink::g_hCursorLink = NULL;
  20. IMPLEMENT_DYNAMIC(CStaticLink, CStatic)
  21. BEGIN_MESSAGE_MAP(CStaticLink, CStatic)
  22. ON_WM_NCHITTEST()
  23. ON_WM_CTLCOLOR_REFLECT()
  24. ON_WM_LBUTTONDOWN()
  25. ON_WM_SETCURSOR()
  26. ON_WM_TIMER()
  27. END_MESSAGE_MAP()
  28. ///////////////////
  29. // Constructor sets default colors = blue/purple.
  30. // bDeleteOnDestroy is used internally by PixieLib in CPixieDlg.
  31. //
  32. CStaticLink::CStaticLink(LPCTSTR lpText, BOOL bDeleteOnDestroy)
  33. {
  34. m_link = lpText; // link text (NULL ==> window text)
  35. m_color = g_colorUnvisited; // not visited yet
  36. m_bDeleteOnDestroy = bDeleteOnDestroy; // delete object with window?
  37.     m_bOverControl     = FALSE;                // Cursor not yet over control
  38.     m_nTimerID         = 1;
  39. }
  40. //////////////////
  41. // Normally, a static control does not get mouse events unless it has
  42. // SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer
  43. // lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
  44. // because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
  45. //
  46. UINT CStaticLink::OnNcHitTest(CPoint point)
  47. {
  48. if (!m_bOverControl)        // Cursor has just moved over control
  49. {
  50. m_bOverControl = TRUE;
  51. /*
  52.     CDC* pDC = GetDC();
  53. LOGFONT lf;
  54. GetFont()->GetObject(sizeof(lf), &lf);
  55. lf.lfUnderline = TRUE;
  56. m_font.DeleteObject();
  57. m_font.CreateFontIndirect(&lf);
  58. // use underline font and visited/unvisited colors
  59. pDC->SelectObject(&m_font);
  60. */
  61. m_color = g_colorOver; // change color
  62. Invalidate(); // repaint 
  63. SetTimer(m_nTimerID, 100, NULL);
  64. }
  65. return HTCLIENT;
  66. }
  67. //////////////////
  68. // Handle reflected WM_CTLCOLOR to set custom control color.
  69. // For a text control, use visited/unvisited colors and underline font.
  70. // For non-text controls, do nothing. Also ensures SS_NOTIFY is on.
  71. //
  72. HBRUSH CStaticLink::CtlColor(CDC* pDC, UINT nCtlColor)
  73. {
  74. ASSERT(nCtlColor == CTLCOLOR_STATIC);
  75. DWORD dwStyle = GetStyle();
  76. HBRUSH hbr = NULL;
  77. if ((dwStyle & 0xFF) <= SS_RIGHT) {
  78. // this is a text control: set up font and colors
  79. if (!(HFONT)m_font) {
  80. // first time init: create font
  81. LOGFONT lf;
  82. GetFont()->GetObject(sizeof(lf), &lf);
  83. // lf.lfUnderline = TRUE;
  84. m_font.CreateFontIndirect(&lf);
  85. }
  86. // use underline font and visited/unvisited colors
  87. pDC->SelectObject(&m_font);
  88. pDC->SetTextColor(m_color);
  89. pDC->SetBkMode(TRANSPARENT);
  90. // return hollow brush to preserve parent background color
  91. hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
  92. }
  93. return hbr;
  94. }
  95. /////////////////
  96. // Handle mouse click: navigate link
  97. //
  98. void CStaticLink::OnLButtonDown(UINT nFlags, CPoint point)
  99. {
  100. if (m_link.IsEmpty()) {
  101. // no link: try to load from resource string or window text 
  102. m_link.LoadString(GetDlgCtrlID()) || (GetWindowText(m_link),1);
  103. if (m_link.IsEmpty())
  104. return;
  105. }
  106. // Call ShellExecute to run the file.
  107. // For an URL, this means opening it in the browser.
  108. //
  109. HINSTANCE h = m_link.Navigate();
  110. if ((UINT)h > 32) {  // success!
  111. m_color = g_colorVisited;  // change color
  112. Invalidate();  // repaint 
  113. } else {
  114. MessageBeep(0); // unable to execute file!
  115. TRACE(_T("*** WARNING: CStaticLink: unable to navigate link %sn"),
  116. (LPCTSTR)m_link);
  117. }
  118. }
  119. void CStaticLink::OnTimer(UINT nIDEvent) 
  120. {
  121.     CPoint p(GetMessagePos());
  122.     ScreenToClient(&p);
  123. HBRUSH hbr = NULL;
  124.     CRect rect;
  125.     GetClientRect(rect);
  126.     if (!rect.PtInRect(p))
  127.     {
  128.         m_bOverControl = FALSE;
  129.     KillTimer(m_nTimerID);
  130. /*
  131.     CDC* pDC = GetDC();
  132. LOGFONT lf;
  133. GetFont()->GetObject(sizeof(lf), &lf);
  134. lf.lfUnderline = FALSE;
  135. m_font.DeleteObject();
  136. m_font.CreateFontIndirect(&lf);
  137. // use underline font and visited/unvisited colors
  138. pDC->SelectObject(&m_font);
  139. */
  140. m_color = g_colorUnvisited; // change color
  141. Invalidate(); // repaint 
  142.         rect.bottom+=10;
  143.         InvalidateRect(rect);
  144. }
  145. CStatic::OnTimer(nIDEvent);
  146. }
  147. //////////////////
  148. // Set "hand" cursor to cue user that this is a link. If app has not set
  149. // g_hCursorLink, then try to get the cursor from winhlp32.exe,
  150. // resource 106, which is a pointing finger. This is a bit of a kludge,
  151. // but it works.
  152. //
  153. BOOL CStaticLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  154. {
  155. if (g_hCursorLink == NULL) {
  156. static bTriedOnce = FALSE;
  157. if (!bTriedOnce) {
  158.          CString windir;
  159.  // For Windows XP
  160. //         GetSystemWindowsDirectory(windir.GetBuffer(MAX_PATH), MAX_PATH);
  161.  // For Windows 2000
  162.          GetWindowsDirectory(windir.GetBuffer(MAX_PATH), MAX_PATH);
  163.          windir.ReleaseBuffer();
  164.          windir += _T("\winhlp32.exe");
  165.          HMODULE hModule = LoadLibrary(windir);
  166. if (hModule) {
  167. g_hCursorLink =
  168. CopyCursor(::LoadCursor(hModule, MAKEINTRESOURCE(106)));
  169. }
  170. FreeLibrary(hModule);
  171. bTriedOnce = TRUE;
  172. }
  173. }
  174. if (g_hCursorLink) {
  175. ::SetCursor(g_hCursorLink);
  176. return TRUE;
  177. }
  178. return FALSE;
  179. }
  180. //////////////////
  181. // Normally, a control class is not destoyed when the window is;
  182. // however, CPixieDlg creates static controls with "new" instead of
  183. // as class members, so it's convenient to allow the option of destroying
  184. // object with window. In applications where you want the object to be
  185. // destoyed along with the window, you can call constructor with
  186. // bDeleteOnDestroy=TRUE.
  187. //
  188. void CStaticLink::PostNcDestroy()
  189. {
  190. if (m_bDeleteOnDestroy)
  191. delete this;
  192. }