Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.2 KiB

  1. // HotLink.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h"
  5. #include "HotLink.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. #define COLOR_BLUE RGB(0, 0, 0xFF)
  12. #define COLOR_YELLOW RGB(0xff, 0x80, 0)
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CHotLink
  15. CHotLink::CHotLink():
  16. m_CapturedMouse(FALSE),
  17. m_fBrowse(FALSE),
  18. m_fExplore(FALSE),
  19. m_fOpen(TRUE),
  20. m_fInitializedFont(FALSE)
  21. {
  22. }
  23. CHotLink::~CHotLink()
  24. {
  25. }
  26. BEGIN_MESSAGE_MAP(CHotLink, CButton)
  27. //{{AFX_MSG_MAP(CHotLink)
  28. ON_WM_LBUTTONDOWN()
  29. ON_WM_LBUTTONUP()
  30. ON_WM_MOUSEMOVE()
  31. ON_WM_CAPTURECHANGED()
  32. //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34. //------------------------------------------------------------------------
  35. // set the title string
  36. void CHotLink::SetTitle( CString sz )
  37. {
  38. // set the title
  39. SetWindowText( sz );
  40. // force the window to redraw
  41. Invalidate( TRUE );
  42. }
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CHotLink message handlers
  45. //------------------------------------------------------------------------
  46. void CHotLink::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  47. {
  48. // prep the device context
  49. CDC* pdc = CDC::FromHandle(lpDrawItemStruct->hDC);
  50. // get the drawing rect
  51. CRect rect = lpDrawItemStruct->rcItem;
  52. CString sz;
  53. GetWindowText(sz);
  54. if (!m_fInitializedFont)
  55. {
  56. // get the window font
  57. LOGFONT logfont;
  58. HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);
  59. ASSERT(hFont != NULL);
  60. VERIFY(0 < GetObject(hFont, sizeof(LOGFONT), &logfont));
  61. // modify the font - add underlining
  62. logfont.lfUnderline = TRUE;
  63. // set the font back
  64. HFONT hNewFont = ::CreateFontIndirect(&logfont);
  65. ASSERT(hNewFont != NULL);
  66. SendMessage(WM_SETFONT, (WPARAM)hNewFont, MAKELPARAM(TRUE, 0));
  67. // get the extents fo the text for later reference
  68. m_cpTextExtents = pdc->GetOutputTextExtent(sz);
  69. // get the main rect
  70. GetClientRect(m_rcText);
  71. // reduce it by the width of the text
  72. m_rcText.left = m_rcText.left + (m_rcText.Width() - m_cpTextExtents.cx) / 2;
  73. m_rcText.right = m_rcText.left + m_cpTextExtents.cx;
  74. m_rcText.top = m_rcText.top + (m_rcText.Height() - m_cpTextExtents.cy) / 2;
  75. m_rcText.bottom = m_rcText.top + m_cpTextExtents.cy;
  76. m_clrText = COLOR_BLUE;
  77. m_fInitializedFont = TRUE;
  78. }
  79. // draw the text in color that was set outside
  80. pdc->SetTextColor(m_clrText);
  81. // draw the text
  82. pdc->DrawText(sz, &rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  83. }
  84. //------------------------------------------------------------------------
  85. // calculate the rectangle that surrounds the text
  86. void CHotLink::GetTextRect( CRect &rect )
  87. {
  88. // get the main rect
  89. GetClientRect( rect );
  90. // reduce it by margins
  91. // Calculations below are for centered text. To locate it inside
  92. // the dialog just make it tight and move control itself
  93. rect.left = rect.left + (rect.Width() - m_cpTextExtents.cx) / 2;
  94. rect.right = rect.left + m_cpTextExtents.cx;
  95. rect.top = rect.top + (rect.Height() - m_cpTextExtents.cy) / 2;
  96. rect.bottom = rect.top + m_cpTextExtents.cy;
  97. }
  98. //------------------------------------------------------------------------
  99. void CHotLink::OnLButtonDown(UINT nFlags, CPoint point)
  100. {
  101. // don't do the hotlink thing if there is no text
  102. if (!m_strLink.IsEmpty() && !m_CapturedMouse && m_rcText.PtInRect(point))
  103. {
  104. SetCapture();
  105. m_CapturedMouse = TRUE;
  106. }
  107. }
  108. //------------------------------------------------------------------------
  109. void CHotLink::OnLButtonUp(UINT nFlags, CPoint point)
  110. {
  111. // only bother if we have the capture
  112. if (m_CapturedMouse)
  113. {
  114. ReleaseCapture();
  115. if ( m_fBrowse )
  116. Browse();
  117. else if ( m_fExplore )
  118. Explore();
  119. else if ( m_fOpen )
  120. Open();
  121. }
  122. }
  123. //------------------------------------------------------------------------
  124. void CHotLink::Browse()
  125. {
  126. ShellExecute(
  127. NULL, // handle to parent window
  128. NULL, // pointer to string that specifies operation to perform
  129. m_strLink, // pointer to filename or folder name string
  130. NULL, // pointer to string that specifies executable-file parameters
  131. NULL, // pointer to string that specifies default directory
  132. SW_SHOW // whether file is shown when opened
  133. );
  134. }
  135. //------------------------------------------------------------------------
  136. void CHotLink::Explore()
  137. {
  138. ShellExecute(
  139. NULL, // handle to parent window
  140. _T("explore"), // pointer to string that specifies operation to perform
  141. m_strLink, // pointer to filename or folder name string
  142. NULL, // pointer to string that specifies executable-file parameters
  143. NULL, // pointer to string that specifies default directory
  144. SW_SHOW // whether file is shown when opened
  145. );
  146. }
  147. //------------------------------------------------------------------------
  148. void CHotLink::Open()
  149. {
  150. ShellExecute(
  151. NULL, // handle to parent window
  152. _T("open"), // pointer to string that specifies operation to perform
  153. m_strLink, // pointer to filename or folder name string
  154. NULL, // pointer to string that specifies executable-file parameters
  155. NULL, // pointer to string that specifies default directory
  156. SW_SHOW // whether file is shown when opened
  157. );
  158. }
  159. //------------------------------------------------------------------------
  160. void CHotLink::OnMouseMove(UINT nFlags, CPoint point)
  161. {
  162. CRect rect;
  163. GetTextRect(rect);
  164. // if the mouse is over the hot area, show the right cursor
  165. if (rect.PtInRect(point))
  166. {
  167. ::SetCursor(AfxGetApp()->LoadCursor(IDC_BROWSE_CUR));
  168. // also reset text color to *yellow*
  169. if (m_clrText != COLOR_YELLOW)
  170. {
  171. m_clrText = COLOR_YELLOW;
  172. InvalidateRect(m_rcText, FALSE);
  173. UpdateWindow();
  174. }
  175. }
  176. else
  177. {
  178. if (m_clrText != COLOR_BLUE)
  179. // we are not pointing to text, render it in *blue*
  180. {
  181. m_clrText = COLOR_BLUE;
  182. InvalidateRect(m_rcText, FALSE);
  183. UpdateWindow();
  184. }
  185. // also remove capture and reset the cursor
  186. ReleaseCapture();
  187. ::SetCursor(AfxGetApp()->LoadCursor(IDC_ARROW));
  188. }
  189. }
  190. void CHotLink::OnCaptureChanged(CWnd *pWnd)
  191. {
  192. m_clrText = COLOR_BLUE;
  193. InvalidateRect(m_rcText, FALSE);
  194. UpdateWindow();
  195. m_CapturedMouse = FALSE;
  196. CButton::OnCaptureChanged(pWnd);
  197. }