Click here to Skip to main content
Click here to Skip to main content

Adding progress bars to a list control

By , 2 Sep 2001
 

Sample Image - napster.jpg

Introduction

This code shows how to add a progress control to a listview control. If you want to use this code, copy listctrlex.h and listctrlex.cpp to your project and subclass it.

These files are good examples of owner-draw control and custom draw list controls. if you want to visually show various data in your listview controls (such as progress, which is done here), you'll need these.

There is another way to show a progress control in a listview control - that is embedding progress bar control in your listview control. For this case that isn't necessary because the code presented here works properly and I don't want to worry about processing child window's messages.

I implemented and tested on Windows 2000 Proffesional, Visual C++ 6.0 with Service Pack 5. Untested under Unicode.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jinhyuck Jung
Korea (Republic Of) Korea (Republic Of)
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralNeedes updatingmemberDonsw11 Dec '08 - 11:15 
THis is a good example, now you shoudl udpate it for c# since it can be a useful tool. Smile | :)
GeneralMy vote of 2memberDonsw11 Dec '08 - 11:14 
Update it for c#
GeneralIt can do more...memberMikeylas30 Oct '06 - 18:32 
Well, thank Jinhyuck Jung for the work. It seems good for the control to work. But I think it can do more, so I do some modification to the control.
 
Now it can show some text other than the percentage text, and even more, it can show some different color for the progress according to its value.
 
Maybe I will submit the codes on later if someone needs it. But the description of submitting confuses me a little. I don't know how to contact the original author.
 
So just wait...
 
Mike

GeneralIgnore the below comments (+fix)memberAnthonyJ28 Apr '03 - 7:33 
The idea of creating lots of CProgressCtrl windows sounds horribly inefficient if you're planning on displaying large datasets. Even just creating enough to fill the list seems bad (what if its resizable? - gets messy).
 
This is exactly what ownerdrawn / customdrawn lists were for - slight tweaks to the way the list is drawn. My own need for this control needs a slightly modified style of bar, so would the posters below recommend I create a derived CProgressCtrl to do the drawing too?
 
As for the column heading problems, the only problem is that GetCellRect is calculating an incorrect rectangle for column 0, because CListCtrl::GetSubItemRect() doesnt handle this case nicely. My fix for this (seems to work nicely for all the cases I've tried) is to replace GetCellRect with this:
 

BOOL CListCtrlEx::GetCellRect(int iRow, int iCol, int nArea, CRect &rect)
{
CRect colRect;
if (!GetHeaderCtrl()->GetItemRect(iCol, colRect))
return FALSE;
 
if(!GetItemRect(iRow, rect, nArea))
return FALSE;

rect.left = colRect.left;
rect.right = colRect.right;

return TRUE;
}

 
The only negative comment that I have is the name of the class - there are lots of classes called CListCtrlEx, so I'd have chosen something more descriptive - eg CProgressListCtrl.
 
--
AnthonyJ@planetquake.com
www.anthony.co.uk
GeneralMore Effecient MethodmemberZac Howland22 Mar '02 - 5:45 
Here is a more effecient method to dynamically embed progress bars into a list ctrl.   (I used a CView-derived class -- though you can do pretty much the same thing in a CListCtrl-derived class).
 
<code>
void CEmbeddedProgressTest1View::OnPaint()
{
     CListCtrl& wndList = GetListCtrl();
     CHeaderCtrl* pwndHead = wndList.GetHeaderCtrl();
 
     CClientDC dc(this);
 
     int iIndex = wndList.GetTopIndex();
     for (int i = 0; i < wndList.GetItemCount() && i < wndList.GetCountPerPage(); i++, iIndex++)
     {
          CRect rcItem;
          wndList.GetSubItemRect(i, m_iProgress, LVIR_BOUNDS, rcItem);
          CProgressCtrl* pProgress = (CProgressCtrl*)m_paProgressBars.GetAt(iIndex);
          pProgress->MoveWindow(rcItem, TRUE);
          pProgress->Invalidate();
     }
     CListView::OnPaint();
}
</code>
 
For this example, I created my Progress bars in OnInitialUpdate and set their ranges and steps there, though you can do those anywhere.   I also had a member variable (m_paProgressBars) that stored the pointers to the progress bars after creation. (The index of the pointer in the array is also the item number in the list).   Another member variable (m_iProgress), indicated the SubItem number where the progress bars should be drawn.
 
Zac Howland
GeneralHERE's the correct waymemberMike Luongo8 Dec '01 - 8:31 
I hope this earns me some brownie points on this site. Because no one has emailed me here is the solution:
 
1) Create a listview (not ownerdrawn)
2) Override the paint function using the code below
 
void CMyListView::OnPaint()
{
//CPaintDC dc(this); // device context for painting
 
CListCtrl & List = GetListCtrl();
CHeaderCtrl * pHeader = List.GetHeaderCtrl();
 
//Get the item rectangle for the subitem
// nProgress = column to draw progress control
CRect rectItem;
List.GetSubItemRect( 0, nProgress, LVIR_BOUNDS, rectItem );
 
//Get the client rectangle for finding the bottom of the column
CRect rectClient;
GetClientRect( rectClient );
 
//get the header rectangle so we know the update rectangle
CRect rectHeader;
pHeader->GetClientRect( rectHeader );
 
//readjust the item rect to equal the column rectangle
rectItem.top = rectHeader.bottom;
rectItem.bottom = rectClient.bottom;
 
//validate the region this will exclude the region during the
// OnPaint virtual call
ValidateRect( rectItem );
 
//////////////
// Draw progress controls here
// *Do not use paintdc (it validates the whole client)
CClientDC dc(this);
 
//get the item rect
int nDrawIndex = List.GetTopIndex();
for ( int nIndex = 0;
nIndex < List.GetCountPerPage();
nIndex++ )
{
//Draw item -> nDrawIndex
nDrawIndex++;
}
 
CListView::OnPaint();
}
OMG | :OMG: OMG | :OMG: OMG | :OMG: OMG | :OMG:
 
There it is! Now you know how to really draw a progress control!! And a new trick that will complement your other programming.
 
Roll eyes | :rolleyes: -Mike Luongo
GeneralRe: HERE's the correct waymemberMax Santos19 Jul '03 - 15:51 

Mike Luongo wrote:
I hope this earns me some brownie points on this site. Because no one has emailed me here is the solution:
 
I think you must create a article and submit it to codeproject, this way everyone can read it.
 
MSN:maxsnts@hotmail.com
GeneralYOU'RE DOING IT ALL WRONG!!!memberMike Luongo8 Dec '01 - 8:16 
Thanks for posting a solution to this problem, but I don't think it is correct. The object is to redraw one column with a progress control -> Not reinvent/copy drawing of the whole control.
 
I have a nice little trick for drawing only one column that won't flicker or have a million child windows and all you do is draw the progress control. It is too long to post. Anyone who needs code could email me at luongomi@msu.edu
 
Until then, please do not use this code...
Suspicious | :suss:
 
-Mike
GeneralMany bugsmemberTre20 Nov '01 - 14:29 
Dragging the columns to a different location causes many problems with the status bar and where it is painted. Also, in the 5 minutes I spent looking at this example, it appears that the location of the progress control is hard coded into the first column. This is a very poor implementation.Cry | :(( Cry | :((
GeneralRe: Many bugsmemberAnthonyJ28 Apr '03 - 7:16 
Well, I'd be interested to see what you found, since it only takes 30 seconds to change the sample to draw to later columns, and they seem to work fine. In fact, its actually the column zero case that has problems...
 
--
AnthonyJ@planetquake.com
www.anthony.co.uk

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 3 Sep 2001
Article Copyright 2001 by Jinhyuck Jung
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid