Page 1 of 1

Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 8:47 am
by Lord
Hi!

Is there a way to scroll two or more ListviewGadgets synchron
using mousewheel, scrollbar or upper and lower scroll buttons?

Code: Select all

Procedure ScrollSynchron()
  ; what to do here ???
EndProcedure

If OpenWindow(0, 10, 10, 500, 250, "Test", #PB_Window_SystemMenu)
  ListViewGadget(1, 10, 10, 235, 230)
  ListViewGadget(2, 255, 10, 235, 230)
  BindGadgetEvent(1, @ScrollSynchron())
 
  For i=1 To 100
    AddGadgetItem(1,-1,"Line "+Str(i),0,0)
    AddGadgetItem(2,-1,"Line "+Str(i),0,0)
  Next
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
EndIf [/code]

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 9:24 am
by Shardik
Are you looking for examples in Windows? If yes you may try these 2 examples:
- al90
- Fluid Byte

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 10:13 am
by RASHAD
Hi Lord
For Windows only
Mouse wheel ,Vertical Scrollbar and Keyboard support

Code: Select all

Procedure winCB(hWnd,uMsg,wParam,lParam)
  Select uMsg
    Case #WM_CTLCOLORLISTBOX
      If lParam = GadgetID(1)
        SendMessage_(GadgetID(2),#LB_SETTOPINDEX,GetScrollPos_(GadgetID(1),#SB_VERT),0)
      ElseIf lParam = GadgetID(2)
        SendMessage_(GadgetID(1),#LB_SETTOPINDEX,GetScrollPos_(GadgetID(2),#SB_VERT),0)
      EndIf      
      
    Case #WM_COMMAND
      If lParam = GadgetID(1)
        Index = SendMessage_(GadgetID(1), #LB_GETCURSEL, 0, 0)
        SendMessage_(GadgetID(2), #LB_SETCURSEL, Index, 0)
      ElseIf lParam = GadgetID(2)
        Index = SendMessage_(GadgetID(2), #LB_GETCURSEL, 0, 0)
        SendMessage_(GadgetID(1), #LB_SETCURSEL, Index, 0)        
      EndIf         
      
    Case #WM_KEYDOWN ,#WM_MENUSELECT
      If wParam=#VK_UP
        SendMessage_(GadgetID(1),#WM_VSCROLL,#SB_LINEUP,0)
        SendMessage_(GadgetID(2),#WM_VSCROLL,#SB_LINEUP,0)
      ElseIf wParam=#VK_DOWN
        SendMessage_(GadgetID(1),#WM_VSCROLL,#SB_LINEDOWN,0)
        SendMessage_(GadgetID(2),#WM_VSCROLL,#SB_LINEDOWN,0)
      EndIf
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 10, 10, 500, 250, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ListViewGadget(1, 10, 10, 235, 230,0)
  ListViewGadget(2, 255, 10, 235, 230,0)
  
  For i=1 To 100
    AddGadgetItem(1,-1,"Line "+Str(i),0,0)
    AddGadgetItem(2,-1,"Line "+Str(i),0,0)
  Next
  
  SetWindowCallback(@winCB())
  
  Repeat
    Select WaitWindowEvent(1)
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
EndIf

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 11:10 am
by Lord
Hi Shardik!

Thank you for your answer.
Shardik wrote: Tue Jul 29, 2025 9:24 am ...
al90
...
This example doesn't work with LiestViewGadget.
Shardik wrote: Tue Jul 29, 2025 9:24 am...
Fluid Byte
Here you can't use mousewheel.

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 11:15 am
by Lord
Hello Rashad!

Thank you for responding.
Your code works as espected and needed (as always).
I'll stick to it.

Is there a way to eliminate this slow moving of list content when
clicking the scrollbar?

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Tue Jul 29, 2025 12:03 pm
by RASHAD
Hi Lord
You are welcome
Next using SubClassing
I hope it will be better than the first example
Added select too

Code: Select all

Global oldCallback

Procedure lbCB(hWnd, uMsg, wParam, lParam)  
  result = CallWindowProc_(oldCallback, hWnd, uMsg, wParam, lParam)
  Select uMsg    
      
    Case #WM_VSCROLL,#WM_MOUSEWHEEL
      If hwnd = GadgetID(1)
        top  = SendMessage_(hWnd,#LB_GETTOPINDEX ,0,0)
        SendMessage_(GadgetID(2),#LB_SETTOPINDEX,top,0)
      ElseIf hwnd = GadgetID(2)
        top  = SendMessage_(hWnd,#LB_GETTOPINDEX ,0,0)
        SendMessage_(GadgetID(1),#LB_SETTOPINDEX,top,0)
      EndIf 
      
    Case #WM_LBUTTONDOWN
      If hwnd = GadgetID(1)
        Index = SendMessage_(GadgetID(1), #LB_GETCURSEL, 0, 0)
        SendMessage_(GadgetID(2), #LB_SETCURSEL, Index, 0)
      ElseIf hwnd = GadgetID(2)
        Index = SendMessage_(GadgetID(2), #LB_GETCURSEL, 0, 0)
        SendMessage_(GadgetID(1), #LB_SETCURSEL, Index, 0)        
      EndIf          
      
    Case #WM_KEYDOWN ,#WM_MENUSELECT
      If wParam=#VK_UP
        SendMessage_(GadgetID(1),#WM_VSCROLL,#SB_LINEUP,0)
        SendMessage_(GadgetID(2),#WM_VSCROLL,#SB_LINEUP,0)
      ElseIf wParam=#VK_DOWN
        SendMessage_(GadgetID(1),#WM_VSCROLL,#SB_LINEDOWN,0)
        SendMessage_(GadgetID(2),#WM_VSCROLL,#SB_LINEDOWN,0)
      EndIf
      
  EndSelect
  
  ProcedureReturn result
EndProcedure


If OpenWindow(0, 10, 10, 500, 250, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ListViewGadget(1, 10, 10, 235, 230,0)
  ListViewGadget(2, 255, 10, 235, 230,0)
  
  For i=1 To 100
    AddGadgetItem(1,-1,"Line "+Str(i),0,0)
    AddGadgetItem(2,-1,"Line "+Str(i),0,0)
  Next
  
  oldCallback = SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, @lbCB())
  oldCallback = SetWindowLongPtr_(GadgetID(2), #GWL_WNDPROC, @lbCB()) 
  
  Repeat
    Select WaitWindowEvent(1)
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
EndIf

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Wed Jul 30, 2025 11:27 am
by Lord
Hi Rashad!

Sorry for my late response, but
I noticed a strange ListGadget behaviour.
I could populate the gadget with more than 65561 entries.
Starting with 65562 entries, I was not able to reach entries
greater than 65561 by moving the scroll bar knob with mouse.
The List jumps just to an entry in the top part.
I can go over this limit with keyboard End and PageDown and
reache the bomm lines.

My first tought was, that something was wrong with your code.
It isn't! It turned out, that this also happens without your code:
OpenWindow(1, 10, 10, 640, 480, "")

ListViewGadget(1, 10, 10, 200, 400)
SendMessage_(GadgetID(1),#WM_SETREDRAW,#False,0)
For i=1 To 80000
AddGadgetItem(1, -1, "Line "+Str(i))
Next
SendMessage_(GadgetID(1),#WM_SETREDRAW,#True,0)

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Looks like a windows thing. So its better to avoid more
than 65561 entries.

The "smooth" scrolling of the actual list ist still there.
I looked for a way to to have this "jump style", but I can live with that.

Thanks for your efford to help me out.

Lord

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Wed Jul 30, 2025 11:55 am
by PBJim
Lord wrote: Wed Jul 30, 2025 11:27 am I looked for a way to to have this "jump style", but I can live with that.
Thanks for your efford to help me out. Lord
The other solution I would suggest, which might also help you, is Rashad's grid tool. I can't recall what it's called, but I do remember it contains a procedure called LIcallback. That allows creation of multiple columns — and they are editable also, if you want them to be.

I've been hoping that PB might eventually provide something similar to VB's data grid control, it would bring a lot of power to PB for business applications, where grids are an essential requirement.

EDIT — I think this was it viewtopic.php?p=630250#p630250

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Wed Jul 30, 2025 12:00 pm
by RASHAD
Hi Lord
I suggest using ListIcon Gadget
It will cost you a little bit more coding
But it's much much better than the ListView Gadget
You can scroll Val & Hal ,Mouse Wheel & Keyboard
In case you need more speed with lot of content you can use virtual ListIcon

Code: Select all


Global oldCallback

Procedure LVcallback(hWnd, uMsg, wParam, lParam)
  
  result = CallWindowProc_(oldCallback, hWnd, uMsg, wParam, lParam)
  Select uMsg
      
    Case #WM_VSCROLL,#WM_MOUSEWHEEL
      If hwnd = GadgetID(1)
        Item_Sp = SendMessage_(GadgetID(1), #LVM_GETITEMSPACING, 1, 0) >> 16 
        SelItem = GetScrollPos_(GadgetID(1),#SB_VERT) - GetScrollPos_(GadgetID(0),#SB_VERT)
        SendMessage_(GadgetID(0), #LVM_SCROLL, 0, SelItem * Item_Sp)
      ElseIf hwnd = GadgetID(0)
        Item_Sp = SendMessage_(GadgetID(0), #LVM_GETITEMSPACING, 1, 0) >> 16 
        SelItem = GetScrollPos_(GadgetID(0),#SB_VERT) - GetScrollPos_(GadgetID(1),#SB_VERT)
        SendMessage_(GadgetID(1), #LVM_SCROLL, 0, SelItem * Item_Sp)
      EndIf 
      
    Case #WM_HSCROLL
      If hwnd = GadgetID(1)
        SelItem = GetScrollPos_(GadgetID(1),#SB_HORZ) - GetScrollPos_(GadgetID(0),#SB_HORZ)
        SendMessage_(GadgetID(0), #LVM_SCROLL, SelItem , 0)
      ElseIf hwnd = GadgetID(0)
        SelItem = GetScrollPos_(GadgetID(0),#SB_HORZ) - GetScrollPos_(GadgetID(1),#SB_HORZ)
        SendMessage_(GadgetID(1), #LVM_SCROLL, SelItem , 0)
      EndIf
      
      
    Case #WM_KEYDOWN ,#WM_MENUSELECT
      If wParam=#VK_UP Or wParam=#VK_DOWN
        If hwnd = GadgetID(1)
          Item_Sp = SendMessage_(GadgetID(1), #LVM_GETITEMSPACING, 1, 0) >> 16 
          SelItem = GetScrollPos_(GadgetID(1),#SB_VERT) - GetScrollPos_(GadgetID(0),#SB_VERT)
          SendMessage_(GadgetID(0), #LVM_SCROLL, 0, SelItem * Item_Sp)
        ElseIf hwnd = GadgetID(0)
          Item_Sp = SendMessage_(GadgetID(0), #LVM_GETITEMSPACING, 1, 0) >> 16 
          SelItem = GetScrollPos_(GadgetID(0),#SB_VERT) - GetScrollPos_(GadgetID(1),#SB_VERT)
          SendMessage_(GadgetID(1), #LVM_SCROLL, 0, SelItem * Item_Sp)
        EndIf             
      ElseIf wParam=#VK_LEFT Or wParam=#VK_RIGHT
        If hwnd = GadgetID(1)
          SelItem = GetScrollPos_(GadgetID(1),#SB_HORZ) - GetScrollPos_(GadgetID(0),#SB_HORZ)
          SendMessage_(GadgetID(0), #LVM_SCROLL, SelItem , 0)
        ElseIf hwnd = GadgetID(0)
          SelItem = GetScrollPos_(GadgetID(0),#SB_HORZ) - GetScrollPos_(GadgetID(1),#SB_HORZ)
          SendMessage_(GadgetID(1), #LVM_SCROLL, SelItem , 0)
        EndIf
      EndIf         
      
  EndSelect
  
  ProcedureReturn result
EndProcedure

OpenWindow(0, 0, 0, 620, 400,"Syncronize ListIcon", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 10, 10, 300, 380, "Column 0", 150, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection|#LVS_NOCOLUMNHEADER)
ListIconGadget(1, 310, 10, 300, 380, "Column 0", 150, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection|#LVS_NOCOLUMNHEADER)

For n = 0 To 1
  For i = 0 To 100
    AddGadgetItem(n,-1,"Line " + Str(i) + " Column 0" + Chr(10) + "Line " + Str(i) + " Column 1"+ Chr(10) + "Line " + Str(i) + " Column 2"+ Chr(10) + "Line " + Str(i) + " Column 3"+ Chr(10) + "Line " + Str(i) + " Column 4"+ Chr(10) + "Line " + Str(i) + " Column 5")
  Next i
Next

oldCallback = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @LVcallback())
oldCallback = SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, @LVcallback())  

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow 
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          
      EndSelect 
      
  EndSelect
  
Until Quit = 1

Re: Scrolling two (or more) ListViewGadgets synchron

Posted: Wed Jul 30, 2025 4:21 pm
by Lord
Hi Rashad!

Thank you for being so patient.

I seems, that your last posting includes what I was looking for.
It never came to my mind using LIG for that, because I didn't
know the existance of #LVS_NOCOLUMNHEADER.
Everything works, no "soft scroll", all lines reachable with
scroll bar and keys.

Thanks again.
Case closed.

Lord