0

I just can't seem to find a solution on the internet where I could event trap the Listview vertical scrollbar. Has someone found a solution that works in vb ; if so can you please post some code or reference to this . . .

(found solution see answer !)

BASit Bulbulia
  • 229
  • 3
  • 16
  • You could (it looks like a hack, I know) override `WndProc` and wait for a [WM_CTLCOLORLISTBOX](https://learn.microsoft.com/en-us/windows/desktop/controls/wm-ctlcolorlistbox) message. Even if the MSDN description seems to point to something completely unrelated, this message is sent each time you scroll the ListBox (to paint the background). You can then check the [TopIndex](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.listbox.topindex) property and see whether the scrollbar has moved the top index of the ListBox. This message can be sent twice per scroll. – Jimi Dec 30 '18 at 00:23
  • May work with a listbox ; not sure if it could work with Listview. . . – BASit Bulbulia Dec 30 '18 at 00:30
  • Oops, I read `ListBox` for unknown reasons :) Nope, for a `ListView` you receive a `WM_NOTIFY` message. – Jimi Dec 30 '18 at 00:39
  • 2
    Should be able to convert something like this to VB I'm pretty sure: https://stackoverflow.com/questions/1851620/handling-scroll-event-on-listview-in-c-sharp – Nathan Champion Dec 30 '18 at 00:41
  • 2
    Or what @Nathan Champion posted (which requires a Custom Control). I forgot to mention that when you receive a `WM_NOTIFY` for a `ListView` scroll event, the Handle of the Control affected is provided in a [NMHDR structure](https://learn.microsoft.com/en-us/windows/desktop/api/richedit/ns-richedit-_nmhdr). The handle is referenced by the `HWND hwndFrom` member. You can use `Marshal.PtrToStructure` to retrieve the values from the Message `lParam`: (`Dim messageHeader As nmHDR = Marshal.PtrToStructure(Of nmHDR)(m.LParam)`) – Jimi Dec 30 '18 at 01:21
  • @Nathan Champion ; I tried converting that code in Vb (Hans Passant's code) and it would just not compile to many errors ! :- – BASit Bulbulia Dec 30 '18 at 06:07
  • @Jimi, I am truly lost . . .can you give me some code in .net vb that uses WM_NOTIFY and NMHDR structure please. – BASit Bulbulia Dec 30 '18 at 06:12
  • .Net Famework 2.0 ? You know you are dealing with a dead soul right ? – Software Dev Dec 30 '18 at 10:08
  • @zack raiyan, unfortunately I inherited a program with it and because of the various deployments of it in the field I am stuck with it and I am in the process of changing same, however right now I need a solution in 2.0 (framework) – BASit Bulbulia Dec 30 '18 at 10:47
  • @BASitBulbulia , you can always upgrade your .Net. But most people don't as their company doesn't allow. – Software Dev Dec 30 '18 at 12:27

2 Answers2

0

After much research I finally came up with a .net vb solution :-)

Public Class Form1
    Public Class ControlScrollListener
        Inherits NativeWindow
        Implements IDisposable

        ' Event
        Public Event Scroll As ScrollEventHandler
        Public Delegate Sub ScrollEventHandler(ByVal sender As Object, ByVal e As EventArgs)

        ' Flag: Has Dispose already been called?
        Private Disposed As Boolean

        ' Windows message for Horizontal Scroll
        Private Const WM_HSCROLL As UInteger = &H114

        ' Windows message for Vertical Scroll
        Private Const WM_VSCROLL As UInteger = &H115

        ' Windows message for mouse wheel
        Private Const WM_MOUSEWHEEL As UInteger = &H20A

        ' The control object
        Private sender As Control

        ''' <summary>
        ''' Constructor
        ''' </summary>
        Public Sub New()
            sender = Nothing
        End Sub

        ''' <summary>
        ''' Constructor
        ''' </summary>
        ''' <param name="control">The control object</param>
        Public Sub New(ByVal control As Control)
            sender = control
            AssignHandle(sender.Handle)
        End Sub

        ''' <summary>
        ''' Public implementation of Dispose pattern callable by consumers.
        ''' </summary>
        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub

        ''' <summary>
        ''' Invokes the default window procedure associated with this window
        ''' </summary>
        ''' <param name="m">A Message that is associated with the current Windows message.</param>
        ''' <remarks>This method is called when a window message is sent to the handle of the window</remarks>
        Protected Overrides Sub WndProc(ByRef m As Message)
            HandleControlScroll(m)
            MyBase.WndProc(m)
        End Sub

        ''' <summary>
        ''' Protected implementation of Dispose pattern.
        ''' </summary>
        ''' <param name="disposing">The boolean value for disposing object</param>
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Disposed Then Return

            If disposing Then
                ' Free any other managed objects here.
                sender = Nothing
            End If

            ' Free any unmanaged objects here.
            ReleaseHandle()
            Disposed = True
        End Sub

        ''' <summary>
        ''' Handle control scroll
        ''' </summary>
        ''' <param name="m">A Message that is associated with the current Windows message.</param>
        Private Sub HandleControlScroll(ByVal m As Message)
            If m.Msg = WM_HSCROLL Or m.Msg = WM_VSCROLL Or m.Msg = WM_MOUSEWHEEL Then


                If Not sender Is Nothing Then
                    RaiseEvent Scroll(sender, New EventArgs())

                End If
            End If
        End Sub
    End Class

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load


        'Creating the list items
        Dim ListItem1 As ListViewItem
        ListItem1 = ListView1.Items.Add("Item 1")

        Dim ListItem2 As ListViewItem
        ListItem2 = ListView1.Items.Add("Item 2")

        Dim ListItem3 As ListViewItem
        ListItem3 = ListView1.Items.Add("Item 3")

        Dim ListItem4 As ListViewItem
        ListItem4 = ListView1.Items.Add("Item 4")


        ListView1.View = View.SmallIcon

        Dim scrollListener As New ControlScrollListener(ListView1)
        AddHandler scrollListener.Scroll, AddressOf listview1_scroll


    End Sub

    Private Sub listview1_scroll(sender As Object, e As EventArgs)

       'here you capture the scroll and do something with it ! 
        'example: msgbox("Scroll happen !")

    End Sub

End Class
BASit Bulbulia
  • 229
  • 3
  • 16
-1
Private Sub xListView_HandleCreated(sender As Object, e As System.EventArgs) Handles ListView1.HandleCreated
    Dim scrollListener As New UI.ControlScrollListener(ListView1)
    AddHandler scrollListener.Scroll, AddressOf Scroll
End Sub

Private Sub Scroll(sender As Object, e As EventArgs)
    'DO SOMETHING HERE...
End Sub
BDL
  • 21,052
  • 22
  • 49
  • 55
yukito
  • 1