GradientProgressCtrl.cpp
上传用户:aokegd
上传日期:2009-12-14
资源大小:1276k
文件大小:4k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // GradientProgressCtrl.cpp : implementation file
  2. #include "stdafx.h"
  3. #include "GradientProgressCtrl.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CGradientProgressCtrl
  11. CGradientProgressCtrl::CGradientProgressCtrl()
  12. {
  13. //初始化
  14. m_nLower = 0;
  15. m_nUpper = 100;
  16. m_nCurrentPosition = 0;
  17. m_nStep = 10;
  18. m_clrStart = COLORREF(RGB(255, 0,0));
  19. m_clrEnd =  COLORREF(RGB(0,0,255));
  20. m_clrBkGround = ::GetSysColor(COLOR_3DFACE);
  21. m_clrText = COLORREF(RGB(255, 255, 255));
  22. m_bShowPercent = FALSE;
  23. }
  24. CGradientProgressCtrl::~CGradientProgressCtrl()
  25. {
  26. }
  27. BEGIN_MESSAGE_MAP(CGradientProgressCtrl, CProgressCtrl)
  28. //{{AFX_MSG_MAP(CGradientProgressCtrl)
  29. ON_WM_PAINT()
  30. ON_WM_ERASEBKGND()
  31. //}}AFX_MSG_MAP
  32. END_MESSAGE_MAP()
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CGradientProgressCtrl message handlers
  35. void CGradientProgressCtrl::OnPaint() 
  36. {
  37. CPaintDC dc(this); // device context for painting
  38. //如果进度条的当前位置不正确,则渐变到背景色
  39. if (m_nCurrentPosition <= m_nLower || m_nCurrentPosition >= m_nUpper)
  40. {
  41. CRect rect;
  42. GetClientRect(rect);
  43. CBrush brush;
  44. brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE));
  45. dc.FillRect(&rect, &brush);
  46. VERIFY(brush.DeleteObject());
  47. return;
  48. }
  49. //获得需要渐变的区域
  50. CRect rectClient;
  51. GetClientRect(&rectClient);
  52. float maxWidth((float)m_nCurrentPosition/(float)m_nUpper * (float)rectClient.right);
  53. //画渐变颜色
  54. DrawGradient(&dc, rectClient, (int)maxWidth);
  55. //如果需要显示百分数,则显示
  56. if (m_bShowPercent)
  57. {
  58. CString percent;
  59. percent.Format("%.0f%%", 100.0f*(float)m_nCurrentPosition/(float)m_nUpper);
  60. dc.SetTextColor(m_clrText);
  61. dc.SetBkMode(TRANSPARENT);
  62. dc.DrawText(percent, &rectClient, DT_VCENTER |  DT_CENTER | DT_SINGLELINE);
  63. }
  64. }
  65. //设置进度条范围
  66. void CGradientProgressCtrl:: SetRange(int nLower, int nUpper)
  67. {
  68. m_nLower = nLower;
  69. m_nUpper = nUpper;
  70. m_nCurrentPosition = nLower;
  71. CProgressCtrl::SetRange(nLower, nUpper);
  72. }
  73. //设置进度条的位置
  74. int CGradientProgressCtrl:: SetPos(int nPos)
  75. {
  76. m_nCurrentPosition = nPos;
  77. return (CProgressCtrl::SetPos(nPos));
  78. }
  79. //设置进度条的步长
  80. int CGradientProgressCtrl:: SetStep(int nStep)
  81. {
  82. m_nStep = nStep;
  83. return (CProgressCtrl::SetStep(nStep));
  84. }
  85. int CGradientProgressCtrl:: StepIt(void)
  86. {
  87. m_nCurrentPosition += m_nStep;
  88. return (CProgressCtrl::StepIt());
  89. }
  90. //在适当区域画渐变颜色
  91. void CGradientProgressCtrl::DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth)
  92. {
  93. RECT rectFill;    
  94. float fStep;              
  95. CBrush brush;
  96. CMemDC memDC(pDC);
  97. //找到其实颜色和结束颜色之间的最大颜色值,决定渐变步长等
  98. int r, g, b;
  99. float rStep, gStep, bStep;
  100. r = (GetRValue(m_clrEnd) - GetRValue(m_clrStart));
  101. g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart));
  102. b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));
  103. int nSteps = max(abs(r), max(abs(g), abs(b)));
  104. fStep = (float)rectClient.right / (float)nSteps;
  105. //计算每个颜色的步长
  106. rStep = r/(float)nSteps;
  107. gStep = g/(float)nSteps;
  108. bStep = b/(float)nSteps;
  109. r = GetRValue(m_clrStart);
  110. g = GetGValue(m_clrStart);
  111. b = GetBValue(m_clrStart);
  112. // 开始填充颜色
  113. for (int iOnBand = 0; iOnBand < nSteps; iOnBand++) 
  114. {
  115. ::SetRect(&rectFill,
  116. (int)(iOnBand * fStep),       
  117.  0,  
  118. (int)((iOnBand+1) * fStep),         
  119. rectClient.bottom+1);
  120. VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));
  121. memDC.FillRect(&rectFill,&brush);
  122. VERIFY(brush.DeleteObject());
  123. if (rectFill.right > nMaxWidth)
  124. {
  125. ::SetRect(&rectFill, rectFill.right, 0, rectClient.right, rectClient.bottom);
  126. VERIFY(brush.CreateSolidBrush(m_clrBkGround));
  127. memDC.FillRect(&rectFill, &brush);
  128. VERIFY(brush.DeleteObject());
  129. return;
  130. }
  131. }
  132. }
  133. BOOL CGradientProgressCtrl::OnEraseBkgnd(CDC* pDC) 
  134. {
  135. return TRUE;
  136. }