进度条ProgressCtrl设置

新建对话框应用程序

修改对话框效果

进度条ProgressCtrl设置_第1张图片


GradientPrgssCtrlTestDlg.h : 头文件

#include "GradientProgressCtrl.h"

public:
	CGradientProgressCtrl m_cProgress;
	int m_nRange;
	BOOL m_bShowPercent;

	COLORREF m_clrText, m_clrBk, m_clrStart, m_clrEnd;

	afx_msg void OnBnClickedBtnTest();

GradientPrgssCtrlTestDlg.cpp : 实现文件

CGradientPrgssCtrlTestDlg::CGradientPrgssCtrlTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGradientPrgssCtrlTestDlg::IDD, pParent)
	, m_nRange(0)
	, m_bShowPercent(FALSE)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CGradientPrgssCtrlTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PROGRESS1, m_cProgress);
	DDX_Text(pDX, IDC_EDIT1, m_nRange);
	DDX_Check(pDX, IDC_CHECK1, m_bShowPercent);
}

BEGIN_MESSAGE_MAP(CGradientPrgssCtrlTestDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_TEST, &CGradientPrgssCtrlTestDlg::OnBnClickedBtnTest)
END_MESSAGE_MAP()

BOOL CGradientPrgssCtrlTestDlg::OnInitDialog()

	// TODO: 在此添加额外的初始化代码
	m_clrText = m_cProgress.GetTextColor();
	m_clrBk = m_cProgress.GetBkColor();
	m_clrStart = m_cProgress.GetStartColor();
	m_clrEnd = m_cProgress.GetEndColor();

void CGradientPrgssCtrlTestDlg::OnBnClickedBtnTest()
{
	UpdateData(TRUE);

	//设置参数
	m_cProgress.SetRange(0, m_nRange);
	m_cProgress.ShowPercent(m_bShowPercent);

	m_cProgress.SetStartColor(m_clrStart);
	m_cProgress.SetEndColor(m_clrEnd);
	m_cProgress.SetTextColor(m_clrText);
	m_cProgress.SetBkColor(m_clrBk);

	for (int i=0; i <= m_nRange; i++)
	{
		PeekAndPump();
		m_cProgress.SetPos(i);
	}
}

全局函数

BOOL PeekAndPump();

BOOL PeekAndPump()
{
	static MSG msg;

	while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
		if (!AfxGetApp()->PumpMessage()) {
			::PostQuitMessage(0);
			return FALSE;
		}	
	}

	return TRUE;
}

效果

进度条ProgressCtrl设置_第2张图片 进度条ProgressCtrl设置_第3张图片


附相关文件:

GradientProgressCtrl.h

#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()
};

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

//{{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

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

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

/////////////////////////////////////////////////////////////////////////////
// CGradientProgressCtrl

CGradientProgressCtrl::CGradientProgressCtrl()
{
	//初始化
	m_nLower = 0;
	m_nUpper = 100;
	m_nCurrentPosition = 0;
	m_nStep = 10;	
	
	m_clrStart	= COLORREF(RGB(255, 0,0));
	m_clrEnd =	 COLORREF(RGB(0,0,255));
	m_clrBkGround = ::GetSysColor(COLOR_3DFACE);
	m_clrText = COLORREF(RGB(255, 255, 255));

	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() 
{
	CPaintDC dc(this); // device context for painting

	//如果进度条的当前位置不正确,则渐变到背景色
	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;
	}


	//获得需要渐变的区域
	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("%.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);
	}
}


//设置进度条范围
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);


	// 开始填充颜色
	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(m_clrBkGround));
			memDC.FillRect(&rectFill, &brush);
			VERIFY(brush.DeleteObject());
			return;
		}
	}
}

BOOL CGradientProgressCtrl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

MemDC.h

#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_

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


class CMemDC : public CDC
{
public:
	
	//构造内存设备场景
	CMemDC(CDC* pDC) : CDC()
    {
		ASSERT(pDC != NULL);
		
		m_pDC = pDC;
		m_pOldBitmap = NULL;
        m_bMemDC = !pDC->IsPrinting();
		
        if (m_bMemDC)
		{
            pDC->GetClipBox(&m_rect);
            CreateCompatibleDC(pDC);
            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
			m_pOldBitmap = SelectObject(&m_bitmap);
            SetWindowOrg(m_rect.left, m_rect.top);
        }
		else	
		{
            m_bPrinting = pDC->m_bPrinting;
            m_hDC		= pDC->m_hDC;
            m_hAttribDC = pDC->m_hAttribDC;
        }
	}
	
	//析构
	~CMemDC()
    {
		if (m_bMemDC) {	
			m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
				this, m_rect.left, m_rect.top, SRCCOPY);
			
            SelectObject(m_pOldBitmap);
		} else {
            m_hDC = m_hAttribDC = NULL;
		}
	}
	
    CMemDC* operator->() {return this;}
	
    operator CMemDC*() {return this;}

private:
	CBitmap  m_bitmap;		
    CBitmap* m_pOldBitmap;	
    CDC*     m_pDC;		
    CRect    m_rect;		
    BOOL     m_bMemDC;		
};

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

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

#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)


你可能感兴趣的:(C/C++程序开发)