How does one implement a progressbar in listview

Hello there

Im wanting to put in a progressbar inside a listview. The progress bars will be in certain rows aligned to a certain column, for example Napster or Aimster.

How is it done, anyone know?

I believe it was the CustomDraw method but I didnt know how it works.

Ben Iti
Who is Participating?
DMNConnect With a Mentor Commented:
Here is MY answer from PAQ's:

Here is a few steps to make your wish to be true.

1. Make new project. Place TListView on the form.
2. Double click your ListView and add some items and subitems to it. Each item should have one subitem,
contains integer per-cent value.

Item: Item1
SubItem: 20

Item: Item2
SubItem: 80

Item: Item3
SubItem: 50

3. Close items editor, rightclick listview, start columns editor. Add 2 (two) columns.

4. Set ViewStyle of your listview to vsReport.

5. DO NOT set OwnerDraw property to TRUE. Leave it false, otherwise yor OnCustomDrawSubItem will never

6. Add next handler to OnCustomDrawSubItem:

procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
 var DefaultDraw: Boolean);
 if (SubItem=1) then
     for i:=0 to SubItem-1 do
       Rect.Left := Rect.Left+Sender.Column[i].Width;
     Rect2.Right := Rect2.Left+w;
     Rect.Right := Rect.Left+v*w div 100;
     with Sender.Canvas do

7. Enjoy!!!!!!!!!!!!!!!!!!!!!!!!!!!

On D3's version of TListView there is no CustomDraw method or property, so I cannot help with that (i.e. if your version has one). However, the principle is the following (Win API-level):

Whenever drawing is do be done on the list-view component Windows posts a notify message to the owner of the list-view (normally your form) saying "I am going to draw the list-view. Do you want to do anything special?". If you respond with "Yes" the API-way then Windows will keep on notifying you about each phase of the draw process and you will have the chance to do your own painting and that includes drawing the progress bar where required.

The whole process iss rather complicated and probably you are far better off if the version of Delphi you are using _has_ that CustomDraw property. However, as I said (sorry), you will probably get help on that from someone with a newer version of Delphi.

So, why you cannot just place ProgressBar (I prefer Gauge) control on listview. All you need it set the Parent property and set the control position.

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Ben_itiAuthor Commented:
Yeah hi Slavak

What do you mean by set control position. How do I do that?
So far its working, its there but in the wrong position.
Please reply

Ben Iti
try override OnCustomDrawSubItem event like this:

procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
 R   : TRect;
 I   : Integer;
 P   : Integer;
 If (SubItem <> 1) Then Exit;  // check for right column

 DefaultDraw := False;

 R := Item.DisplayRect(drBounds);

 For I := 0 To SubItem - 1 Do
  R.Left := R.Left + ListView1.Columns[I].Width;

 R.Right := R.Left + ListView1.Columns[SubItem].Width;
 R := Rect(R.Left + 1, R.Top + 1, R.Right - 1, R.Bottom - 1);

 ListView1.Canvas.Brush.Color := clBlack;

 P := Random(100);  // set gauge position here

 R.Right := R.Left + (ListView1.Columns[SubItem].Width * P) div 100;
 R := Rect(R.Left + 1, R.Top + 1, R.Right - 1, R.Bottom - 1);

 ListView1.Canvas.Brush.Color := Random($FFFFFF);
 ListView1.Canvas.Brush.Color := ListView1.Color;
Good, DMN. But what a difference?

Oops - sorry
Ben_itiAuthor Commented:
Thanks both of you's
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.