进度条重绘(CProgressCtrl)

一个简单的进度条重绘,这个是基于MFC的CProgressCtrl做的

#if !defined(AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_)
#define AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// EnhProgressCtrl.h : header file
//
#include "MemDC.h"

/////////////////////////////////////////////////////////////////////////////
// CGradientProgressCtrl window

class CGradientProgressCtrl : public CProgressCtrl
{
// Construction
public:
    CGradientProgressCtrl();

// Attributes
public:
// Attributes

    void SetRange(int nLower, int nUpper);
    int SetPos(int nPos);
    int SetStep(int nStep);
    int StepIt(void);

// Operations
public:

    // Set Functions
    void SetTextColor(COLORREF color)   {m_clrText = color;}
    void SetBkColor(COLORREF color)      {m_clrBkGround = color;}
    void SetStartColor(COLORREF color)  {m_clrStart = color;}
    void SetEndColor(COLORREF color)    {m_clrEnd = color;}

    // Show the percent caption
    void ShowPercent(BOOL bShowPercent = TRUE)  {m_bShowPercent = bShowPercent;}

    // Get Functions
    COLORREF GetTextColor(void) {return m_clrText;}
    COLORREF GetBkColor(void)        {return m_clrBkGround;}
    COLORREF GetStartColor(void)    {return m_clrStart;}
    COLORREF GetEndColor(void)  {return m_clrEnd;}


// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CGradientProgressCtrl)
    //}}AFX_VIRTUAL

// Implementation
public:
    virtual ~CGradientProgressCtrl();

    // Generated message map functions
protected:
    void DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth); 
    int m_nLower, m_nUpper, m_nStep, m_nCurrentPosition;
    COLORREF    m_clrStart, m_clrEnd, m_clrBkGround, m_clrText;
    BOOL m_bShowPercent;
    //{{AFX_MSG(CGradientProgressCtrl)
    afx_msg void OnPaint();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()


#if 1 ///add zp 20170213
    void Redrew();
#endif
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_)

实现

// GradientProgressCtrl.cpp : implementation file
// Download by http://www.codefans.net
#include "stdafx.h"
#include "GradientProgressCtrl.h"

#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGradientProgressCtrl
extern CFont *g_DisplayFont32;
CGradientProgressCtrl::CGradientProgressCtrl()
{
    //初始化
    m_nLower = 0;
    m_nUpper = 100;
    m_nCurrentPosition = 0;
    m_nStep = 10;   

    m_clrStart  = COLORREF(RGB(0,255,0));
    m_clrEnd =   COLORREF(RGB(255,0,0));
    m_clrBkGround = COLORREF(RGB(255, 255, 255));
    m_clrText = COLORREF(RGB(0,0,0));

    m_bShowPercent = FALSE;
}

CGradientProgressCtrl::~CGradientProgressCtrl()
{
}


BEGIN_MESSAGE_MAP(CGradientProgressCtrl, CProgressCtrl)
    //{{AFX_MSG_MAP(CGradientProgressCtrl)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGradientProgressCtrl message handlers

void CGradientProgressCtrl::OnPaint() 
{
#ifdef NEW_PROGRESS ///modify zp 20170213 18:30:20 之前使用的是纯颜色,修改后使用的是图片
    //Redrew();
    CPaintDC dc(this);
#else
    CPaintDC dc(this); // device context for painting

    //如果进度条的当前位置不正确,则渐变到背景色
    if (m_nCurrentPosition <= m_nLower || m_nCurrentPosition > m_nUpper)
    {
        CRect rect;
        GetClientRect(rect);
        CBrush brush;
        brush.CreateSolidBrush(RGB(255,255,255));
        dc.FillRect(&rect, &brush);
        VERIFY(brush.DeleteObject());
        return;
    }

    //获得需要渐变的区域
    CRect rectClient;
    GetClientRect(&rectClient);
    float maxWidth((float)m_nCurrentPosition/(float)m_nUpper * (float)rectClient.right);

    //画渐变颜色
    DrawGradient(&dc, rectClient, (int)maxWidth);

    //如果需要显示百分数,则显示
    if (m_bShowPercent)
    {
        CString percent;
        percent.Format(_T("%.0f%%"), 100.0f*(float)m_nCurrentPosition/(float)m_nUpper);
        dc.SetTextColor(RGB(0, 0, 0));
        dc.SetBkMode(TRANSPARENT);
        dc.SelectObject(g_DisplayFont32);
        dc.DrawText(percent, &rectClient, DT_VCENTER |  DT_CENTER | DT_SINGLELINE);
    }
#endif
}

#if 1 add zp 20170213
void CGradientProgressCtrl::Redrew()
{
    PAINTSTRUCT ps;//声明一个绘画区域
    CDC *pDC=BeginPaint(&ps);//把绘画区域选入设备上下文并开始
    int AdrPos=GetPos();//获取进度条的进度位置
    CString StrPos;//声明字符串,用于显示进度条的进度
    StrPos.Format(_T("%d%%"),AdrPos);//把进度位置复制到StrPos
    CRect ClientRC;
    GetClientRect(&ClientRC);//获取客户区矩形
    CSize CsText=pDC->GetTextExtent(StrPos);//获取显示StrPos的规模大小
    int nX=(ClientRC.Width()-CsText.cx )/2;//获取显示字符串的X
    int nY=(ClientRC.Height()-CsText.cy )/2;//获取显示字符串的Y
    pDC->SetBkMode(TRANSPARENT);//设置背景模式为透明
    int nMin,nMax;//声明进度条的最大最小限制
    GetRange(nMin,nMax);//获取限制
    double Every=(double)ClientRC.Width()/(nMax-nMin);//获取单位刻度
    int Now=Every*AdrPos;//当前长度
    CRect LeftRC,RightRC;//声明进度条区域和空白区域
    LeftRC=RightRC=ClientRC;
    LeftRC.right =Now;//进度条区域
    RightRC.left =Now;//空白区域

    CBitmap bitmap;
    //bitmap.LoadBitmap(IDB_BITMAP_aqua);
    bitmap.LoadBitmap(IDB_BITMAP_prg);
    CBrush brushQueen(&bitmap);
    pDC->FillRect(LeftRC,&brushQueen);//画进度条区域
    pDC->FillRect(RightRC,&(CBrush)RGB(120,120,120));//画空白区域

    pDC->SetTextColor(RGB(255,0,0));//设置文本颜色
    //pDC->TextOutA(nX,nY,StrPos);//写文本
    pDC->TextOut(nX,nY,StrPos);//写文本
    ReleaseDC(pDC);//销毁设备上下文
    EndPaint(&ps);//结束绘画区域绘画

    //  CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CWnd::OnPaint() for painting messages
}
#endif

//设置进度条范围
void CGradientProgressCtrl:: SetRange(int nLower, int nUpper)
{
    m_nLower = nLower;
    m_nUpper = nUpper;
    m_nCurrentPosition = nLower;
    CProgressCtrl::SetRange(nLower, nUpper);
}

//设置进度条的位置
int CGradientProgressCtrl:: SetPos(int nPos)
{
    m_nCurrentPosition = nPos;
    return (CProgressCtrl::SetPos(nPos));
}

//设置进度条的步长
int CGradientProgressCtrl:: SetStep(int nStep)
{
    m_nStep = nStep;
    return (CProgressCtrl::SetStep(nStep));
}

int CGradientProgressCtrl:: StepIt(void)
{
    m_nCurrentPosition += m_nStep;
    return (CProgressCtrl::StepIt());
}

//在适当区域画渐变颜色
void CGradientProgressCtrl::DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth)
{
    RECT rectFill;             
    float fStep;              
    CBrush brush;           


    CMemDC memDC(pDC);

    //找到其实颜色和结束颜色之间的最大颜色值,决定渐变步长等
    int r, g, b;                            
    float rStep, gStep, bStep;      

    r = (GetRValue(m_clrEnd) - GetRValue(m_clrStart));
    g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart));
    b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));

    int nSteps = max(abs(r), max(abs(g), abs(b)));

    fStep = (float)rectClient.right / (float)nSteps;

    //计算每个颜色的步长
    rStep = r/(float)nSteps;
    gStep = g/(float)nSteps;
    bStep = b/(float)nSteps;

    r = GetRValue(m_clrStart);
    g = GetGValue(m_clrStart);
    b = GetBValue(m_clrStart);

#if 0 //modify zp 20170213 使用图片填充进度条
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP_prg);
    CBrush brushQueen(&bitmap);
    memDC->FillRect(&rectFill,&brushQueen);//画进度条区域
#else
    // 开始填充颜色
    for (int iOnBand = 0; iOnBand < nSteps; iOnBand++) 
    {       
        ::SetRect(&rectFill,
                    (int)(iOnBand * fStep),       
                     0,                                  
                    (int)((iOnBand+1) * fStep),         
                    rectClient.bottom+1);           

        VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));
        memDC.FillRect(&rectFill,&brush);
        VERIFY(brush.DeleteObject());

        if (rectFill.right > nMaxWidth)
        {
            ::SetRect(&rectFill, rectFill.right, 0, rectClient.right, rectClient.bottom);
            VERIFY(brush.CreateSolidBrush(RGB(255,255,255)));
            memDC.FillRect(&rectFill, &brush);
            VERIFY(brush.DeleteObject());
            return;
        }
    }
#endif
}

BOOL CGradientProgressCtrl::OnEraseBkgnd(CDC* pDC) 
{
    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值