下面是个人撰写的C++源码:
************************progressListCtrl.h*********************************
#pragma once
#include <vector>
#include "def.h"
using namespace std;
// CProgressListCtrl
class CProgressListCtrl : public CListCtrl
{
DECLARE_DYNAMIC(CProgressListCtrl)
public:
CProgressListCtrl();
virtual ~CProgressListCtrl();
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
public:
void SetProgressColumnIndex(int nIndex);
private:
void GetProgressPercent(const int & nIndex, int & nMax, int & nPos);
int m_nProgressColumnIndex;
vector <CProgressCtrl *> m_ProgressList;
int m_nTop;
int m_nPerpageLastItem;
};
************************progressListCtrl.cpp*********************************
#include "stdafx.h"
#include "ProgressListCtrl.h"
// CProgressListCtrl
IMPLEMENT_DYNAMIC(CProgressListCtrl, CListCtrl)
CProgressListCtrl::CProgressListCtrl()
{
m_nProgressColumnIndex = 0;
m_nTop = 0;
m_nPerpageLastItem = 0;
}
CProgressListCtrl::~CProgressListCtrl()
{
}
BEGIN_MESSAGE_MAP(CProgressListCtrl, CListCtrl)
ON_WM_PAINT()
END_MESSAGE_MAP()
// CProgressListCtrl 消息处理程序
void CProgressListCtrl::SetProgressColumnIndex(int nIndex)
{
m_nProgressColumnIndex = nIndex;
}
void CProgressListCtrl::OnPaint()
{
int nTop = GetTopIndex();
int nTotal = GetItemCount();
int nPerpageCount = GetCountPerPage();
int nPerpageLastItem = (nPerpageCount + nTop) > nTotal ? nTotal : (nPerpageCount + nTop);
int nMax = 0, nPos = 0, nOldMax = 0, nOldLower = 0;
CHeaderCtrl * pHeader = GetHeaderCtrl();
CRect rectCol, rectProgress;
pHeader->GetItemRect(m_nProgressColumnIndex, &rectCol);
if (nPerpageCount > 0)
{
if (m_nTop != nTop || m_nPerpageLastItem != nPerpageLastItem)
{
m_nTop = nTop;
m_nPerpageLastItem = nPerpageLastItem;
int nCount = m_ProgressList.size();
for (int i = 0; i < nCount; ++i)
{
CProgressCtrl * pProgessCtrl = m_ProgressList.at(0);
pProgessCtrl->DestroyWindow();
delete pProgessCtrl;
vector<CProgressCtrl *>::iterator iter = m_ProgressList.begin();
m_ProgressList.erase(iter);
}
for (int i = nTop; i < nPerpageLastItem; ++i)
{
GetItemRect(i, &rectProgress, LVIR_LABEL);
rectProgress.left = rectCol.left;
rectProgress.right = rectCol.right;
CProgressCtrl *pProgressCtrl = new CProgressCtrl;
pProgressCtrl->Create(PBS_SMOOTH, rectProgress, this, IDC_PROGRESS_LIST + i);
GetProgressPercent(i, nMax, nPos);
pProgressCtrl->SetRange32(0, nMax);
pProgressCtrl->SetPos(nPos);
pProgressCtrl->ShowWindow(SW_SHOWNORMAL);
m_ProgressList.push_back(pProgressCtrl);
}
}
else
{
vector<CProgressCtrl *>::iterator iter = m_ProgressList.begin();
for (int i = nTop; i < nPerpageLastItem; ++i)
{
GetItemRect(i, &rectProgress, LVIR_LABEL);
rectProgress.left = rectCol.left;
rectProgress.right = rectCol.right;
GetProgressPercent(i, nMax, nPos);
(*iter)->MoveWindow(rectProgress);
(*iter)->GetRange(nOldLower, nOldMax);
if (nOldMax != nMax)
{
(*iter)->SetRange32(0, nMax);
}
(*iter)->SetPos(nPos);
++iter;
}
}
}
CListCtrl::OnPaint();
}
void CProgressListCtrl::GetProgressPercent(const int & nIndex, int & nMax, int & nPos)
{
CString strData, strMax, strPos;
int nFindBackSlash = 0;
strData = this->GetItemText(nIndex, m_nProgressColumnIndex);//format:23/100
nFindBackSlash = strData.Find('/');
if (nFindBackSlash >= 0)
{
strMax = strData.Right(strData.GetLength() - nFindBackSlash - 1);
strPos = strData.Left(nFindBackSlash);
nMax = ::wcstol(strMax.GetBuffer(), NULL, 10);
nPos = ::wcstol(strPos.GetBuffer(), NULL, 10);
}
else
{
nMax = 100;
nPos = 0;
}
}