XTTipWindow.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:18k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTTipWindow.cpp : implementation of the CXTTipWindow class.
  2. //
  3. // This file is a part of the XTREME CONTROLS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Thanks to Michael Berlenz for helping to extend the CXTTipWindow class.
  21. #include "stdafx.h"
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "Common/XTPColorManager.h"
  24. #include "Common/XTPSystemHelpers.h"
  25. #include "XTDefines.h"
  26. #include "XTGlobal.h"
  27. #include "XTVC50Helpers.h"
  28. #include "XTTipWindow.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CXTTipWindow
  36. /////////////////////////////////////////////////////////////////////////////
  37. CXTTipWindow::CXTTipWindow()
  38. {
  39. m_sizeMargin = CSize(0, 0);
  40. m_nLineSpace = 0;
  41. m_dwTipStyle = 0;
  42. m_nElapseTimerEventID = 1;
  43. m_pParentWnd = NULL;
  44. m_strTitle = _T("");
  45. m_strDescrip = _T("");
  46. m_crBackColor = ::GetSysColor(COLOR_INFOBK);
  47. m_crTextColor = ::GetSysColor(COLOR_INFOTEXT);
  48. m_sizeTitle = CSize(0, 0);
  49. //  m_bMouseWasClickedSoDoNotShowTip = FALSE;
  50. m_ptMousePos = CPoint(0, 0);
  51. m_bCenterHorz = FALSE;
  52. m_nDelayTimerEventID = 2;
  53. m_bDelayTimerRunning = FALSE;
  54. m_pointTipOffsetPos = CPoint(0, 20); //20 = mouse cursor height
  55. m_pnTabStopPositions = NULL;
  56. m_nTabPositions = 0;
  57. m_rectTipArea.SetRectEmpty();
  58. }
  59. CXTTipWindow::~CXTTipWindow()
  60. {
  61. }
  62. BOOL CXTTipWindow::Create(CWnd* pParentWnd)
  63. {
  64. // register the wnd class.
  65. CString wndClass = ::AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW);
  66. // call the base class for creation.
  67. if (!CWnd::CreateEx(0, wndClass, _T(""), WS_POPUP, 0, 0, 0, 0, pParentWnd->m_hWnd, 0, NULL))
  68. {
  69. TRACE0("Failed to create popup window.n");
  70. return FALSE;
  71. }
  72. m_pParentWnd = pParentWnd;
  73. return TRUE;
  74. }
  75. BEGIN_MESSAGE_MAP(CXTTipWindow, CWnd)
  76. //{{AFX_MSG_MAP(CXTTipWindow)
  77. ON_WM_MOUSEMOVE()
  78. ON_WM_KILLFOCUS()
  79. ON_WM_PAINT()
  80. ON_WM_TIMER()
  81. ON_WM_ERASEBKGND()
  82. ON_WM_LBUTTONDOWN()
  83. ON_WM_RBUTTONDOWN()
  84. ON_WM_MBUTTONDOWN()
  85. //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87. BOOL CXTTipWindow::ShowTipWindow(const CPoint& point, DWORD dwTipStyle/*= TWS_XT_DROPSHADOW*/, UINT nDelay/*= 0*/, UINT nElapse/*= 5000*/, BOOL bCenterHorz /*= FALSE*/)
  88. {
  89. //Check for valid tip text
  90. if (m_strTitle.IsEmpty() && m_strDescrip.IsEmpty())
  91. return FALSE;
  92. // Save values for InitializeSize() function
  93. m_ptMousePos = point;
  94. m_bCenterHorz = bCenterHorz;
  95. // Return if process is running
  96. if (m_bDelayTimerRunning || IsWindowVisible())
  97. return FALSE;
  98. // Analyze tip text
  99. m_arStrings.RemoveAll();
  100. if (m_strDescrip.Find(_T("n")) != -1)
  101. {
  102. CString strDesc(m_strDescrip);
  103. while (strDesc.Find(_T("n")) != -1)
  104. {
  105. int nDelim = strDesc.Find(_T("n"));
  106. CString strAdd = strDesc.Left(nDelim);
  107. m_arStrings.Add(strAdd);
  108. strDesc = strDesc.Mid(nDelim + 1);
  109. }
  110. m_arStrings.Add(strDesc);
  111. }
  112. // Save the tip style
  113. m_dwTipStyle = dwTipStyle;
  114. if (!nDelay)
  115. {
  116. // Show the tip window
  117. InitializeSize(m_ptMousePos, m_bCenterHorz);
  118. SetWindowPos(&wndTop, m_rcScreenWindow.left, m_rcScreenWindow.top, m_rcShadow.right - m_rcWindow.left,
  119. m_rcShadow.bottom - m_rcWindow.top, SWP_SHOWWINDOW | SWP_NOACTIVATE); //see also InitializeSize()
  120. SetCapture();
  121. }
  122. // If a time-out value was specified, start the timer.
  123. if (nElapse || nDelay)
  124. {
  125. if (nDelay)
  126. {
  127. SetTimer(m_nDelayTimerEventID, nDelay, NULL); //if timer runns out, window will be shown
  128. m_bDelayTimerRunning = TRUE;
  129. }
  130. if (nElapse)
  131. SetTimer(m_nElapseTimerEventID, nDelay + nElapse, NULL); //if timer runns out, window will be hide
  132. }
  133. return TRUE; // success!
  134. }
  135. //////////////////////////////////////////////////////////////////////////
  136. // ShowTipWindow
  137. // ----------------------------------------------------------------------------
  138. // rectCtrl = if the mouse is inside this rectangle the tip will be shown
  139. // => client coordinates of the window that owns this tip window
  140. // pointMousePos => client coordinates of the window that owns this tip window
  141. //
  142. BOOL CXTTipWindow::ShowTipWindow(const CRect& rectCtrl, const CPoint& pointMousePos, DWORD dwTipStyle/*= TWS_XT_DROPSHADOW*/, UINT nDelay/*= 0*/, UINT nElapse/*= 5000*/, BOOL bCenterHorz /*= FALSE*/, BOOL bShowTipAtCursorPos/*= FALSE*/)
  143. {
  144. //Check for valid tip text
  145. //  if (m_strTitle.IsEmpty() && m_strDescrip.IsEmpty()) //Do not process this check here!
  146. //      return FALSE;
  147. //Check for zero rectangle
  148. if (rectCtrl.IsRectNull())
  149. return ShowTipWindow(pointMousePos, dwTipStyle, nDelay, nElapse, bCenterHorz);
  150. //Check mouse was clicked -> do not show tip window
  151. //  if (m_bMouseWasClickedSoDoNotShowTip && rectCtrl == m_rectLast)
  152. //      return FALSE;
  153. //In case the tip window is visible hide it
  154. HideTipWindow();
  155. //Calculate offset for bShowTipAtCursorPos = TRUE
  156. CPoint pointMove = pointMousePos - rectCtrl.TopLeft();
  157. pointMove.Offset(m_pointTipOffsetPos);
  158. //Copy rectCtrl and move rectangle to zero origin
  159. m_rectTipArea = rectCtrl;
  160. m_rectTipArea.OffsetRect(-rectCtrl.TopLeft());
  161. //Offset rectangle
  162. CPoint ptTipWindowPos = rectCtrl.TopLeft();
  163. if (bShowTipAtCursorPos) //else show window at top left corner of rectCtrl
  164. {
  165. m_rectTipArea.OffsetRect(-pointMove);
  166. ptTipWindowPos += pointMove;
  167. }
  168. //  m_bMouseWasClickedSoDoNotShowTip = FALSE;
  169. //m_rectLast = rectCtrl;
  170. m_pParentWnd->ClientToScreen(&ptTipWindowPos);
  171. return ShowTipWindow(ptTipWindowPos, dwTipStyle, nDelay, nElapse, bCenterHorz);
  172. }
  173. void CXTTipWindow::HideTipWindow()
  174. {
  175. // Kill the timers
  176. KillTimer(m_nElapseTimerEventID);
  177. KillTimer(m_nDelayTimerEventID);
  178. m_bDelayTimerRunning = FALSE;
  179. // Release capture
  180. if (GetCapture() == this)
  181. ReleaseCapture();
  182. // Hide the tip window
  183. if (IsWindowVisible())
  184. ShowWindow(SW_HIDE);
  185. //Initialize variables
  186. m_rectTipArea.SetRectEmpty();
  187. }
  188. void CXTTipWindow::InitializeSize(const CPoint& point, BOOL bCenterHorz /*FALSE*/)
  189. {
  190. // Create a temporary window dc, we are not actually
  191. // going to paint anything, we just want to get the sizes
  192. // of the title and description text.
  193. CWindowDC dc(NULL);
  194. // Get the size of the title string.
  195. CFont* pOldFont = dc.SelectObject(&XTAuxData().fontBold);
  196. m_sizeTitle = dc.GetTabbedTextExtent(m_strTitle, m_nTabPositions, m_pnTabStopPositions);
  197. // Get the size of the description string.
  198. dc.SelectObject(&XTAuxData().font);
  199. CSize sizeDescrip(0, 0); // description text size.
  200. if (m_arStrings.GetSize() == 0)
  201. {
  202. sizeDescrip = dc.GetTabbedTextExtent(m_strDescrip, m_nTabPositions, m_pnTabStopPositions);
  203. }
  204. else
  205. {
  206. TEXTMETRIC tm;          // get the text metrics for the device context that is using the
  207. dc.GetTextMetrics(&tm); // control's font, this will give us the text height in pixels.
  208. CSize sizeTemp;
  209. int nStrings;
  210. for (nStrings = 0; nStrings < m_arStrings.GetSize(); ++nStrings)
  211. {
  212. // Strings could be empty because only a line break could be in the line.
  213. // A empty string will return zero text extend. But we still have to count this line!
  214. if (m_arStrings[nStrings].IsEmpty())
  215. sizeDescrip.cy += tm.tmHeight;
  216. else
  217. {
  218. sizeTemp = dc.GetTabbedTextExtent(m_arStrings[nStrings], m_nTabPositions, m_pnTabStopPositions);
  219. sizeDescrip.cy += sizeTemp.cy;
  220. sizeDescrip.cx = __max(sizeDescrip.cx, sizeTemp.cx);
  221. }
  222. }
  223. }
  224. // Restore GDI object.
  225. dc.SelectObject(pOldFont);
  226. // Define the width of the tip window.
  227. int nWidth = __max(m_sizeTitle.cx, sizeDescrip.cx);
  228. nWidth = (m_sizeMargin.cx * 2 + nWidth);
  229. // Define the height of the tip window.
  230. int nHeight = (m_sizeMargin.cy * 2 + ((m_strTitle.GetLength() > 0) ? m_sizeTitle.cy + m_nLineSpace : 0) + sizeDescrip.cy);
  231. // Set the sizes for the tip window and its shadow.
  232. m_rcScreenWindow.left = point.x;
  233. m_rcScreenWindow.top = point.y;
  234. m_rcScreenWindow.right = point.x + nWidth + 2; //+2 for better view
  235. m_rcScreenWindow.bottom = point.y + nHeight;
  236. if (bCenterHorz)
  237. m_rcScreenWindow.OffsetRect(-m_rcScreenWindow.Width()/2, 0);
  238. // ensure that the tip window is visible.
  239. CRect rcWork = XTPMultiMonitor()->GetWorkArea(point);
  240. CSize size = m_rcScreenWindow.Size();
  241. // move right
  242. if (m_rcScreenWindow.left < rcWork.left)
  243. {
  244. m_rcScreenWindow.left = rcWork.left;
  245. m_rcScreenWindow.right = m_rcScreenWindow.left + size.cx;
  246. }
  247. // move left
  248. else if (m_rcScreenWindow.right > rcWork.right)
  249. {
  250. m_rcScreenWindow.right = rcWork.right;
  251. m_rcScreenWindow.left = m_rcScreenWindow.right - size.cx;
  252. }
  253. // move up
  254. if (m_rcScreenWindow.bottom > rcWork.bottom)
  255. {
  256. m_rcScreenWindow.bottom = rcWork.bottom;
  257. m_rcScreenWindow.top = m_rcScreenWindow.bottom - size.cy;
  258. }
  259. // Initialize the size of the shadow rect.
  260. m_rcWindow = m_rcScreenWindow;
  261. m_rcWindow.top = 0;
  262. m_rcWindow.left = 0;
  263. m_rcWindow.right = m_rcScreenWindow.Width();
  264. m_rcWindow.bottom = m_rcScreenWindow.Height();
  265. m_rcShadow = m_rcWindow;
  266. if (m_dwTipStyle & TWS_XT_DROPSHADOW)
  267. m_rcShadow.OffsetRect(5, 5);
  268. }
  269. void CXTTipWindow::OnKillFocus(CWnd* pNewWnd)
  270. {
  271. CWnd::OnKillFocus(pNewWnd);
  272. HideTipWindow();
  273. // Repaint the area where the shadow was displayed.
  274. if (m_dwTipStyle & TWS_XT_DROPSHADOW)
  275. {
  276. m_pParentWnd->RedrawWindow(0, 0,
  277. RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  278. }
  279. }
  280. int CXTTipWindow::CheckValue(int iValue)
  281. {
  282. return ((iValue > 255) ? 255 : ((iValue < 0) ? 0 : iValue));
  283. }
  284. COLORREF CXTTipWindow::AlphaPixel(COLORREF crPixel, int i)
  285. {
  286. return RGB(
  287. CheckValue(GetRValue(crPixel)-i),
  288. CheckValue(GetGValue(crPixel)-i),
  289. CheckValue(GetBValue(crPixel)-i));
  290. }
  291. void CXTTipWindow::DrawShadowRect(CDC* pDC, const CRect& rcShadow)
  292. {
  293. if ((m_dwTipStyle & TWS_XT_ALPHASHADOW) == 0)
  294. {
  295. // Bit pattern for a monochrome brush with every
  296. // other pixel turned off
  297. WORD bits[] =
  298. {
  299. 0x0055, 0x00AA, 0x0055, 0x00AA,
  300. 0x0055, 0x00AA, 0x0055, 0x00AA
  301. };
  302. // Need a monochrome pattern bitmap
  303. CBitmap bitmap;
  304. bitmap.CreateBitmap(8, 8, 1, 1, &bits);
  305. // Create the pattern brush
  306. CBrush brush;
  307. brush.CreatePatternBrush(&bitmap);
  308. CBrush *pOldBrush = pDC->SelectObject(&brush);
  309. // Turn every other pixel to black
  310. COLORREF clrBk = pDC->SetBkColor(RGB(0x00, 0x00, 0x00));
  311. COLORREF clrText = pDC->SetTextColor(RGB(0xFF, 0xFF, 0xFF));
  312. // 0x00A000C9 is the ROP code to AND the brush with the destination
  313. pDC->PatBlt(rcShadow.left, rcShadow.top, rcShadow.Width(), rcShadow.Height(),
  314. (DWORD)0x00A000C9);         //DPa - raster code
  315. // Restore the device context
  316. pDC->SelectObject(pOldBrush);
  317. pDC->SetTextColor(clrText);
  318. pDC->SetBkColor(clrBk);
  319. brush.DeleteObject();
  320. bitmap.DeleteObject();
  321. }
  322. else
  323. {
  324. CRect rc1 = rcShadow;
  325. CRect rc2 = rcShadow;
  326. CRect rc3 = rcShadow;
  327. CRect rc4 = rcShadow;
  328. CRect rc5 = rcShadow;
  329. CRect rc6 = rcShadow;
  330. rc2.DeflateRect(1, 1);
  331. rc3.DeflateRect(2, 2);
  332. rc4.DeflateRect(3, 3);
  333. rc5.DeflateRect(4, 4);
  334. rc6.DeflateRect(5, 5);
  335. int cx = rcShadow.Width() + 5;
  336. int cy = rcShadow.Height() + 5;
  337. int x;
  338. for (x = 5; x < cx; ++x)
  339. {
  340. int y;
  341. for (y = 5; y < cy; ++y)
  342. {
  343. CPoint pt(x, y);
  344. int iAlpha = 0;
  345. // area covered by menu...continue.
  346. if (rc6.PtInRect(pt))
  347. {
  348. continue;
  349. }
  350. else if (rc5.PtInRect(pt))
  351. {
  352. iAlpha = 75;
  353. }
  354. else if (rc4.PtInRect(pt))
  355. {
  356. iAlpha = 60;
  357. }
  358. else if (rc3.PtInRect(pt))
  359. {
  360. iAlpha = 45;
  361. }
  362. else if (rc2.PtInRect(pt))
  363. {
  364. iAlpha = 30;
  365. }
  366. else if (rc1.PtInRect(pt))
  367. {
  368. iAlpha = 15;
  369. }
  370. if (iAlpha != 0)
  371. {
  372. COLORREF crAlpha = AlphaPixel(pDC->GetPixel(x, y), iAlpha);
  373. pDC->SetPixel(x, y, crAlpha);
  374. }
  375. }
  376. }
  377. }
  378. }
  379. void CXTTipWindow::OnPaint()
  380. {
  381. CPaintDC dc(this); // device context for painting
  382. // Set the background mode to transparent.
  383. dc.SetBkMode(TRANSPARENT);
  384. // Draw a shadow on the the parent window, we will need the
  385. // parent's device context to do this.
  386. if (m_dwTipStyle & TWS_XT_DROPSHADOW)
  387. DrawShadowRect(&dc, m_rcShadow);
  388. // use the system tooltip colors for text and background.
  389. dc.SetTextColor(m_crTextColor);
  390. dc.FillSolidRect(m_rcWindow, m_crBackColor);
  391. // Draw a border around the window.
  392. dc.Draw3dRect(m_rcWindow, GetXtremeColor(COLOR_3DDKSHADOW),
  393. GetXtremeColor(COLOR_3DDKSHADOW));
  394. // Draw an inner light grey border.
  395. if (m_dwTipStyle & TWS_XT_THICKBORDER)
  396. {
  397. CRect rect(m_rcWindow);
  398. rect.DeflateRect(1, 1);
  399. dc.Draw3dRect(rect, GetXtremeColor(COLOR_3DSHADOW),
  400. GetXtremeColor(COLOR_3DSHADOW));
  401. }
  402. // Draw the title text.
  403. CFont* pOldFont = dc.SelectObject(&XTAuxData().fontBold);
  404. dc.TabbedTextOut(m_sizeMargin.cx + 1, m_sizeMargin.cy, m_strTitle, m_nTabPositions,
  405. m_pnTabStopPositions, m_sizeMargin.cx + 1);
  406. // Draw the description text.
  407. dc.SelectObject(&XTAuxData().font);
  408. if (m_arStrings.GetSize() == 0)
  409. dc.TabbedTextOut(m_sizeMargin.cx + 1, m_sizeMargin.cy + ((m_strTitle.GetLength() > 0) ? m_sizeTitle.cy + m_nLineSpace : 0),
  410. m_strDescrip, m_nTabPositions, m_pnTabStopPositions, m_sizeMargin.cx + 1);
  411. else
  412. {
  413. // Get the string height for stepping through
  414. CSize sizeDesc = dc.GetTabbedTextExtent(m_arStrings[0], m_nTabPositions, m_pnTabStopPositions);
  415. // The second parameter is long because we add the height of the strings already done, and also
  416. // we don't add anything to get below the title if the length of the title is 0.
  417. int nStrings;
  418. for (nStrings = 0; nStrings < m_arStrings.GetSize(); ++nStrings)
  419. dc.TabbedTextOut(m_sizeMargin.cx + 1,
  420. m_sizeMargin.cy + (nStrings * sizeDesc.cy) + ((m_strTitle.GetLength() > 0) ? m_sizeTitle.cy + m_nLineSpace : 0),
  421. m_arStrings[nStrings], m_nTabPositions, m_pnTabStopPositions, m_sizeMargin.cx + 1);
  422. }
  423. // Restore the device context.
  424. dc.SelectObject(pOldFont);
  425. }
  426. void CXTTipWindow::OnTimer(UINT_PTR nIDEvent)
  427. {
  428. if (m_nElapseTimerEventID == nIDEvent)
  429. {
  430. // Hide the tip window.
  431. HideTipWindow();
  432. }
  433. if (m_nDelayTimerEventID == nIDEvent)
  434. {
  435. KillTimer(m_nDelayTimerEventID);
  436. if (!m_rectTipArea.IsRectNull())
  437. {
  438. //If someone moves the mouse over a tip area in the client window
  439. //it may happen that the tip delay timer will be started. During this
  440. //delay time the user may move the mouse out of the application window.
  441. //After the timer runs out the tip window will be shown but because
  442. //of the fast mouse move the cursor will not be located inside the tip area.
  443. //Because the cursor my located outside the application we will not get
  444. //the mouse move messages at CXTTipWindow::OnMouseMove().
  445. //So better check if the mouse is still located inside the tip area.
  446. //If not do not show the tip window.
  447. CRect rect = m_rectTipArea;
  448. rect.left += m_ptMousePos.x;
  449. rect.top += m_ptMousePos.y;
  450. rect.right += m_ptMousePos.x;
  451. rect.bottom += m_ptMousePos.y;
  452. CPoint pointMouse;
  453. GetCursorPos(&pointMouse);
  454. if (!rect.PtInRect(pointMouse))
  455. return;
  456. }
  457. // Show the tip window
  458. InitializeSize(m_ptMousePos, m_bCenterHorz); //Calculates m_rcScreenWindow values
  459. SetWindowPos(&wndTop, m_rcScreenWindow.left, m_rcScreenWindow.top, m_rcScreenWindow.Width(), m_rcScreenWindow.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE); //+5 because of the shadow
  460. SetCapture();
  461. m_bDelayTimerRunning = FALSE;
  462. }
  463. CWnd::OnTimer(nIDEvent);
  464. }
  465. BOOL CXTTipWindow::OnEraseBkgnd(CDC* /*pDC*/)
  466. {
  467. return TRUE;
  468. }
  469. //////////////////////////////////////////////////////////////////////////
  470. //
  471. // Hide the tip window and forward the message to the window at mouse point.
  472. //
  473. void CXTTipWindow::ForwardMessage(UINT uiMsg, UINT nFlags, CPoint point)
  474. {
  475. //  m_bMouseWasClickedSoDoNotShowTip = TRUE;
  476. HideTipWindow();
  477. CPoint pt(point);
  478. ClientToScreen(&pt);
  479. CWnd* pClick = WindowFromPoint(pt);
  480. if (!pClick->IsChild(this) && pClick != this)
  481. {
  482. LRESULT iHitTest = pClick->SendMessage(WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));
  483. if (AfxGetMainWnd() != NULL)
  484. pClick->SendMessage(WM_MOUSEACTIVATE, (LPARAM)AfxGetMainWnd()->m_hWnd, MAKELPARAM(iHitTest , uiMsg));
  485. pClick->ScreenToClient(&pt);
  486. pClick->SendMessage(uiMsg, nFlags, MAKELPARAM(pt.x, pt.y));
  487. }
  488. CWnd::OnLButtonDown(nFlags, point);
  489. }
  490. void CXTTipWindow::OnLButtonDown(UINT nFlags, CPoint point)
  491. {
  492. ForwardMessage(WM_LBUTTONDOWN, nFlags, point);
  493. }
  494. void CXTTipWindow::OnRButtonDown(UINT nFlags, CPoint point)
  495. {
  496. ForwardMessage(WM_RBUTTONDOWN, nFlags, point);
  497. }
  498. void CXTTipWindow::OnMButtonDown(UINT nFlags, CPoint point)
  499. {
  500. ForwardMessage(WM_MBUTTONDOWN, nFlags, point);
  501. }
  502. void CXTTipWindow::OnMouseMove(UINT /*nFlags*/, CPoint point)
  503. {
  504. if (!m_rectTipArea.IsRectNull() && !m_rectTipArea.PtInRect(point))
  505. HideTipWindow();
  506. }
  507. void CXTTipWindow::SetTipText(LPCTSTR lpszTitle, LPCTSTR lpszDescrip, BOOL bRedraw)
  508. {
  509. m_strTitle = lpszTitle;      //Single line
  510. // Avoid uggly outputed rectangle character in the tip window
  511. m_strDescrip = lpszDescrip;    //Could be multi-line
  512. m_strDescrip.Remove(_T('r'));
  513. if (bRedraw)
  514. {
  515. InvalidateRect(NULL);
  516. }
  517. }
  518. void CXTTipWindow::SetTextTabStopPositions(LPINT pnTabStopPositions, int nTabPositions)
  519. {
  520. //pointer to integer array containing the tab stop positions (could be a static array)
  521. m_pnTabStopPositions = pnTabStopPositions;
  522. //number of array elements
  523. m_nTabPositions = nTabPositions;
  524. }