#include "stdafx.h" #include "UILoading.h" #include using namespace DuiLib; using namespace Gdiplus; namespace { void DrawLine(Graphics* _objGraphics, PointF _objPointOne, PointF _objPointTwo, Color _objColor, int _intLineThickness) { SolidBrush brush(_objColor); Pen objPen(&brush, (Gdiplus::REAL)_intLineThickness); { objPen.SetStartCap(LineCap::LineCapRound); objPen.SetEndCap(LineCap::LineCapRound); _objGraphics->DrawLine(&objPen, _objPointOne, _objPointTwo); } } PointF GetCoordinate(PointF _objCircleCenter, int _intRadius, double _dblAngle) { double dblAngle = 3.14 * _dblAngle / 180; PointF pf(_objCircleCenter.X + _intRadius * (float)cos(dblAngle), _objCircleCenter.Y + _intRadius * (float)sin(dblAngle)); return pf; } Color Darken(Color _objColor, int _intPercent) { int intRed = _objColor.GetR(); int intGreen = _objColor.GetG(); int intBlue = _objColor.GetB(); Color color(_intPercent, min(intRed, 255), min(intGreen, 255), min(intBlue, 255)); return color; } double* GetSpokesAngles(int _intNumberSpoke) { double* Angles = new double[_intNumberSpoke]; double dblAngle = (double)360 / _intNumberSpoke; for (int shtCounter = 0; shtCounter < _intNumberSpoke; shtCounter++) { Angles[shtCounter] = (shtCounter == 0 ? dblAngle : Angles[shtCounter - 1] + dblAngle); } return Angles; } } IMPLEMENT_DUICONTROL(CLoadingUI) CLoadingUI::CLoadingUI() : m_bStop(true) , m_nTime(100) , m_nNumber(0) , m_Angles(nullptr) , m_Colors(nullptr) , m_NumberOfSpoke(10) , m_SpokeThickness(4) , m_OuterCircleRadius( 10) , m_InnerCircleRadius (8) { } CLoadingUI::~CLoadingUI() { Stop(); if(m_Angles) delete m_Angles; if(m_Colors) delete m_Colors; } LPCTSTR CLoadingUI::GetClass() const { return DUI_CTR_LOADINGCIRCLE; } LPVOID CLoadingUI::GetInterface(LPCTSTR pstrName) { if (_tcscmp(pstrName, DUI_CTR_LOADINGCIRCLE) == 0) return static_cast(this); return CControlUI::GetInterface(pstrName); } void CLoadingUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if (_tcsicmp(pstrName, _T("style") ) == 0) { LPTSTR pstr = NULL; m_nNumber = _tcstol(pstrValue, &pstr, 10); } else if (_tcsicmp(pstrName, _T("time") ) == 0) { LPTSTR pstr = NULL; m_nTime = _tcstol(pstrValue, &pstr, 10); } else if (_tcsicmp(pstrName, _T("spoke") ) == 0) { LPTSTR pstr = NULL; m_NumberOfSpoke = _tcstol(pstrValue, &pstr, 0); } else if (_tcsicmp(pstrName, _T("thickness")) == 0) { LPTSTR pstr = NULL; m_SpokeThickness = _tcstol(pstrValue, &pstr, 0); } else if (_tcsicmp(pstrName, _T("outradius")) == 0) { LPTSTR pstr = NULL; m_OuterCircleRadius = _tcstol(pstrValue, &pstr, 0); } else if (_tcsicmp(pstrName, _T("innerradius")) == 0) { LPTSTR pstr = NULL; m_InnerCircleRadius = _tcstol(pstrValue, &pstr, 0); } else if (_tcsicmp(pstrName, _T("color")) == 0) { while (*pstrValue > _T('\0') && *pstrValue <= _T(' ')) pstrValue = ::CharNext(pstrValue); if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); LPTSTR pstr = NULL; DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); m_Color.SetValue(clrColor); } else { __super::SetAttribute(pstrName, pstrValue); } } void CLoadingUI::PaintBkImage(HDC hDC) { m_CenterPoint.X = (Gdiplus::REAL)this->GetWidth() / 2; m_CenterPoint.Y = (Gdiplus::REAL)this->GetHeight() / 2; if (m_NumberOfSpoke > 0) { Image* img = new Bitmap(this->GetWidth(), this->GetHeight()); Graphics g(img); g.SetSmoothingMode(SmoothingMode::SmoothingModeHighQuality); int intPosition = m_ProgressValue; for (int intCounter = 0; intCounter < m_NumberOfSpoke; intCounter++) { intPosition = intPosition % m_NumberOfSpoke; DrawLine(&g, GetCoordinate(m_CenterPoint, m_InnerCircleRadius, m_Angles[intPosition]), GetCoordinate(m_CenterPoint, m_OuterCircleRadius, m_Angles[intPosition]), m_Colors[intCounter], m_SpokeThickness); intPosition++; } // 获得窗口的Graphics对象 Graphics gh(hDC); // 将描画好的CacheImage画到窗口上 gh.DrawImage(img, m_rcItem.left, m_rcItem.top); delete img; } } Color* CLoadingUI::GenerateColorsPallet(Color _objColor, bool _blnShadeColor, int _intNbSpoke) { Color* objColors = new Color[m_NumberOfSpoke]; byte bytIncrement = (byte)(255 / m_NumberOfSpoke); byte PERCENTAGE_OF_DARKEN = 0; for (int intCursor = 0; intCursor < m_NumberOfSpoke; intCursor++) { if (_blnShadeColor) { if (intCursor == 0 || intCursor < m_NumberOfSpoke - _intNbSpoke) { objColors[intCursor] = _objColor; } else { PERCENTAGE_OF_DARKEN += bytIncrement; if (PERCENTAGE_OF_DARKEN > 255) { PERCENTAGE_OF_DARKEN = 255; } objColors[intCursor] = Darken(_objColor, PERCENTAGE_OF_DARKEN); } } else { objColors[intCursor] = _objColor; } } return objColors; } void CLoadingUI::Start() { if (m_nTime > 0 && m_pManager && m_bStop == true) { m_pManager->SetTimer(this, kTimerLoadingId, m_nTime); } m_bStop = false; } void CLoadingUI::Stop() { m_bStop = true; if (m_pManager) { m_pManager->KillTimer(this, kTimerLoadingId); } } void CLoadingUI::Init() { CControlUI::Init(); m_Angles = GetSpokesAngles(m_NumberOfSpoke); m_Colors = GenerateColorsPallet(m_Color, true, m_NumberOfSpoke); Start(); } void DuiLib::CLoadingUI::DoEvent(TEventUI& event) { if (event.Type == UIEVENT_TIMER && event.wParam == kTimerLoadingId) { m_ProgressValue = ++m_ProgressValue % m_NumberOfSpoke; Invalidate(); } else { CControlUI::DoEvent(event); } } CControlUI* CreateLoadingControl(LPCTSTR pstrType) { if (_tcsicmp(pstrType, DUI_CTR_LOADINGCIRCLE) == 0) { return new CLoadingUI(); } return NULL; }