LineChartCtrl.cpp
上传用户:hnxinke
上传日期:2013-04-11
资源大小:94k
文件大小:5k
源码类别:

绘图程序

开发平台:

Visual C++

  1. // LineChartCtrl.cpp : implementation file
  2. //
  3. // Written by Yuheng Zhao (yuheng@ministars.com) 
  4. // http://www.ministars.com
  5. // The original idea and part of the code from Ken C. Len's CHistogramCtrl
  6. // http://www.codeguru.com/controls/histogram_control.shtml
  7. //
  8. // Copyright (c) 1998.
  9. //
  10. // This code may be used in compiled form in any way you desire. This
  11. // file may be redistributed unmodified by any means PROVIDING it is 
  12. // not sold for profit without the authors written consent, and 
  13. // providing that this notice and the authors name is included. If 
  14. // the source code in  this file is used in any commercial application 
  15. // then a simple email would be nice.
  16. //
  17. // This file is provided "as is" with no expressed or implied warranty.
  18. // The author accepts no liability if it causes any damage whatsoever.
  19. // It's free - so you get what you pay for.
  20. //
  21. #include "stdafx.h"
  22. #include "LineChartCtrl.h"
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CLineChartCtrl
  30. CLineChartCtrl::CLineChartCtrl()
  31. {
  32. CLineChartCtrl::RegisterWndClass(AfxGetInstanceHandle());
  33. }
  34. CLineChartCtrl::~CLineChartCtrl()
  35. {
  36. int nCount = m_items.GetSize();
  37. for (int i = 0; i < nCount; i++)
  38. delete m_items.GetAt(i);
  39. m_items.RemoveAll();
  40. }
  41. BEGIN_MESSAGE_MAP(CLineChartCtrl, CWnd)
  42. //{{AFX_MSG_MAP(CLineChartCtrl)
  43. ON_WM_PAINT()
  44. //}}AFX_MSG_MAP
  45. END_MESSAGE_MAP()
  46. BOOL CLineChartCtrl::RegisterWndClass(HINSTANCE hInstance)
  47. {
  48. WNDCLASS wc;
  49. wc.lpszClassName = "LINE_CHART_CTRL"; // matches class name in client
  50. wc.hInstance = hInstance;
  51. wc.lpfnWndProc = ::DefWindowProc;
  52. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  53. wc.hIcon = 0;
  54. wc.lpszMenuName = NULL;
  55. wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH);
  56. wc.style = CS_GLOBALCLASS; // To be modified
  57. wc.cbClsExtra = 0;
  58. wc.cbWndExtra = 0;
  59. return (::RegisterClass(&wc) != 0);
  60. }
  61. void CLineChartCtrl::InvalidateCtrl()
  62. {
  63. CClientDC dc(this);
  64. CRect rcClient;
  65. GetClientRect(rcClient);
  66. if (m_MemDC.GetSafeHdc() == NULL)
  67. {
  68. m_MemDC.CreateCompatibleDC(&dc);
  69. m_Bitmap.CreateCompatibleBitmap(&dc,rcClient.Width(),rcClient.Height());
  70. m_MemDC.SelectObject(m_Bitmap);
  71. // draw scale
  72. m_MemDC.SetBkColor(RGB(0,0,0));
  73. CBrush bkBrush(HS_CROSS,RGB(0,128,0));
  74. m_MemDC.FillRect(rcClient,&bkBrush);
  75. }
  76. InvalidateRect(rcClient, FALSE);
  77. }
  78. UINT CLineChartCtrl::SetPos(int nIndex, UINT nPos)
  79. {
  80. if (nIndex >= m_items.GetSize())
  81. return 0;
  82. CLineChartItem* pItem = m_items.GetAt(nIndex);
  83. if (nPos > pItem->m_nUpper)
  84. nPos = pItem->m_nUpper;
  85. if (nPos < pItem->m_nLower)
  86. nPos = pItem->m_nLower;
  87. pItem->m_nOldPos = pItem->m_nPos;
  88. pItem->m_nPos = nPos;
  89. return pItem->m_nOldPos;
  90. }
  91. void CLineChartCtrl::OnPaint() 
  92. {
  93. CPaintDC dc(this); // device context for painting
  94. CRect rcClient;
  95. GetClientRect(rcClient);
  96. // draw scale
  97. if (m_MemDC.GetSafeHdc() != NULL)
  98. dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY);
  99. }
  100. void CLineChartCtrl::DrawSpike()
  101. {
  102. CRect rcClient;
  103. GetClientRect(rcClient);
  104. if (m_MemDC.GetSafeHdc() != NULL)
  105. {
  106. m_MemDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &m_MemDC, 4, 0, SRCCOPY);
  107. // draw scale
  108. CRect rcRight = rcClient;
  109. rcRight.left = rcRight.right - 4;
  110. m_MemDC.SetBkColor(RGB(0,0,0));
  111. CBrush bkBrush(HS_HORIZONTAL,RGB(0,128,0));  
  112. m_MemDC.FillRect(rcRight,&bkBrush);
  113. static BOOL bDrawVerticle = FALSE;
  114. bDrawVerticle = !bDrawVerticle;
  115. // Draw Verticle lines only every two steps
  116. if (bDrawVerticle)
  117. {
  118. CPen pen(PS_SOLID, 1, RGB(0,128,0));
  119. CPen* pOldPen = m_MemDC.SelectObject(&pen);
  120. m_MemDC.MoveTo(CPoint(rcClient.right-2, rcClient.top));
  121. m_MemDC.LineTo(CPoint(rcClient.right-2, rcClient.bottom));
  122. m_MemDC.SelectObject(pOldPen);
  123. }
  124. int nCount = m_items.GetSize();
  125. CLineChartItem* pItem;
  126. CPoint ptOld, ptNew;
  127. for (int i=0; i<nCount; i++)
  128. {
  129. pItem = m_items.GetAt(i);
  130. UINT  nRange = pItem->m_nUpper - pItem->m_nLower;
  131. ptOld.x = rcRight.left-1; // Minus one to make sure to draw inside the area
  132. ptNew.x = rcRight.right-1;
  133. ptOld.y = (int)((((float)(nRange - pItem->m_nOldPos))/(float)nRange)
  134. * (float)rcRight.Height());
  135. ptNew.y = (int)((((float)(nRange - pItem->m_nPos))/(float)nRange)
  136. * (float)rcRight.Height());
  137. CPen pen(PS_SOLID, 1, pItem->m_colorLine);
  138. CPen* pOldPen = m_MemDC.SelectObject(&pen);
  139. m_MemDC.MoveTo(ptOld);
  140. m_MemDC.LineTo(ptNew);
  141. m_MemDC.SelectObject(pOldPen);
  142. }
  143. }
  144. }
  145. BOOL CLineChartCtrl::Add(COLORREF color, UINT Upper, UINT Lower)
  146. {
  147. CLineChartItem* pItem = new CLineChartItem;
  148. pItem->m_colorLine = color;
  149. pItem->m_nLower = Lower;
  150. pItem->m_nUpper = Upper;
  151. pItem->m_nPos = 0;
  152. pItem->m_nOldPos = 0;
  153. try 
  154. {
  155. m_items.Add(pItem);
  156. InvalidateCtrl();
  157. return TRUE;
  158. }
  159. catch (CMemoryException* e)
  160. {
  161. if (pItem !=NULL) 
  162. delete pItem;
  163. e->Delete();
  164. return FALSE;
  165. }
  166. }
  167. void CLineChartCtrl::Go()
  168. {
  169. DrawSpike();
  170. Invalidate(FALSE);
  171. }