Solved

Need working code for getting TProgressBar on TListView

Posted on 2011-09-10
4
1,219 Views
Last Modified: 2012-05-12
I want to be able to place Progress Bars (TProgressBar) onto List Views (TListView) in Delphi, and I can find a lot of incomplete guides on how to do this.  Most source code I can find does not tackle the fact that sometimes people might need to scroll the ListView window.  The best code I can find at present is attached, however, the progress bars don't repaint correctly, and you will end up with the wrong progress bars on the wrong lines, especially if you're a fast scroller, and it mostly happens when you're scrolling back up.

Does anybody have any working code which will help me be able to achieve the ability create TProgressBars on a TListView, and be able to scroll and resize while updating correctly and efficiently?

N.B. I do not want to rely on third party components such as TSM's AdvListView or Virtual Treeview (neither of them compile to 64 bit anyway), and I most certainly do not want to draw the progress bars manually.  TProgressBar is what I need.

I am running Delphi XE2.

Thanks in advance.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, CommCtrl;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure ListView1CustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  private
    { Private declarations }
    procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY;
    procedure AdjustProgressBar(item: TListItem; r: TRect);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Byte;
  r: TRect;
  pb: TProgressBar;
begin
  Listview1.Columns.Add.Width := 100;
  Listview1.Columns.Add.Width := 200;
  Listview1.ViewStyle := vsReport;

  Randomize;
  for i:=0 to 40 do
  begin
    Listview1.Items.Add.Caption := 'Texte ' + IntToStr(i);
    r := Listview1.Items[i].DisplayRect(drBounds);
    pb := TProgressBar.Create(Self);
    pb.Parent := Listview1;
    pb.Position := Random(pb.Max);
    Listview1.Items[i].Data := pb;
    AdjustProgressBar(Listview1.Items[i], r);
  end;end;

  procedure TForm1.WMNotify(var Message: TWMNotify);
var
  i: Integer;
  r: TRect;
begin

  case Message.NMHdr.code of
    HDN_ITEMCHANGED, HDN_ITEMCHANGING:
      begin
        for i:=0 to Listview1.Items.Count-1 do
        begin
          r := Listview1.Items[i].DisplayRect(drBounds);
          AdjustProgressBar(Listview1.Items[i], r);
        end;

        ListView1.Repaint;
      end;end;
  inherited;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  r: TRect;
  pb: TProgressBar;
begin
  r := Item.DisplayRect(drBounds);
  if r.Top>=Listview1.BoundsRect.Top then
    AdjustProgressBar(Item, r);
end;

procedure TForm1.AdjustProgressBar(item: TListItem; r: TRect);
var
  pb: TProgressBar;
begin
  r.Left := r.Left + Listview1.columns[0].Width;
  r.Right := r.Left + Listview1.columns[1].Width;
  pb := item.Data;
  pb.BoundsRect := r;
end;

end.

Open in new window

0
Comment
Question by:Lester_Clayton
  • 2
4 Comments
 
LVL 25

Expert Comment

by:epasquier
ID: 36517473
>> and I most certainly do not want to draw the progress bars manually.
I'm about sure that is by far your best shot.
trying to move in sync a component above another such as grids or list view can be a real nightmare, as what you have seen already suggests.

A progressbar is really not very hard to paint (except if you love those new fancy Vista/Seven greenish animations, and can't cope without it), I believe you can do it in 2 lines of code (2 rectangles part) in a OnCustomDrawItem event.
0
 
LVL 3

Accepted Solution

by:
VahaC earned 500 total points
ID: 36528680
and I most certainly do not want to draw the progress bars manually.  TProgressBar is what I need.
As for me best solution is to draw progress bars manually

Look attached example TListview-vs-ProgressBar.zip
0
 
LVL 9

Author Closing Comment

by:Lester_Clayton
ID: 36529059
Thank you very much for the code.  It may not be the TProgressBar component, but it looks exactly the same!  I've implemented it and I like what I see.  Kudos.
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36529233
This is indeed some piece of code that went into the trouble of drawing nice smooth progressbar.

Now you see ?  You most certainly WANT to draw the progress bars manually instead of trying to play with components "inclusion". That is very often the case as far as custom ListView, TreeView etc... are concerned, and knowing how to do custom drawing on these components can be the key to nice interfaces, with less efforts than it appears at first glance

And besides, there are so many code sample around to help you on details.Like this excellent article
http://www.delphidabbler.com/articles?article=16
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question