4
votes

I would like to control a RichTextBox scrolling but can't find any method to perform this in the control.

The reason to do this is that I want the mouse wheel scroll to be effective when the mouse cursor in over the RichTextBox control (it has no active focus : mouse wheel event is handled by the form).

Any help is appreciated!

1
Side note: A Windows application which does this system-wide is "KatMouse". I sadly don't know how to do it on your own in your program.Ray
You could set the RichTextBox as selected control when hovering with mouse over it.Max
The duplicate question leads to a link. I prefer King King answer giving a solution right away.Martin Delille

1 Answers

2
votes

It's a little simple with win32. Here you are:

//must add using System.Reflection
public partial class Form1 : Form, IMessageFilter 
{
    bool hovered;
    MethodInfo wndProc;

    public Form1() 
    {
       InitializeComponent();
       Application.AddMessageFilter(this);
       richTextBox1.MouseEnter += (s, e) => { hovered = true; };
       richTextBox1.MouseLeave += (s, e) => { hovered = false; };
       wndProc = typeof(Control).GetMethod("WndProc", BindingFlags.NonPublic | 
                                                      BindingFlags.Instance);
    }

    public bool PreFilterMessage(ref Message m) 
    {
        if (m.Msg == 0x20a && hovered) //WM_MOUSEWHEEL = 0x20a
        {
           Message msg = Message.Create(richTextBox1.Handle, m.Msg, m.WParam, m.LParam);
           wndProc.Invoke(richTextBox1, new object[] { msg });
        }
        return false;
    }
}

NOTE: I use an IMessageFilter to catch the WM_MOUSEWHEEL message at the application-level. I also use Reflection to invoke the protected method WndProc to process the message WM_MOUSEWHEEL, you can always use a SendMessage win32 function to send the WM_MOUSEWHEEL to richTextBox1 instead, but it requires a declaration import here. It's up to you.