Select Page

Redirecting events from one control to another is quite easy. I recently needed it for an application that uses a number of ComboBoxes to filter data in a DataGridView. It was very confusing to the user when she selected an item in the ComboBox and subsequently tried using the mouse wheel to scroll through the data, that it would be the ComboBox, and not the DataGridView that would be scrolling.
I decided to make a special ComboBox that would redirect Mouse wheel events to the DataGridView, instead of trying to fix it by manipulating focus. Manipulating focus gives you nothing but problems in my experience.

The ComboBox with MouseWheel redirect

The class i implemented for this solution just overrides the WndProc function, which handles all the messages sent to the control. It then reroutes mouse wheel events to another control (the reciever) through the Win32 API function SendMessage.
That’s it…

public class ComboBoxMWRedirect : ComboBox
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(
        IntPtr hWnd,
        int message,
        IntPtr WParam,
        IntPtr LParam);

    private const int WM_MOUSEWHEEL = 0x020A;
    private Control _reciever;

    //needed for designer support
    private ComboBoxMWRedirect() {}

    public ComboBoxMWRedirect(Control reciever)
    {
        _reciever = reciever;
    }

    protected override void WndProc(ref Message message)
    {
        if (message.Msg == WM_MOUSEWHEEL)
        {
            //route mouse wheel messages to the reciever
            SendMessage(
                _reciever.Handle,
                message.Msg,
                message.WParam,
                message.LParam);
        }
        else
        {
            //route all other messages on to the base class
            base.WndProc(ref message);
        }
    }
}

Now to have one of your ComboBoxes redirect the mouse wheel, just use one of these instead, and specify the recieving control when you call the constructor. If, for instance, i want to redirect to a DataGridView calle dataGridView1 i would construct the redirecting ComboBox like this:

ComboBoxMWRedirect cb = new ComboBoxMWRedirect(dataGridView1);

Completely avoiding the event

The code can also be used to avoid the Mouse wheel event altogether. Just change the WndProc overridde to the code below, and mouse wheel events will be ignored.

protected override void WndProc(ref Message message)
{
    //avoid mouse wheel events
    if (message.Msg != WM_MOUSEWHEEL)
        base.WndProc(ref message);
}

Overriding WndProc gives you a lot of power and control over what happens in your application. This particular (very limited) example handles MouseWheel events on a ComboBox, but you can really use this to do a lot of very powerful stuff, like disabling the keyboard or parts of it, routing messages to other controls, broadcasting messages to have several controls react to the same message, etc. etc.