www.gusucode.com > 基于VC编程界面编程高级应用技术源码程序 > VC界面编程高级应用技术/code/2/TaxExpert/ProgressBar.cpp

    #include "stdafx.h"
#include "ProgressBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CProgressBar, CProgressCtrl)
BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
//{{AFX_MSG_MAP(CProgressBar)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CProgressBar::CProgressBar()
{
    m_Rect.SetRect(0,0,0,0);
}

CProgressBar::CProgressBar
(LPCTSTR strMessage, int nSize,int MaxValue, BOOL bSmooth)
{
    Create(strMessage, nSize, MaxValue, bSmooth);
}

CProgressBar::~CProgressBar()
{
    Clear();
}

CStatusBar* CProgressBar::GetStatusBar()
{
    CStatusBar* pStatusBar = NULL;
	CWnd *pMainWnd = AfxGetMainWnd();
    if (!pMainWnd)
        return NULL;
	//获取窗口的状态栏	
    pStatusBar = (CStatusBar*) pMainWnd->\
	GetDescendantWindow(AFX_IDW_STATUS_BAR);
    if (!pStatusBar || !pStatusBar->IsKindOf(RUNTIME_CLASS(CStatusBar))) 
        return NULL;
   return pStatusBar;
}

BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize, int MaxValue, 
                          BOOL bSmooth /*=FALSE*/)
{
    BOOL bSuccess = FALSE;
	 CStatusBar *pStatusBar = GetStatusBar();
    if (!pStatusBar) return FALSE;
	 DWORD dwStyle = WS_CHILD|WS_VISIBLE;
#ifdef PBS_SMOOTH    
    if (bSmooth)
		dwStyle |= PBS_SMOOTH;
#endif
	// 将状态栏做为进度条的父窗口
    bSuccess = CProgressCtrl::Create(dwStyle, CRect(0,0,0,0), pStatusBar, 1);
    ASSERT(bSuccess);
    if (!bSuccess) return FALSE;
    SetRange(0, MaxValue);
    SetStep(1);
	m_strMessage = strMessage;
    m_nSize      = nSize;
	//重绘进度条
    Resize();
	return TRUE;
}

void CProgressBar::Clear()
{
    if (!IsWindow(GetSafeHwnd()))
        return;
	ModifyStyle(WS_VISIBLE, 0);
	CString str;
    str.LoadString(AFX_IDS_IDLEMESSAGE);
	CStatusBar *pStatusBar = GetStatusBar();
    if (pStatusBar) 
		pStatusBar->SetWindowText(str);
}

BOOL CProgressBar::SetText(LPCTSTR strMessage)
{ 
    m_strMessage = strMessage; 
    return Resize(); 
}

BOOL CProgressBar::SetSize(int nSize)
{
    m_nSize = nSize; 
    return Resize();
}

COLORREF CProgressBar::SetBarColour(COLORREF clrBar)
{
#ifdef PBM_SETBKCOLOR
    if (!IsWindow(GetSafeHwnd()))
        return 0;
	
    SendMessage(PBM_SETBARCOLOR, 0, (LPARAM) clrBar);
#else
    UNUSED(clrBar);
    return CLR_DEFAULT;
#endif
}

COLORREF CProgressBar::SetBkColour(COLORREF clrBk)
{
#ifdef PBM_SETBKCOLOR
    if (!IsWindow(GetSafeHwnd()))
        return 0;
	
    return SendMessage(PBM_SETBKCOLOR, 0, (LPARAM) clrBk);
#else
    UNUSED(clrBk);
    return CLR_DEFAULT;
#endif
}

BOOL CProgressBar::SetRange(int nLower, int nUpper, int nStep)    
{    
    if (!IsWindow(GetSafeHwnd()))
        return FALSE;
	
#ifdef PBM_SETRANGE32
    ASSERT(-0x7FFFFFFF <= nLower && nLower <= 0x7FFFFFFF);
    ASSERT(-0x7FFFFFFF <= nUpper && nUpper <= 0x7FFFFFFF);
    SendMessage(PBM_SETRANGE32, (WPARAM) nLower, (LPARAM) nUpper);
#else
    ASSERT(0 <= nLower && nLower <= 65535);
    ASSERT(0 <= nUpper && nUpper <= 65535);
    CProgressCtrl::SetRange(nLower, nUpper);
#endif
    CProgressCtrl::SetStep(nStep);
    return TRUE;
}

int CProgressBar::SetPos(int nPos)     
{
    if (!IsWindow(GetSafeHwnd()))
        return 0;
	
#ifdef PBM_SETRANGE32
    ASSERT(-0x7FFFFFFF <= nPos && nPos <= 0x7FFFFFFF);
#else
    ASSERT(0 <= nPos && nPos =< 65535);
#endif
    ModifyStyle(0,WS_VISIBLE);
    return CProgressCtrl::SetPos(nPos);
}

int  CProgressBar::OffsetPos(int nPos) 
{ 
    if (!IsWindow(GetSafeHwnd()))
        return 0;
	
    ModifyStyle(0,WS_VISIBLE);
    return CProgressCtrl::OffsetPos(nPos);
}

int  CProgressBar::SetStep(int nStep)
{ 
    if (!IsWindow(GetSafeHwnd()))
        return 0;
	
    ModifyStyle(0,WS_VISIBLE);
    return CProgressCtrl::SetStep(nStep);    
}

int  CProgressBar::StepIt()             
{ 
    if (!IsWindow(GetSafeHwnd()))
        return 0;
    ModifyStyle(0,WS_VISIBLE);
    return CProgressCtrl::StepIt();    
}

BOOL CProgressBar::Resize() 
{
    if (!IsWindow(GetSafeHwnd()))
        return FALSE;
	
    CStatusBar *pStatusBar = GetStatusBar();
    if (!pStatusBar) return FALSE;
	
    // 重绘进度条文本
    if (IsWindowVisible())
	{
        pStatusBar->SetWindowText(m_strMessage);
        pStatusBar->UpdateWindow();
    }
	
    //计算文本的宽度
    CClientDC dc(pStatusBar);
    CFont *pOldFont = dc.SelectObject(pStatusBar->GetFont());
    CSize size = dc.GetTextExtent(m_strMessage);
    int margin = dc.GetTextExtent(_T(" ")).cx * 2;
    dc.SelectObject(pOldFont);
	
    CRect rc;
    pStatusBar->GetItemRect (0, rc);
    rc.left = size.cx + 2*margin;
    rc.right = rc.left + (rc.right - rc.left) * m_nSize / 100;
    if (rc.right < rc.left)
		rc.right = rc.left;
    int Height = rc.bottom - rc.top;
    rc.bottom -= Height/10;
    rc.top    += Height/10;
	
     if (rc != m_Rect) {
        MoveWindow(&rc);
		m_Rect = rc;
    }
	
    return TRUE;
}
BOOL CProgressBar::OnEraseBkgnd(CDC* pDC) 
{
    Resize();
    return CProgressCtrl::OnEraseBkgnd(pDC);
}