demo下载地址:http://download.youkuaiyun.com/download/qianpeng4/9985772
#pragma once
#include
using namespace Gdiplus;
// CCircleProgress
class CCircleProgress : public CStatic
{
DECLARE_DYNAMIC(CCircleProgress)
public:
CCircleProgress();
virtual ~CCircleProgress();
public:
ULONG_PTR gdiplusToken;
Color* m_colors;
int m_percent;
int m_penWidth;
CPoint m_centerPoint;
int m_elementCount;
int m_insideRadius;
int m_outsideRadius;
CRect m_rect;
int m_offSet;
CString m_strPercent;
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
void Init(CWnd* parentWnd,int nCount, int elementWidth, COLORREF color,CRect rect);
void SetPercent(int percent);
void SetColors(COLORREF color);
Color Darken(Color color, int percent);
void SetCircleAppearance(int insideRadius, int outsideRadius);
afx_msg void OnTimer(UINT_PTR nIDEvent);
void StartProgress();
void StopProgress();
};
// CircleProgress.cpp : 实现文件
//
#include "stdafx.h"
#include "MFCApplication1.h"
#include "CircleProgress.h"
#include
#define PI 3.1415926535897932384626433832795028
// CCircleProgress
IMPLEMENT_DYNAMIC(CCircleProgress, CStatic)
CCircleProgress::CCircleProgress()
{
GdiplusStartupInput gdiplusStartupInput;
//初始化GDI+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
m_colors = NULL;
m_percent = 0;
m_penWidth = 0;
m_centerPoint = 0;
m_elementCount = 0;
m_insideRadius = 0;
m_outsideRadius = 0;
m_rect = 0;
m_offSet = 0;
m_strPercent = L"0%";
}
CCircleProgress::~CCircleProgress()
{
GdiplusShutdown(gdiplusToken);
}
BEGIN_MESSAGE_MAP(CCircleProgress, CStatic)
ON_WM_PAINT()
ON_WM_TIMER()
END_MESSAGE_MAP()
// CCircleProgress 消息处理程序
void CCircleProgress::OnPaint()
{
CPaintDC dc(this); // device context for painting
CDC memdc;
memdc.CreateCompatibleDC(NULL);
CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap(&dc, m_rect.Width(), m_rect.Height());
memdc.SelectObject(memBitmap);
memdc.FillSolidRect(CRect(0,0,m_rect.Width(),m_rect.Height()), RGB(240, 240, 240));
Graphics graphics(memdc);
graphics.SetSmoothingMode(SmoothingModeDefault); //描边时消除锯齿
byte byIncrement = (byte)(255 / 12);
byte iPercent = 255;
double angle = (double)360 / m_elementCount;
Pen initPen(Darken(GetPixel(dc, 1, 1), 255), m_penWidth);
initPen.SetStartCap(LineCapRound); //设置线帽样式
initPen.SetEndCap(LineCapRound);
for (int iCounter = 0; iCounter < m_elementCount; iCounter++)
{
Point startP, endP;
startP.X = m_centerPoint.x + m_insideRadius * (float)cos((PI*(1 + iCounter)*angle) / 180);
startP.Y = m_centerPoint.y + m_insideRadius * (float)sin((PI*(1 + iCounter)*angle) / 180);
endP.X = m_centerPoint.x + m_outsideRadius * (float)cos((PI*(1 + iCounter)*angle) / 180);
endP.Y = m_centerPoint.y + m_outsideRadius * (float)sin((PI*(1 + iCounter)*angle) / 180);
graphics.DrawLine(&initPen, startP, endP);
}
for (int iCounter = 0; iCounter < m_elementCount; iCounter++)
{
Point startP, endP;
startP.X = m_centerPoint.x + m_insideRadius * (float)cos((PI*(1 + iCounter)*angle) / 180);
startP.Y = m_centerPoint.y + m_insideRadius * (float)sin((PI*(1 + iCounter)*angle) / 180);
endP.X = m_centerPoint.x + m_outsideRadius * (float)cos((PI*(1 + iCounter)*angle) / 180);
endP.Y = m_centerPoint.y + m_outsideRadius * (float)sin((PI*(1 + iCounter)*angle) / 180);
int index = (iCounter + m_offSet) % m_elementCount;
Pen pen(m_colors[index], m_penWidth);
pen.SetStartCap(LineCapRound); //设置线帽样式
pen.SetEndCap(LineCapRound);
graphics.DrawLine(&pen, startP, endP);
}
//画百分比
Gdiplus::FontFamily fontFamily(L"宋体");
Gdiplus::Font font(&fontFamily,20,FontStyleRegular,UnitPixel);
StringFormat stringformat;
stringformat.SetAlignment(StringAlignmentCenter);
stringformat.SetLineAlignment(StringAlignmentCenter);
SolidBrush brush(Color(255, 0x66, 0xcc, 0x66));
graphics.DrawString(m_strPercent, -1, &font, RectF(0, 0, m_rect.Width(), m_rect.Height()), &stringformat, &brush);
BitBlt(dc, 0, 0, m_rect.Width(), m_rect.Height(), memdc, 0, 0, SRCCOPY);
}
void CCircleProgress::Init(CWnd* parentWnd, int nCount, int elementWidth, COLORREF color, CRect rect)
{
m_rect = rect;
m_penWidth = elementWidth;
m_centerPoint.SetPoint(rect.Width() / 2, rect.Height() / 2);
m_elementCount = nCount;
m_colors = new Color[nCount];
SetColors(color);
RECT rc;
rc.top = rect.top; rc.bottom = rect.bottom; rc.left = rect.left; rc.right = rect.right;
Create(L"", SS_OWNERDRAW | WS_CHILDWINDOW, rc, parentWnd);
ShowWindow(SW_SHOW);
}
void CCircleProgress::SetPercent(int percent)
{
m_percent = percent;
m_strPercent.Format(L"%d%%", percent);
if (percent == 100)
{
StopProgress();
}
else
{
RedrawWindow();
}
}
void CCircleProgress::SetColors(COLORREF color)
{
byte byteIncrement = byte(255 / m_elementCount);
Color argb;
argb.SetFromCOLORREF(color);
for (int i = 0; i < m_elementCount; i++)
{
m_colors[i] = Darken(argb, byteIncrement*(i + 1));
}
}
Color CCircleProgress::Darken(Color color, int percent)
{
return Color(percent, color.GetR(), color.GetG(), color.GetB());
}
void CCircleProgress::SetCircleAppearance(int insideRadius, int outsideRadius)
{
m_insideRadius = insideRadius;
m_outsideRadius = outsideRadius;
SetWindowPos(this, m_rect.left, m_rect.top, outsideRadius * 2 + 6, outsideRadius * 2 + 6, SWP_NOZORDER);
m_rect = CRect(m_rect.left, m_rect.top,m_rect.left + outsideRadius * 2 + 6, m_rect.top + outsideRadius * 2 + 6);
m_centerPoint = CPoint(m_rect.Width() / 2 , m_rect.Height() / 2 );
Invalidate(TRUE);
}
void CCircleProgress::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1)
{
m_offSet = (m_offSet + 1) % m_elementCount;
Invalidate(FALSE);
}
CStatic::OnTimer(nIDEvent);
}
void CCircleProgress::StartProgress()
{
SetTimer(1, 200, NULL);
}
void CCircleProgress::StopProgress()
{
KillTimer(1);
}