Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scrollbar in TListView (or TListBox)

1,438 views
Skip to first unread message

virtualj

unread,
Mar 18, 2002, 1:27:19 PM3/18/02
to

How can I manage the scrollbar in a TListView? There isn't an OnScroll event.. there isn't a VerthScrollBar properties... But there is the scroll bar!! I've to scroll a ListView togheter another ListView... If one scroll, also the other must scroll.. Please help me.

Peter Below (TeamB)

unread,
Mar 19, 2002, 2:07:05 PM3/19/02
to

There is a technique that works for nearly all controls that have scrollbars:
trap the WM_VSCROLL or WM_HSCROLL message the scrollbar sends to the control
and forward it to the other control you want to scroll as well.

Search the archives for PBSyncListbox, that will turn up a sample listbox
derivative that uses this method. You can convert that to a listview descendent
just by doing a bunch of search and replaces on the unit.

--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


virtualj

unread,
Mar 19, 2002, 2:22:30 PM3/19/02
to

How can I trap the message to control?

virtualj

unread,
Mar 19, 2002, 3:06:05 PM3/19/02
to

i try with this:

Application.OnMessage := AppMessage;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
var handle2: HWND;
begin
if msg.message = WM_HSCROLL then begin
if msg.hwnd = ListView1.Handle then
handle2 := ListView2.Handle
else
handle2 := ListView1.Handle;
SetScrollPos(handle2,SB_VERT,GetScrollPos(msg.hwnd,SB_VERT),True);
end;
end;

But with a Breakpoint in "if msg.message = WM_HSCROLL then begin"
I see that any message is generated when I scroll.. When I
scroll in effect doesn't happen anything...
Why??

virtualj

unread,
Mar 19, 2002, 7:03:17 PM3/19/02
to

"virtualj" <virtu...@tin.it> wrote:
Why anyone answer to me?

Peter Below (TeamB)

unread,
Mar 20, 2002, 5:08:16 AM3/20/02
to
In article <3c978ff6$1_2@dnews>, Virtualj wrote:
> How can I trap the message to control?

I told you where to find an example for that. If you choose not to use it that's
your problem.

virtualj

unread,
Mar 20, 2002, 9:11:06 AM3/20/02
to

I don't understand where have I to serch "the archives for PBSyncListbox"... In Borland Help there isn't..
Sorry, but I'm Italian.. I'm trying with all my resource to understand!! Give me few compriension please..

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote:

Peter Below (TeamB)

unread,
Mar 20, 2002, 1:54:19 PM3/20/02
to
In article <3c98987a$1_1@dnews>, Virtualj wrote:
> I don't understand where have I to serch "the archives for PBSyncListbox"...

"Archives" as in newsgroup archives, the links to which are given in the
signature below.

virtualj

unread,
Mar 20, 2002, 5:06:20 PM3/20/02
to

Now I understand what you mean.. I try to do it, I do the conversion
to ListView.. I have only to try it in function!! (or at work,
i don't know how can I say it... pheraps "working" it's good)
I regards you too much and I want congratulate with all this
newsgroups.. I always find an answer to my questions and
problem! Very thanks.

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote:

virtualj

unread,
Mar 20, 2002, 5:29:34 PM3/20/02
to

Good Good Good!! It works.. but.. The list are not syncronized
when I drag the scrollbar with mouse. It works only when I
click on the scrollup or scrolldown button.. where can be the error? I copy your component but I change only the name and the ancestor type (TlistView). In compiling no errors..

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote:

virtualj

unread,
Mar 20, 2002, 7:55:06 PM3/20/02
to

From Delphi 6 Help:

"The limitation on this technique applies to real-time
scrolling of a window's content. An application implements
such scrolling by processing the WM_HSCROLL or WM_VSCROLL
messages that carry the SB_THUMBTRACK notification message,
thereby tracking the position of the scroll box, also known as
the thumb, while the user moves it. Unfortunately, there is no function to retrieve the thumb's 32-bit position while the
user moves it. GetScrollPos provides static position data
only; an application can therefore only obtain 32-bit position
data before or after a scroll has taken place."

I'm searching in vain the function for move either the scrollbars simultaneously?

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote:

Peter Below (TeamB)

unread,
Mar 21, 2002, 2:48:06 PM3/21/02
to
In article <3c990d4e$1_1@dnews>, Virtualj wrote:
> Good Good Good!! It works.. but.. The list are not syncronized
> when I drag the scrollbar with mouse. It works only when I
> click on the scrollup or scrolldown button.. where can be the error?

There is none. The thumb-tracking is something controls can handle as
they like. The messages are all send over to the other control, there is
really not much you can do in addition to what the code already does. The only
way out it see is a kind of brute force fix, and it seems to work. See unit below.
I have only looked at the vertical scrolling behaviour here, you may need
something similar to fix thumb dragging for horizontal scrolling.

unit PBSyncListview;

interface

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

type
TSyncKind = (skBoth, skVScroll, skHScroll, skNone);
TPBSyncListview = class(TListview)
private
FInSync: Boolean;
FSyncKind: TSyncKind;
Procedure WMVScroll( Var Msg: TMessage ); message WM_VSCROLL;
Procedure WMHScroll( Var Msg: TMessage ); message WM_HSCROLL;
Procedure WMKeyDown( Var Msg: TMessage ); message WM_KEYDOWN;
Procedure WMKeyUp ( Var Msg: TMessage ); message WM_KEYUP;
Procedure WMChar ( Var Msg: TMessage ); message WM_CHAR;
Procedure FixTopItem;
protected
Procedure Sync( msg, wparam: Integer; lparam: longint ); virtual;
public
Procedure DoSync( msg, wparam: Integer; lparam: longint ); virtual;
Procedure DoFixTopItem( topIndex: Integer ); virtual;
published
property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('PBGoodies', [TPBSyncListview]);
end;

{ TPBSyncListview }

procedure TPBSyncListview.DoFixTopItem(topIndex: Integer);
var
diff: Integer;
begin
If FSyncKind = skNone Then Exit;
FInSync := True;
try
diff := topindex - TopItem.Index;
While diff > 0 Do Begin
Perform( WM_VSCROLL, SB_LINEDOWN, 0 );
Dec( diff );
End;
While diff < 0 Do Begin
Perform( WM_VSCROLL, SB_LINEUP, 0 );
Inc( diff );
End;
finally
FInSync := False;
end;
end;

procedure TPBSyncListview.DoSync(msg, wparam, lparam: Integer);
begin
If FSyncKind = skNone Then Exit;
FInSync := True;
try
Perform( msg, wparam, lparam );
finally
FInSync := False;
end;
end;

procedure TPBSyncListview.FixTopItem;
var
i: Integer;
begin
If Assigned( Parent ) Then
For i:= 0 To Parent.Controlcount-1 Do
If (Parent.Controls[i] Is TPBSyncListview)
and not (Parent.Controls[i] = Self)
Then
TPBSyncListview( Parent.Controls[i] ).DoFixTopItem( TopItem.Index );
end;

procedure TPBSyncListview.Sync(msg, wparam, lparam: Integer);
var
i: Integer;
begin
If Assigned( Parent ) Then
For i:= 0 To Parent.Controlcount-1 Do
If (Parent.Controls[i] Is TPBSyncListview)
and not (Parent.Controls[i] = Self)
Then
TPBSyncListview( Parent.Controls[i] ).DoSync( msg, wparam, lparam );
end;

procedure TPBSyncListview.WMChar(var Msg: TMessage);
begin
If not FInSync and (FSyncKind <> skNone) Then
Sync( WM_CHAR, msg.wparam, msg.lparam );
inherited;
end;

procedure TPBSyncListview.WMHScroll(var Msg: TMessage);
begin
If not FInSync and (FSyncKind In [skBoth, skHScroll]) Then
Sync( WM_HSCROLL, msg.wparam, msg.lparam );
inherited;
end;

procedure TPBSyncListview.WMKeyDown(var Msg: TMessage);
begin
If not FInSync and (FSyncKind <> skNone) Then
Sync( WM_KEYDOWN, msg.wparam, msg.lparam );
inherited;
end;

procedure TPBSyncListview.WMKeyUp(var Msg: TMessage);
begin
If not FInSync and (FSyncKind <> skNone) Then
Sync( WM_KEYUP, msg.wparam, msg.lparam );
inherited;
end;

procedure TPBSyncListview.WMVScroll(var Msg: TMessage);
begin
If not FInSync and (FSyncKind In [skBoth, skVScroll]) Then
Sync( WM_VSCROLL, msg.wparam, msg.lparam );
inherited;
If not FInSync and (FSyncKind In [skBoth, skVScroll])
and (TWMVScroll(msg).Scrollcode = SB_THUMBTRACK )
Then
FixTopItem;
end;

end.

virtualj

unread,
Mar 21, 2002, 8:37:24 PM3/21/02
to

I'll try with this.. I have found another solution by insert a
TScrollBar that have a OnScroll event in wich I call the
TListView.Scroll procedure.. it works fine, but there are two problems:
1- when I scroll the scrollbar fast the two ListView scroll faster!
2- the scrollbar doesn't use Win Xp standard scrollbar style.. strange.. It seems like under win98

"Peter Below (TeamB)" <10011...@compuXXserve.com> wrote:

0 new messages