[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 889
  • Last Modified:

ProgressBar in ListView

How can i (the easiest way) show a Progress bar (like the TProgressBar) in a Column of a ListView (with Re-Moving and Re-Sizeing)
0
snoopy_Spy
Asked:
snoopy_Spy
  • 9
  • 6
1 Solution
 
philipleighsCommented:
Hi,

The easiest way would be to position a progress bar over the top of the listview's column.
Change the position/column at run time.

....but the approach I would take is:

Create a descendant of TListView. Inside, create a contained progressbar. Override the Paint method, implement the function with a call to inherited, then FProgressBar.PaintTo(Canvas, X, Y);

Cheers,
Phil.
0
 
snoopy_SpyAuthor Commented:
But how can i get the x and y - positions of the progress bar ? (for example column 3 and row 6 )
0
 
philipleighsCommented:
Hi again,

Try this. Make sure that Col and Row are not outside your range, or you'll get a range error.
Also, it assumes that the ListView is in vsReport mode.
ShowColumnHeaders can be true or false.

procedure TForm1.RepositionProgressBar(Col, Row: Integer);
var pt: TPoint;
    RowHeight: Integer;
    ColLeft: Integer;
    Index: Integer;
    rc: TRect;
  begin
    //Work out the top left position of the first list item
    pt := ListView1.Items[0].Position;

    //Work out the row height
    RowHeight := ListView1.Items[1].Position.Y - pt.Y;

    //Work out the left edge of the specified column
    ColLeft := 0;
    for Index := 0 to Col - 1 do
      Inc(ColLeft, ListView1.Column[Index].Width);

    //Build the bounding rectangle, and reposition the progress bar
    rc.Left := ListView1.Left + ColLeft + pt.X;
    rc.Top := ListView1.Top + RowHeight * Row + pt.Y;
    rc.Right := rc.Left + ListView1.Column[Col].Width;
    rc.Bottom := rc.Top + RowHeight;
    ProgressBar1.BoundsRect := rc;
  end;

Cheers,
Phil.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

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.

 
philipleighsCommented:
BTW, it needs to have at least two items in the list view (otherwise it can't workout the rowheight).

Cheers,
Phil.
0
 
philipleighsCommented:
Hey snoopy,

Have you had a chance to try this out?

Cheers,
Phil.
0
 
snoopy_SpyAuthor Commented:
I have 2 problems with your solution :
1.) I can't change the Background auf the TProgressBar to the Background of the Listview (not so important)
but 2.)
I can't write a event where i can change the position and size of the ProgressBar when i move or resize the column !
0
 
philipleighsCommented:
The parent form gets a WM_NOTIFY while a column's width is changing.

Each time your form gets a WMNotify message, look at the idCtrl parameter (wParam).

If it equals the handle of the listview, then recalculate the bounds of the progress bar. (you could narrow down the number of times you check by examining the contents of lParam (address of an NMHDR).

If the rectangle is different from the progress bar's position, then use BoundsRect to change it.

Hmm, I don't know about the background of the progress bar.

Cheers,
Phil.
0
 
snoopy_SpyAuthor Commented:
What do you mean with the lParam (address of an NMHDR) ?
What is a NMHDR ?
0
 
philipleighsCommented:
It's a windows type. It is described in the Win32 API help. TWMNotify exposes it so you don't have to do any typecasting.

Basically, declare a message handler in the form.

TForm1 = class(TForm)
....
protected
  procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;

....

implementation

....

procedure TForm1.WMNotify(var Msg: TWMNotify);
begin
  inherited;
  if Msg.idCtrl = ListView1.Handle then
    if Msg.NMHdr.code = xxxx {some magic number} then
      begin
        ResizeProgressBar;
      end;
end;


if you omit this line:
    if Msg.NMHdr.code = xxxx {some magic number} then

you'll resize the progress bar everytime something happens to the listview which would be overkill. My guess is that NMHdr.code will contain a particular value when you resize a column. Work out that value and hard code it.

I haven't actually done this, but it's an approach that I'd take.

One other thing, this line:
  if Msg.idCtrl = ListView1.Handle then

might need to be changed to:
  if Msg.idCtrl = GetDlgCtrlID(ListView1.Handle) then

Good luck,
Phil.
0
 
snoopy_SpyAuthor Commented:
I have tried this :
procedure TForm1.WMNotify(var Msg: TWMNotify);
begin
    inherited;
    if Msg.idCtrl = ListView1.Handle then
        Edit2.Text := 'YES'
    else Edit2.Text := 'NO';

But i only get YES when i click the column header or on a item not when i change the column width !
0
 
philipleighsCommented:
Hmm, when I looked in Spy++ it showed me that WM_NOTIFY was being sent repeatedly when the mouse was down and moving over the column.

BTW, how you you know that it is only sent when you click? You could be setting Edit2.Text to 'YES' 50 times.

A method I use for this kind of thing is:

if Msg.idCtrl = ListView1.Handle then
begin
  Caption := Caption + 'x';
  if Length(Caption) > 50 then
    Caption := '';
end;

That way it is more obvious when a message has come through.
0
 
snoopy_SpyAuthor Commented:
Ups ...

thanxs

Post an answer !
0
 
philipleighsCommented:
Great! I'm glad you got it working.

Cheers,
Phil.
0
 
philipleighsCommented:
BTW, you can change the background colour of the ProgressBar by putting it inside a panel. ProgressBar uses the background colour of it's parent.

So drop a TPanel on your form, set Color to clWindow, and Visible to false.
Now cut and paste the ProgressBar into the TPanel!

Cheers,
Phil.
0
 
snoopy_SpyAuthor Commented:
Thanxs
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

  • 9
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now