新建对话框应用程序
修改对话框效果
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();
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()
// 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;
}
附相关文件:
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 : 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;
}
#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_)