You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
605 lines
12 KiB
C++
605 lines
12 KiB
C++
// XTPProgressCtrl.cpp : implementation of the CXTPProgressCtrl class.
|
|
//
|
|
// This file is a part of the XTREME CONTROLS MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPResourceImage.h"
|
|
#include "Common/XTPWinThemeWrapper.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
#include "../Util/XTPControlTheme.h"
|
|
#include "XTPProgressCtrl.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define TID_TIMER 101
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPProgressCtrl, CProgressCtrl)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPScrollBar
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CXTPProgressCtrl::CXTPProgressCtrl()
|
|
{
|
|
m_bPreSubclassInit = TRUE;
|
|
m_nMarqueePos = 0;
|
|
m_nMarqueeDelay = 0;
|
|
m_nTheme = xtpControlThemeDefault;
|
|
m_bFlatStyle = FALSE;
|
|
m_bUseVisualStyle = TRUE;
|
|
|
|
m_themeProgress = new CXTPWinThemeWrapper();
|
|
}
|
|
|
|
CXTPProgressCtrl::~CXTPProgressCtrl()
|
|
{
|
|
SAFE_DELETE(m_themeProgress);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPProgressCtrl, CProgressCtrl)
|
|
ON_WM_CREATE()
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_SYSCOLORCHANGE()
|
|
|
|
ON_MESSAGE(PBM_SETMARQUEE, OnStartMarquee)
|
|
ON_MESSAGE(PBM_STEPIT, OnStepIt)
|
|
ON_MESSAGE(PBM_SETPOS, OnSetPos)
|
|
ON_WM_TIMER()
|
|
END_MESSAGE_MAP()
|
|
|
|
void CXTPProgressCtrl::Init()
|
|
{
|
|
RefreshMetrics();
|
|
|
|
ModifyStyleEx(WS_EX_STATICEDGE | WS_EX_CLIENTEDGE, 0);
|
|
SetWindowPos(NULL, 0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
|
SetWindowText(_T(""));
|
|
|
|
m_nMarqueePos = 0;
|
|
|
|
SendMessage(WM_NCPAINT);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPProgressCtrl::PreSubclassWindow()
|
|
{
|
|
CProgressCtrl::PreSubclassWindow();
|
|
|
|
if (m_bPreSubclassInit)
|
|
{
|
|
// Initialize the control.
|
|
Init();
|
|
}
|
|
}
|
|
|
|
int CXTPProgressCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CProgressCtrl::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
// Initialize the control.
|
|
Init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL CXTPProgressCtrl::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if (!CProgressCtrl::PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
// When creating controls dynamically Init() must
|
|
// be called from OnCreate() and not from
|
|
// PreSubclassWindow().
|
|
|
|
m_bPreSubclassInit = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPProgressCtrl::RefreshMetrics()
|
|
{
|
|
RefreshXtremeColors();
|
|
m_clrBorderNormal.SetStandardValue(GetSysColor(COLOR_3DSHADOW));
|
|
|
|
if (m_nTheme == xtpControlThemeFlat)
|
|
{
|
|
m_clrBorderNormal.SetStandardValue(GetSysColor(COLOR_WINDOWFRAME));
|
|
|
|
}
|
|
|
|
if (m_nTheme == xtpControlThemeOffice2003)
|
|
{
|
|
XTPCurrentSystemTheme systemTheme = XTPColorManager()->GetCurrentSystemTheme();
|
|
switch (systemTheme)
|
|
{
|
|
case xtpSystemThemeBlue:
|
|
case xtpSystemThemeRoyale:
|
|
case xtpSystemThemeAero:
|
|
m_clrBorderNormal.SetStandardValue(RGB(127, 157, 185));
|
|
break;
|
|
|
|
case xtpSystemThemeOlive:
|
|
m_clrBorderNormal.SetStandardValue(RGB(164, 185, 127));
|
|
break;
|
|
|
|
case xtpSystemThemeSilver:
|
|
m_clrBorderNormal.SetStandardValue(RGB(165, 172, 178));
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_themeProgress->OpenTheme(0, L"PROGRESS");
|
|
|
|
m_clrBarColor.SetStandardValue(GetXtremeColor(COLOR_HIGHLIGHT));
|
|
m_clrTextColor.SetStandardValue(GetXtremeColor(COLOR_HIGHLIGHTTEXT));
|
|
m_clrBackColor.SetStandardValue(GetXtremeColor(COLOR_3DFACE));
|
|
}
|
|
|
|
COLORREF CXTPProgressCtrl::GetBackColor()
|
|
{
|
|
return m_clrBackColor;
|
|
}
|
|
|
|
void CXTPProgressCtrl::DrawNcBorders(CDC* pDC, CRect rc)
|
|
{
|
|
COLORREF clrBack = GetBackColor();
|
|
|
|
if (m_bUseVisualStyle && m_themeProgress->IsAppThemed())
|
|
return;
|
|
|
|
if (m_bFlatStyle)
|
|
return;
|
|
|
|
if (m_nTheme == xtpControlThemeDefault)
|
|
{
|
|
pDC->DrawEdge(rc, EDGE_SUNKEN, BF_RECT);
|
|
return;
|
|
}
|
|
if (m_nTheme == xtpControlThemeOffice2000)
|
|
{
|
|
pDC->Draw3dRect(rc, m_clrBorderNormal, GetXtremeColor(COLOR_BTNHIGHLIGHT));
|
|
}
|
|
else
|
|
{
|
|
COLORREF clrBorder = m_clrBorderNormal;
|
|
pDC->Draw3dRect(rc, clrBorder, clrBorder);
|
|
}
|
|
|
|
rc.DeflateRect(1, 1);
|
|
pDC->Draw3dRect(rc, clrBack, clrBack);
|
|
}
|
|
|
|
|
|
void CXTPProgressCtrl::OnSysColorChange()
|
|
{
|
|
CProgressCtrl::OnSysColorChange();
|
|
RefreshMetrics();
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
|
|
void CXTPProgressCtrl::SetBarColor(COLORREF clrBarColor)
|
|
{
|
|
m_clrBarColor.SetCustomValue(clrBarColor);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
COLORREF CXTPProgressCtrl::SetBkColor(COLORREF clrNew)
|
|
{
|
|
m_clrBackColor.SetCustomValue(clrNew);
|
|
Invalidate(FALSE);
|
|
return m_clrBackColor;
|
|
}
|
|
|
|
|
|
COLORREF CXTPProgressCtrl::SetTextColor(COLORREF clrNew)
|
|
{
|
|
m_clrTextColor.SetCustomValue(clrNew);
|
|
Invalidate(FALSE);
|
|
return m_clrTextColor;
|
|
}
|
|
|
|
|
|
void CXTPProgressCtrl::DoPaint(CDC* pDC)
|
|
{
|
|
CRect rcClient;
|
|
GetClientRect(rcClient);
|
|
|
|
BOOL bThemed = m_bUseVisualStyle && m_themeProgress->IsAppThemed();
|
|
BOOL bVertical = GetStyle() & PBS_VERTICAL;
|
|
|
|
if (!bThemed && m_nTheme == xtpControlThemeResource && !bVertical)
|
|
{
|
|
PaintOffice2007(pDC);
|
|
return;
|
|
}
|
|
|
|
if (!bThemed && !m_bFlatStyle)
|
|
{
|
|
DrawNcBorders(pDC, rcClient);
|
|
rcClient.DeflateRect(2, 2);
|
|
}
|
|
|
|
|
|
pDC->FillSolidRect(rcClient, GetBackColor());
|
|
|
|
|
|
if (bThemed)
|
|
{
|
|
m_themeProgress->DrawThemeBackground(*pDC, bVertical ? PP_BARVERT : PP_BAR, 0, rcClient, NULL);
|
|
}
|
|
|
|
BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater();
|
|
|
|
int x, dxSpace, dxBlock, nBlocks;
|
|
int iStart, iEnd;
|
|
|
|
BOOL bSmooth = GetStyle() & PBS_SMOOTH;
|
|
BOOL bMarquee = GetStyle() & PBS_MARQUEE;
|
|
|
|
if (bThemed)
|
|
{
|
|
if (bVertical)
|
|
rcClient.DeflateRect(3, 4);
|
|
else
|
|
rcClient.DeflateRect(4, 3);
|
|
}
|
|
else if (!m_bFlatStyle && m_nTheme == xtpControlThemeDefault)
|
|
{
|
|
// give 1 pixel around the bar
|
|
rcClient.DeflateRect(1, 1);
|
|
}
|
|
else if (!m_bFlatStyle && (m_nTheme == xtpControlThemeFlat) && bSmooth)
|
|
{
|
|
// give 1 pixel around the bar
|
|
rcClient.InflateRect(1, 1);
|
|
}
|
|
|
|
CRect rc = rcClient;
|
|
|
|
if (bMarquee)
|
|
{
|
|
dxBlock = rc.Height() * 2 / 3;
|
|
dxSpace = bVista ? 0 : 2;
|
|
|
|
if (bThemed)
|
|
{
|
|
m_themeProgress->GetThemeInt(0, 0, TMT_PROGRESSCHUNKSIZE, &dxBlock);
|
|
m_themeProgress->GetThemeInt(0, 0, TMT_PROGRESSSPACESIZE, &dxSpace);
|
|
}
|
|
|
|
rc.left = m_nMarqueePos + rcClient.left;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
if (rc.left >= rcClient.right)
|
|
rc.left = rcClient.left;
|
|
|
|
rc.right = rc.left + dxBlock;
|
|
|
|
if (rc.right > rcClient.right)
|
|
rc.right = rcClient.right;
|
|
|
|
if (bThemed)
|
|
{
|
|
m_themeProgress->DrawThemeBackground(*pDC, PP_CHUNK, 0, rc, NULL);
|
|
}
|
|
else
|
|
{
|
|
pDC->FillSolidRect(rc, m_clrBarColor);
|
|
}
|
|
rc.left = rc.right + dxSpace;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PBRANGE range;
|
|
SendMessage(PBM_GETRANGE, (WPARAM) FALSE, (LPARAM) &range);
|
|
|
|
int iLow = range.iLow;
|
|
int iHigh = range.iHigh;
|
|
int iPos = (int)SendMessage(PBM_GETPOS);
|
|
|
|
|
|
if (bVertical)
|
|
{
|
|
iStart = rc.top;
|
|
iEnd = rc.bottom;
|
|
dxBlock = (rc.right - rc.left) * 2 / 3;
|
|
}
|
|
else
|
|
{
|
|
iStart = rc.left;
|
|
iEnd = rc.right;
|
|
dxBlock = (rc.bottom - rc.top) * 2 / 3;
|
|
}
|
|
|
|
x = MulDiv(iEnd - iStart, iPos - iLow, iHigh - iLow);
|
|
|
|
dxSpace = 2;
|
|
|
|
if (bThemed)
|
|
{
|
|
m_themeProgress->GetThemeInt(0, 0, TMT_PROGRESSCHUNKSIZE, &dxBlock);
|
|
m_themeProgress->GetThemeInt(0, 0, TMT_PROGRESSSPACESIZE, &dxSpace);
|
|
}
|
|
|
|
if (dxBlock == 0)
|
|
dxBlock = 1; // avoid div by zero
|
|
|
|
if (!bThemed && bSmooth)
|
|
{
|
|
dxBlock = 1;
|
|
dxSpace = 0;
|
|
}
|
|
|
|
nBlocks = (x + (dxBlock + dxSpace) - 1) / (dxBlock + dxSpace); // round up
|
|
|
|
for (int i = 0; i < nBlocks; i++)
|
|
{
|
|
if (bVertical)
|
|
{
|
|
|
|
rc.top = rc.bottom - dxBlock;
|
|
|
|
// are we past the end?
|
|
if (rc.bottom <= rcClient.top)
|
|
break;
|
|
|
|
if (rc.top <= rcClient.top)
|
|
rc.top = rcClient.top + 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
rc.right = rc.left + dxBlock;
|
|
|
|
// are we past the end?
|
|
if (rc.left >= rcClient.right)
|
|
break;
|
|
|
|
if (rc.right >= rcClient.right)
|
|
rc.right = rcClient.right - 1;
|
|
}
|
|
|
|
if (bThemed)
|
|
{
|
|
m_themeProgress->DrawThemeBackground(*pDC, bVertical ? PP_CHUNKVERT : PP_CHUNK, 0, rc, NULL);
|
|
}
|
|
else
|
|
{
|
|
pDC->FillSolidRect(&rc, m_clrBarColor);
|
|
}
|
|
|
|
if (bVertical)
|
|
{
|
|
rc.bottom = rc.top - dxSpace;
|
|
}
|
|
else
|
|
{
|
|
rc.left = rc.right + dxSpace;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bThemed)
|
|
return;
|
|
|
|
CString strText;
|
|
GetWindowText(strText);
|
|
|
|
if (!strText.IsEmpty())
|
|
{
|
|
CRect rcText(rcClient);
|
|
rcText.DeflateRect(2, 0);
|
|
|
|
pDC->SetTextColor(m_clrTextColor);
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
CXTPFontDC font(pDC, CWnd::GetFont());
|
|
pDC->DrawText(strText, rcText, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | DT_VCENTER);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CXTPProgressCtrl::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
if (m_bUseVisualStyle && m_themeProgress->IsAppThemed() && m_themeProgress->IsAppThemeReady())
|
|
{
|
|
return (BOOL)Default();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPProgressCtrl::OnPaint()
|
|
{
|
|
if (m_bUseVisualStyle && m_themeProgress->IsAppThemed() && m_themeProgress->IsAppThemeReady())
|
|
{
|
|
Default();
|
|
}
|
|
else
|
|
{
|
|
CPaintDC dcPaint(this);
|
|
CXTPBufferDC dc(dcPaint);
|
|
|
|
DoPaint(&dc);
|
|
}
|
|
}
|
|
|
|
void CXTPProgressCtrl::PaintOffice2007(CDC* pDC)
|
|
{
|
|
CXTPResourceImages* pImages = XTPResourceImages();
|
|
|
|
CXTPResourceImage* pImage = pImages->LoadFile(_T("PROGRESSTRACK"));
|
|
ASSERT(pImage);
|
|
if (!pImage)
|
|
return;
|
|
|
|
CRect rc;
|
|
GetClientRect(rc);
|
|
|
|
pDC->FillSolidRect(rc, GetBackColor());
|
|
|
|
pImage->DrawImage(pDC, rc, pImage->GetSource(), CRect(2, 2, 2, 2), 0xFF00FF);
|
|
|
|
PBRANGE range;
|
|
SendMessage(PBM_GETRANGE, (WPARAM) FALSE, (LPARAM) &range);
|
|
|
|
int nLower = range.iLow;
|
|
int nUpper = range.iHigh;
|
|
int nPos = (int)SendMessage(PBM_GETPOS);
|
|
|
|
|
|
rc.DeflateRect(2, 2);
|
|
|
|
int nWidth = rc.Width();
|
|
|
|
int x = MulDiv(nWidth, nPos - nLower, nUpper - nLower);
|
|
|
|
pImage = pImages->LoadFile(_T("PROGRESSCHUNK"));
|
|
ASSERT(pImage);
|
|
if (!pImage)
|
|
return;
|
|
|
|
CRect rcSrc(pImage->GetSource());
|
|
rcSrc.right -= 4;
|
|
|
|
CRect rcDest(rc.left, rc.top, rc.left + x, rc.bottom);
|
|
|
|
if (rcDest.Width() < rcSrc.Width())
|
|
rcSrc.left = rcSrc.right - rcDest.Width();
|
|
|
|
pImage->DrawImage(pDC, rcDest, rcSrc, CRect(2, 2, 2, 2), 0xFF00FF);
|
|
|
|
if (rc.left + x < rc.right - 1)
|
|
{
|
|
int nShadow = min(4, rc.right - rc.left - x);
|
|
rcSrc = CRect(rcSrc.right, rcSrc.top, rcSrc.right + nShadow, rcSrc.bottom);
|
|
|
|
rcDest = CRect(rcDest.right, rcDest.top, rcDest.right + nShadow, rcDest.bottom);
|
|
|
|
pImage->DrawImage(pDC, rcDest, rcSrc, CRect(0, 2, 0, 2), 0xFF00FF);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
LRESULT CXTPProgressCtrl::OnStartMarquee(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
m_nMarqueePos = 0;
|
|
m_nMarqueeDelay = 0;
|
|
|
|
if (((GetStyle() & PBS_MARQUEE) == 0))
|
|
return Default();
|
|
|
|
if (m_bUseVisualStyle && m_themeProgress->IsAppThemed() && m_themeProgress->IsAppThemeReady())
|
|
return Default();
|
|
|
|
|
|
BOOL bMarquee = wParam && (lParam > 0);
|
|
m_nMarqueePos = 0;
|
|
|
|
KillTimer(TID_TIMER);
|
|
|
|
if (bMarquee)
|
|
{
|
|
m_nMarqueeDelay = (UINT)lParam;
|
|
SetTimer(TID_TIMER, m_nMarqueeDelay, NULL);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
void CXTPProgressCtrl::DoStep(int nStep)
|
|
{
|
|
CXTPClientRect rcClient(this);
|
|
|
|
BOOL bVista = XTPSystemVersion()->IsWinVistaOrGreater();
|
|
int dxBlock = (rcClient.Height() - 2) * 2 / 3;
|
|
int nSpace = bVista ? 0 : 2;
|
|
|
|
m_nMarqueePos += (dxBlock + nSpace) * nStep;
|
|
|
|
if (m_nMarqueePos > rcClient.right)
|
|
m_nMarqueePos = 0;
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPProgressCtrl::OnTimer(UINT_PTR nIDEvent)
|
|
{
|
|
if (nIDEvent == TID_TIMER && (GetStyle() & PBS_MARQUEE))
|
|
{
|
|
DoStep(m_nMarqueeDelay > 50 ? 1 : 2);
|
|
return;
|
|
}
|
|
|
|
CWnd::OnTimer(nIDEvent);
|
|
}
|
|
|
|
LRESULT CXTPProgressCtrl::OnStepIt(WPARAM /*wParam*/, LPARAM /*lParam*/)
|
|
{
|
|
if (((GetStyle() & PBS_MARQUEE) == 0))
|
|
return Default();
|
|
|
|
if (m_bUseVisualStyle && m_themeProgress->IsAppThemed() && m_themeProgress->IsAppThemeReady())
|
|
return Default();
|
|
|
|
DoStep(1);
|
|
return 1;
|
|
}
|
|
|
|
LRESULT CXTPProgressCtrl::OnSetPos(WPARAM /*wParam*/, LPARAM /*lParam*/)
|
|
{
|
|
LRESULT lResult = Default();
|
|
|
|
Invalidate(FALSE);
|
|
return lResult;
|
|
}
|
|
|
|
|
|
void CXTPProgressCtrl::SetUseVisualStyle(BOOL bUseVisualStyle/* = TRUE*/)
|
|
{
|
|
m_bUseVisualStyle = bUseVisualStyle;
|
|
|
|
RefreshMetrics();
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPProgressCtrl::SetTheme(XTPControlTheme nTheme)
|
|
{
|
|
m_nTheme = nTheme;
|
|
|
|
m_bUseVisualStyle = (m_nTheme == xtpControlThemeDefault);
|
|
|
|
RefreshMetrics();
|
|
|
|
if (m_hWnd) Invalidate(FALSE);
|
|
}
|