Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Wheele
Hello All,
Hope you are doing great.
I need your help to make two WinForms listviews synchronized on both Vertical and Horizontal scrolls (using the scrolls or mouse middle wheele) using VB.NET (2013).
I've followed kleinma perfect example there http://www.vbforums.com/showthread.p...-of-2-listview
But still I am unable to make what I want.
Public Class ffListView
Inherits ListView
'Protected Overrides Sub WndProc(ByRef m As Message)
' If m.Msg = &H203 Then m.Msg = &H201
' MyBase.WndProc(m)
'End Sub
'SCROLL CONSTANTS
Private Const SBM_SETSCROLLINFO As Integer = &HE9
Private Const WM_HSCROLL As Integer = &H115
Private Const WM_VSCROLL As Integer = &H114
'CUSTOM EVENT
Public Event Scroll(ByVal sender As Object, ByVal e As EventArgs)
Protected Sub OnScroll()
RaiseEvent Scroll(Me, EventArgs.Empty)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_HSCROLL OrElse m.Msg = WM_VSCROLL OrElse m.Msg = SBM_SETSCROLLINFO Then
OnScroll()
End If
End Sub
End Class
The above custom Listview is working perfectly .. but when I use the mouse wheel to scroll, there is no vertical synchronization >> problem ONE
And I need to synchronize the horizontal scrolls as well .. The main is lstvwOutput and the follower is lstvwOriginal >> problem TWO
Private Const WM_HSCROLL As Integer = &H114
Private Const WM_VSCROLL As Integer = &H115
Private Const SBS_HORZ As Integer = 0
Private Const SBS_VERT As Integer = 1
Private Declare Function GetScrollPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer) As Integer
Private Declare Function SetScrollPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByVal nPos As Integer, ByVal bRedraw As Boolean) As Integer
Private Declare Function PostMessageA Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Boolean
Private Sub scrollControl(ByVal hWnd As IntPtr, ByVal Amount As Integer)
If SetScrollPos(hWnd, SBS_HORZ, Amount, True) <> -1 Then
PostMessageA(hWnd, WM_HSCROLL, &H10000 * Amount, 50)
Else
'MsgBox("Can't set info (Err: " & GetLastWin32Error() & ")")
End If
End Sub
Private Sub lstvwOutput_Scroll(sender As Object, e As EventArgs) Handles lstvwOutput.Scroll
lstvwOriginal.TopItem = lstvwOriginal.Items(lstvwOutput.TopItem.Index)
scrollControl(lstvwOriginal.Handle, GetScrollPos(lstvwOutput.Handle, SBS_HORZ))
lstvwOriginal.Invalidate()
End Sub
Could you kindly help me on these two problems?
Thanks,
Moatassem
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
I didn't look at kleinma's code but to detect mouse wheel use WM_MOUSEWHEEL.
I was actually trying to do this myself sometime ago, tho no support for the thumbbar.
LV's must be identically the same size, item count, column widths, and only works one way, you scroll LV1 and it scrolls LV2...
FORM CODE,
Code:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
' tell the class who is the 2nd LV.
LVex.OtherListview = ListView2
Code:
Imports System.Runtime.InteropServices
Public Class LVex
Inherits ListView
<DllImport("user32.dll")> _
Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wp As IntPtr, lp As IntPtr) As IntPtr
End Function
Private Const WM_VSCROLL As Integer = &H115
Private Const WM_HSCROLL As Integer = &H114
Private Const WM_MOUSEWHEEL As Integer = &H20A
Public Shared OtherListview As ListView
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If OtherListview IsNot Nothing AndAlso Me.Handle <> OtherListview.Handle Then
Select Case m.Msg
Case WM_VSCROLL, WM_HSCROLL, WM_MOUSEWHEEL
' pass same msg to other LV
SendMessage(OtherListview.Handle, m.Msg, m.WParam, m.LParam)
End Select
End If
MyBase.WndProc(m)
End Sub
End Class
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Hello Edgemeal,
Thanks a lot ..
Now whenever main LV (lstvwOutput) is scrolled vertically, the other (lstvwOriginal) follows it.
but the remaining part is the horizontal scrolling, it is not working at all. Why?
Here is my code:
In the main Form handling the Scroll event of the main LV (lstvwOutput):
Code:
<DllImport("user32.dll")> _
Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wp As IntPtr, lp As IntPtr) As IntPtr
End Function
Private Sub lstvwOutput_Scroll(ByVal sender As Object, ByVal e As EventArgs, ByVal m As System.Windows.Forms.Message) Handles lstvwOutput.Scroll
SendMessage(lstvwOriginal.Handle, m.Msg, m.WParam, m.LParam)
End Sub
Below is the custom Listview which exposes the Scroll Event:
Code:
Public Class ffListView
Inherits ListView
'SCROLL CONSTANTS
Private Const SBM_SETSCROLLINFO As Integer = &HE9
Private Const WM_VSCROLL As Integer = &H115
Private Const WM_HSCROLL As Integer = &H114
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private Const WM_MOUSEHWHEEL As Integer = &H20E
'CUSTOM EVENT
Public Event Scroll(ByVal sender As Object, ByVal e As EventArgs, ByVal m As System.Windows.Forms.Message)
Protected Sub OnScroll(ByVal m As System.Windows.Forms.Message)
RaiseEvent Scroll(Me, EventArgs.Empty, m)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_HSCROLL OrElse m.Msg = WM_VSCROLL OrElse m.Msg = SBM_SETSCROLLINFO OrElse m.Msg = WM_MOUSEWHEEL OrElse m.Msg = WM_MOUSEHWHEEL Then
OnScroll(m)
End If
End Sub
Public Sub New()
Me.DoubleBuffered = True
Me.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.FullRowSelect = True
Me.GridLines = True
Me.HideSelection = False
Me.View = Windows.Forms.View.Details
Me.MultiSelect = True
End Sub
'Protected Overrides Sub WndProc(ByRef m As Message)
' If m.Msg = &H203 Then m.Msg = &H201
' MyBase.WndProc(m)
'End Sub
End Class
By the way, I added the below and now the Horizontal scroll of secondary LV is moving with the primary LV but the actualy LV is not moving ...
It seems that the SetScrollPos and SendMessage are setting contracdicting data to the secondary LV.
Code:
Private Declare Function SetScrollPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nBar As Integer, ByVal nPos As Integer, ByVal bRedraw As Boolean) As Integer
Private Declare Function GetScrollPos Lib "user32.dll" (hWnd As System.IntPtr, nBar As Integer) As Integer
Private Sub lstvwOutput_Scroll(ByVal sender As Object, ByVal e As EventArgs, ByVal m As System.Windows.Forms.Message) Handles lstvwOutput.Scroll
SetScrollPos(lstvwOriginal.Handle, SBS_HORZ, GetScrollPos(lstvwOutput.Handle, SBS_HORZ), True)
SendMessage(lstvwOriginal.Handle, m.Msg, m.WParam, m.LParam)
End Sub
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Hello Again,
Correction! :)
Both scrolls are synchronized ONLY when using mouse Wheel .. but moving the Scroll (V or H) itself on the primary LV only moves the contents of the primary LV not the secondary one.
Any clue?
Regards
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Pardon my ignorance by why would one need to to this sort of thing?
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Quote:
Originally Posted by
tassoma
Hello Again,
Correction! :)
Both scrolls are synchronized ONLY when using mouse Wheel .. but moving the Scroll (V or H) itself on the primary LV only moves the contents of the primary LV not the secondary one.
Any clue?
Regards
I just tried your Class ffListView and it works fine here on Win7, only thing that doesn't work is if i slide the trackBar thing.
to sync LV2 to LV1 I did same thing.
Code:
Private Sub ListView1_Scroll(sender As Object, e As System.EventArgs, m As System.Windows.Forms.Message) _
Handles ListView1.Scroll
SendMessage(ListView2.Handle, m.Msg, m.WParam, m.LParam)
End Sub
Sure you don't have any left over code messing you up?
BTW I was messing with GetScrollInfo & SetScrollInfo too, the scrollbar moves even when I used the trackBar, but the list items don't move, I gave up. :(
BTW2, I don't have a tilt wheel on this mouse so can't test for that.
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Quote:
Originally Posted by
Gruff
Pardon my ignorance by why would one need to to this sort of thing?
I'm creating an application to import bug CSV files into a master big listview.
This listview is powered by many add-on functions to edit any field/cell that matchs a given criteria and perform mass changes.
After the user finishes editing his rows.
The app extracts the rows which were modified giving the user 2 new listviews for the rows which were edited only.
one listview to show the new rows
one listview to show the same rows but the un-changes ones
The user can verify that his changes are okay (scrolling one listview should scroll the other) .. then the tool export both listviews to new CSV files that can be fed into the system to update its database at once.
Regards
Re: Synchronizing two Listviews on Vertical and Horizontal Scrolls and User Mouse Whe
Quote:
Originally Posted by
Edgemeal
I just tried your Class ffListView and it works fine here on Win7, only thing that doesn't work is if i slide the trackBar thing.
Sure you don't have any left over code messing you up?
What do you mean that it works fine?
It works only if you scroll the LV using the mouse wheel where the LV is having no vertical trackbar.
But my LV are too wide (+30 columns) so I have both H and V trackbars .. the mouse wheel will only scroll vertically.
So the challenge is to use the trackbar to do the same which seems too hard to accomplish :(