一个带刻度的CProcessCtrl

本文介绍了一个自定义进度条控件的实现方法,包括如何根据当前进度动态调整显示区域,使用渐变填充来呈现丰富的视觉效果,并可根据需求显示百分比指示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是OnPaint:

void CScaleProgressCtrl::OnPaint()
{
 CPaintDC dc(this); // device context for painting

 // TODO: Add your message handler code here

 // If the current positionis  invalid then we should fade into the  background
 if (m_nCurrentPosition <= m_nLower || m_nCurrentPosition >= m_nUpper)
 {
  CRect rect;
  GetClientRect(rect);
  CBrush brush;
  brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE));
  dc.FillRect(&rect, &brush);
  VERIFY(brush.DeleteObject());
  return;
 }


 // Figure out what part should be visible so we can stop the gradient when needed
 CRect rectClient;
 GetClientRect(&rectClient);
 float maxWidth((float)m_nCurrentPosition/(float)m_nUpper * (float)rectClient.right);


 // Draw the Scale

 DrawScale(&dc, rectClient, (int)maxWidth);

 // Show percent indicator if needed
 if (m_bShowPercent)
 {
  CString percent;
  percent.Format("%.0f%%", 100.0f*(float)m_nCurrentPosition/(float)m_nUpper);
  dc.SetTextColor(m_clrText);
  dc.SetBkMode(TRANSPARENT);
  dc.DrawText(percent, &rectClient, DT_VCENTER |  DT_CENTER | DT_SINGLELINE);
 }

 // Do not call CProgressCtrl::OnPaint() for painting messages

画刻度:

void CScaleProgressCtrl::DrawScale(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth)
{
 RECT rectFill;      // Rectangle for filling band
 float fStep;              // How wide is each band?
 CBrush brush;   // Brush to fill in the bar 

 
 CMemDC memDC(pDC);

 // First find out the largest color distance between the start and end colors.  This distance
 // will determine how many steps we use to carve up the client region and the size of each
 // gradient rect.
 int r, g, b;       // First distance, then starting value
 float rStep, gStep, bStep;  // Step size for each color

 // Get the color differences
 r = (GetRValue(m_clrEnd) - GetRValue(m_clrStart));
 g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart));
 b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));


 // Make the number of steps equal to the greatest distance
 int nSteps = max(abs(r), max(abs(g), abs(b)));

 // Determine how large each band should be in order to cover the
 // client with nSteps bands (one for every color intensity level)
 fStep = (float)rectClient.right / (float)nSteps;

 // Calculate the step size for each color
 rStep = r/(float)nSteps;
 gStep = g/(float)nSteps;
 bStep = b/(float)nSteps;

 // Reset the colors to the starting position
 r = GetRValue(m_clrStart);
 g = GetGValue(m_clrStart);
 b = GetBValue(m_clrStart);


 // Start filling bands
 for (int iOnBand = 0; iOnBand < nSteps; iOnBand++)
 {
  
  ::SetRect(&rectFill,
     (int)(iOnBand * fStep),       // Upper left X
      0,          // Upper left Y
     (int)((iOnBand+1) * fStep),          // Lower right X
     rectClient.bottom+1);   // Lower right Y
 
  // CDC::FillSolidRect is faster, but it does not handle 8-bit color depth
  VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));
  memDC.FillRect(&rectFill,&brush);
  VERIFY(brush.DeleteObject());


  // If we are past the maximum for the current position we need to get out of the loop.
  // Before we leave, we repaint the remainder of the client area with the background color.
  if (rectFill.right > nMaxWidth)
  {
   ::SetRect(&rectFill, rectFill.right, 0, rectClient.right, rectClient.bottom);
   VERIFY(brush.CreateSolidBrush(m_clrBkGround));
   memDC.FillRect(&rectFill, &brush);
   VERIFY(brush.DeleteObject());
   return;
  }
 }
}

各变量:

int m_nLower, m_nUpper, m_nStep, m_nCurrentPosition;
 COLORREF m_clrStart, m_clrEnd, m_clrBkGround, m_clrText;
 BOOL m_bShowPercent;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值