0

Here it is suggested to use this to get the scroll event produced with the mouse wheel. I read the official documentation but still do not know how to use this in C#. I have code mostly from this answer.

My code is this:

internal class EnhancedListView : ListView
{
    internal event ScrollEventHandler ScrollEnded,
        ScrollStarted;

    const int WM_NOTIFY = 0x004E;

    internal EnhancedListView()
    {
        Scroll += EnhancedListView_Scroll;
    }

    ScrollEventType mLastScroll = ScrollEventType.EndScroll;
    private void EnhancedListView_Scroll(object sender, ScrollEventArgs e)
    {
        if (e.Type == ScrollEventType.EndScroll)
        {
            ScrollEnded?.Invoke(this, e);
        }
        else if (mLastScroll == ScrollEventType.EndScroll)
        {
            ScrollStarted?.Invoke(this, e);
        }
        mLastScroll = e.Type;
    }

    internal event ScrollEventHandler Scroll;

    protected virtual void OnScroll(ScrollEventArgs e)
    {
        Scroll?.Invoke(this, e);
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg == 0x115)
        {
            // WM_VSCROLL
            OnScroll(
                new ScrollEventArgs(
                    (ScrollEventType)(m.WParam.ToInt32() & 0xffff),
                    0
                )
            );
        }
        else if (m.Msg == WM_NOTIFY)
        {
            // What should I put here?
        }
    }
}
silviubogan
  • 3,343
  • 3
  • 31
  • 57
  • 1
    You aren't listening for the MouseWheel event, if that is what the question is. – LarsTech Mar 14 '19 at 18:05
  • `WM_NOTIFY` is sent by the control to its Parent. You'll see that coupled with `WM_SETCURSOR` all the time. Look at the answer you linked and move one answer up. You'll have to handle directly all the cursor (Key presses) movements. – Jimi Mar 14 '19 at 18:05

1 Answers1

1

I stumbled across your question whilst trying to solve the same problem. I've synthesized the following from this answer (about handling WM_NOTIFY messages) and the Wine source code (which gives an integer value for LVN_BEGINSCROLL):

[StructLayout(LayoutKind.Sequential)]
private struct NMHDR
{
    public IntPtr hwndFrom;
    public IntPtr idFrom;
    public int code;
}

const int LVN_FIRST = -100;
const int LVN_BEGINSCROLL = LVN_FIRST - 80;

const int WM_REFLECT = 0x2000;

...

else if(m.Msg == WM_NOTIFY + WM_REFLECT)
{
    var notify = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
    if(notify.code == LVN_BEGINSCROLL)
    {
        OnScroll(new ScrollEventArgs((ScrollEventType)(m.WParam.ToInt32() & 0xffff), 0));
    }
}