EZSnakeCtrl.cpp
上传用户:cqzhuye
上传日期:2007-01-01
资源大小:72k
文件大小:7k
源码类别:

浏览器

开发平台:

Visual C++

  1. //////
  2. // EZSnakeCtrl - An Indefinite progressctrl like netscape's status bar progress
  3. // Copyright V.Lakshmi Narasimhan,ezlux@Yahoo.com.
  4. // Feel free to use,modify,twist,turn or even 
  5. // digest the code for any non commercial purposes.
  6. // I would appreciate constructive suggestions & bug reports.
  7. // Please dont delete the above lines.
  8. ///////
  9. // EZSnakeCtrl.cpp : implementation file
  10. //
  11. #include "stdafx.h"
  12. #include "EZSnakeCtrl.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CEZSnakeCtrl
  20. CEZSnakeCtrl::CEZSnakeCtrl()
  21. {
  22. m_bReverse=FALSE;
  23. m_bTimeForTail=FALSE;
  24. m_nMax=100;
  25. m_clrBk=RGB(255,255,255);
  26. m_nSize=40;
  27. m_clrEnd=RGB(0,255,255);
  28. m_clrStart=RGB(255,0,0);
  29. m_nStep=1;
  30. m_nPos=0;
  31. m_nTail=0;
  32. }
  33. CEZSnakeCtrl::~CEZSnakeCtrl()
  34. {
  35. }
  36. BEGIN_MESSAGE_MAP(CEZSnakeCtrl, CStatic)
  37. //{{AFX_MSG_MAP(CEZSnakeCtrl)
  38. ON_WM_PAINT()
  39. //}}AFX_MSG_MAP
  40. END_MESSAGE_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CEZSnakeCtrl message handlers
  43. void CEZSnakeCtrl::SetSize(int nSize)
  44. {
  45. m_nSize=nSize;
  46. }
  47. void CEZSnakeCtrl::SetBkColor(COLORREF clrFG)
  48. {
  49. m_clrBk=clrFG;
  50. }
  51. void CEZSnakeCtrl::SetGradientFill(COLORREF clrStart, COLORREF clrEnd)
  52. {
  53. m_clrCurStart=m_clrStart=clrStart;
  54. m_clrCurEnd=m_clrEnd=clrEnd;
  55. }
  56. void CEZSnakeCtrl::SetStep(int nStep)
  57. {
  58. m_nStep=nStep;
  59. }
  60. void CEZSnakeCtrl::SetMax(int nMax)
  61. {
  62.      m_nMax=nMax;
  63. }
  64. int CEZSnakeCtrl::GetPos()
  65. {
  66. return m_nPos;
  67. }
  68. int CEZSnakeCtrl::GetStep()
  69. {
  70. return m_nStep;
  71. }
  72. int CEZSnakeCtrl::GetSize()
  73. {
  74. return m_nSize;
  75. }
  76. COLORREF CEZSnakeCtrl::GetBkColor()
  77. {
  78. return m_clrBk;
  79. }
  80. COLORREF CEZSnakeCtrl::GetGradientStartColor()
  81. {
  82. return m_clrStart;
  83. }
  84. COLORREF CEZSnakeCtrl::GetGradientEndColor()
  85. {
  86.    return m_clrEnd;
  87. }
  88. int CEZSnakeCtrl::GetTail()
  89. {
  90. return m_nTail;
  91. }
  92. BOOL CEZSnakeCtrl::IsReverse()
  93. {
  94.   return m_bReverse;
  95. }
  96. int CEZSnakeCtrl::StepIt()
  97. {
  98.    if(!m_bReverse)
  99.    {
  100.    if(m_nPos>=m_nMax)
  101.    {
  102.    m_nPos=m_nMax;
  103.    if(!m_bTimeForTail) m_bTimeForTail=TRUE;
  104.    else if(m_nTail>=m_nMax)
  105.    {
  106.    m_bTimeForTail=FALSE;
  107.    m_nPos=m_nMax-m_nStep;
  108.    m_nTail=m_nMax;
  109.                m_bReverse=TRUE;
  110.    m_clrCurStart=m_clrEnd;
  111.    m_clrCurEnd=m_clrStart;
  112.    }
  113.            else SafeStepTail();
  114.        
  115.    }
  116.    else
  117.    {
  118.        SafeStepHead();
  119.    SafeStepTail();
  120.    }
  121.    }
  122.    else
  123.    {
  124.    if(m_nPos<=0)
  125.    {
  126.    m_nPos=0;
  127.    if(!m_bTimeForTail) m_bTimeForTail=TRUE;
  128.    else if(m_nTail<=0)
  129.    {
  130.    m_bTimeForTail=FALSE;
  131.    m_nPos=m_nStep;
  132.    m_nTail=0;
  133.    m_bReverse=FALSE;
  134.    m_clrCurStart=m_clrStart;
  135.    m_clrCurEnd=m_clrEnd;
  136.    }
  137.    else
  138.    SafeStepTail();
  139.    }
  140.    else
  141.    {
  142.    SafeStepHead();
  143.    SafeStepTail();
  144.    }
  145.    }
  146.    return m_nPos;
  147. }
  148. void CEZSnakeCtrl::OnPaint() 
  149. {
  150. CDC *pdc;
  151. pdc=GetDC();
  152. CRect rect,rcLeft,rcRight,rcSnake;
  153. GetClientRect(&rect);
  154. rcLeft.CopyRect(&rect);
  155. rcRight.CopyRect(&rect);
  156. rcSnake.CopyRect(&rect); 
  157. float nTailpos=(float)m_nTail/(float)m_nMax*(float)rect.right;
  158. float nHeadpos=(float)m_nPos/(float)m_nMax*(float)rect.right;
  159. rcSnake.left=(long)(m_bReverse?nHeadpos:nTailpos);
  160. rcSnake.right=(long)(m_bReverse?nTailpos:nHeadpos);
  161. rcLeft.right=rcSnake.left;
  162. rcRight.left=rcSnake.right;
  163.     DrawGradient(pdc,rcSnake);
  164. CBrush brush;
  165. VERIFY(brush.CreateSolidBrush(m_clrBk));
  166. pdc->FillRect(&rcLeft, &brush);
  167. pdc->FillRect(&rcRight,&brush);
  168. VERIFY(brush.DeleteObject());
  169.     ReleaseDC(pdc);
  170. // Do not call CStatic::OnPaint() for painting messages
  171. }
  172. /***********************************************************
  173. //////////Modified DrawGradient from CGradientProgressControl
  174. //////////Thanks::matt weagle (mweagle@redrose.net)
  175. //////////This is the code that actually draws the snake 
  176. *************************************************************/
  177. void CEZSnakeCtrl::DrawGradient(CDC *pDC, CRect rcGrad)
  178. {
  179. RECT rectFill;    // Rectangle for filling band
  180. float fStep;              // How wide is each band?
  181. CBrush brush; // Brush to fill in the bar
  182. //CMemDC memDC(pDC);
  183. CDC* memDC=pDC;
  184. // First find out the largest color distance between the start and end colors.  This distance
  185. // will determine how many steps we use to carve up the client region and the size of each
  186. // gradient rect.
  187. int r, g, b; // First distance, then starting value
  188. float rStep, gStep, bStep; // Step size for each color
  189. // Get the color differences
  190. r = (GetRValue(m_clrCurEnd) - GetRValue(m_clrCurStart));
  191. g = (GetGValue(m_clrCurEnd) - GetGValue(m_clrCurStart));
  192. b =  (GetBValue(m_clrCurEnd) - GetBValue(m_clrCurStart));
  193. // Make the number of steps equal to the greatest distance
  194. int nSteps = max(abs(r), max(abs(g), abs(b)));
  195. // Determine how large each band should be in order to cover the
  196. // client with nSteps bands (one for every color intensity level)
  197. fStep = ((float)abs(rcGrad.right-rcGrad.left)) / (float)nSteps;
  198. // Calculate the step size for each color
  199. rStep = r/(float)nSteps;
  200. gStep = g/(float)nSteps;
  201. bStep = b/(float)nSteps;
  202. // Reset the colors to the starting position
  203. r = GetRValue(m_clrCurStart);
  204. g = GetGValue(m_clrCurStart);
  205. b = GetBValue(m_clrCurStart);
  206. // Start filling bands
  207. for (int iOnBand = 0; iOnBand < nSteps; iOnBand++) 
  208. {
  209. ::SetRect(&rectFill,
  210. (int)(rcGrad.left+iOnBand * fStep),       // Upper left X
  211. rcGrad.top,  // Upper left Y
  212. rcGrad.left+(int)((iOnBand+1) * fStep),          // Lower right X
  213. rcGrad.bottom); // Lower right Y
  214. if(rectFill.left<rcGrad.left || rectFill.right>rcGrad.right)
  215. return;
  216. // CDC::FillSolidRect is faster, but it does not handle 8-bit color depth
  217. VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));
  218. memDC->FillRect(&rectFill,&brush);
  219. VERIFY(brush.DeleteObject());
  220. }
  221. }
  222. int CEZSnakeCtrl::SafeStepHead()
  223. {
  224.    int nStep;
  225.    if(m_bReverse)
  226.    {
  227.   nStep=m_nPos-m_nStep;
  228.   if(nStep>0)
  229.   {
  230.   m_nPos-=m_nStep;
  231.   nStep=m_nStep;
  232.   }
  233.   else
  234.   {
  235.   nStep=m_nPos;
  236.   m_nPos=0;
  237.   }
  238.    }
  239.    else
  240.    {
  241.   nStep=m_nPos+m_nStep;
  242.   if(nStep<m_nMax)
  243.   {
  244.   m_nPos+=m_nStep;
  245.   nStep=m_nStep;
  246.   }
  247.   else
  248.   {
  249.   nStep=m_nMax-m_nPos;
  250.   m_nPos=m_nMax;
  251.   }
  252.    }
  253.   return nStep;
  254. }
  255. int CEZSnakeCtrl::SafeStepTail()
  256. {
  257. if(!m_bTimeForTail && ((m_bReverse && m_nMax-m_nPos<m_nSize) || (!m_bReverse && m_nPos<m_nSize)))
  258.   return 0;
  259.    int nStep;
  260.    if(m_bReverse)
  261.    {
  262.   nStep=m_nTail-m_nStep;
  263.   if(nStep>0)
  264.   {
  265.   m_nTail-=m_nStep;
  266.   nStep=m_nStep;
  267.   }
  268.   else
  269.   {
  270.   nStep=m_nTail;
  271.   m_nTail=0;
  272.   }
  273.    }
  274.    else
  275.    {
  276.   nStep=m_nTail+m_nStep;
  277.   if(nStep<m_nMax)
  278.   {
  279.   m_nTail+=m_nStep;
  280.   nStep=m_nStep;
  281.   }
  282.   else
  283.   {
  284.   nStep=m_nMax-m_nTail;
  285.   m_nTail=m_nMax;
  286.   }
  287.    }
  288.   return nStep;
  289. }
  290. void CEZSnakeCtrl::ResetProgress()
  291. {
  292. m_bReverse=FALSE;
  293. m_nTail=m_nPos=0;
  294. }
  295. int CEZSnakeCtrl::GetMax()
  296. {
  297.   return m_nMax;
  298. }