Click here to Skip to main content
Click here to Skip to main content

Redirect Mouse Wheel Events to Unfocused Windows Forms Controls

By , 16 Nov 2011
Rate this:
Please Sign up or sign in to vote.

Introduction

In a Windows Forms application, the mouse wheel events will go by default to the control that has focus. So the user has to click the control before using the wheel on it. In many cases, this behaviour is annoying and counterintuitive and the application could provide a much better user experience if the mouse wheel would scroll/zoom/whatever the control under the mouse pointer. This behaviour is also known as mouse over scrolling or mouse over zooming. A classic example for this is a TreeView/ListView combination similar to a Windows Explorer.

Background

To implement this behaviour in different applications, I wrote the same code again and again using MouseEnter, MouseLeave, IMessageFilter, etc. So I did want to write a class that would allow me to do it in one single line of code - and this is what I came up with. It allows me to simply attach any control to the redirector and it will immediately start receiving the mouse wheel events whenever the mouse pointer is inside its bounds.

Using the Code

  1. Add MouseWheelRedirector.vb to your Windows Forms Application project.
  2. To start receiving mouse wheel events for a control:
  3. MouseWheelRedirector.Attach(myControl)
  4. To stop receiving mouse wheel events for that control (unless focused):
  5. MouseWheelRedirector.Detach(myControl)
  6. To suspend redirection for all attached controls (without detaching them):
  7. MouseWheelRedirector.Active = False
  8. To resume redirection for all attached controls:
  9. MouseWheelRedirector.Active = True

Here is some example code showing the usage of the class with a TreeView and a ListView. To use it, just create a new Windows Application and drop the following code into the code window for Form1:

Option Explicit On
Option Strict On
Option Infer On

Imports System.Windows.Forms

Public Class Form1

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

        Dim tools = New ToolStrip
        tools.Items.Add(New ToolStripButton("Suspend MouseWheelRedirector", _
                    Nothing, AddressOf SuspendRedirector))
        tools.Items.Add(New ToolStripButton("Resume MouseWheelRedirector", _
                    Nothing, AddressOf ResumeRedirector))

        Dim split = New SplitContainer
        split.Dock = DockStyle.Fill

        Dim tree = New TreeView
        tree.Dock = DockStyle.Fill

        Dim list = New ListView
        list.Dock = DockStyle.Fill
        list.View = View.List

        Me.Height = 300
        Me.Width = 800

        split.Panel1.Controls.Add(tree)
        split.Panel2.Controls.Add(list)

        Me.Controls.Add(split)
        Me.Controls.Add(tools)

        For i = 0 To 199
            tree.Nodes.Add("Tree View Node " & i)
            list.Items.Add("List View Item " & i)
        Next

        tree.ExpandAll()

        MouseWheelRedirector.Attach(tree)
        MouseWheelRedirector.Attach(list)
    End Sub

    Private Sub SuspendRedirector(ByVal sender As Object, ByVal e As System.EventArgs)
        MouseWheelRedirector.Active = False
    End Sub

    Private Sub ResumeRedirector(ByVal sender As Object, ByVal e As System.EventArgs)
        MouseWheelRedirector.Active = True
    End Sub

End Class

Points of Interest

This class uses the following techniques for the given task:

  • Listen to the control's MouseEnter and MouseLeave events to determine when the mouse pointer is over the control.
  • Implement IMessageFilter to catch WM_MOUSEWHEEL messages in the application.
  • PInvoke the Windows API call SendMessage redirecting the WM_MOUSEWHEEL message to the control's handle.
  • The IMessageFilter object is implemented as a singleton of the MouseWheelRedirector class and accessed by the shared members Attach, Detach, and Active.

Limitations

As herves pointed out in the Comments and Discussions section, if an attached control has child controls, the redirector won't work when the mouse pointer is over one of the child controls: whenever the mouse pointer hits the child control, the parent control's mouse leave event will fire and the parent control will stop receiving redirected mouse wheel events until the next mouse enter event.

History

  • November 15, 2011: Added one line of code to the Detach function:
  • If instance.currentControl Is control Then instance.currentControl = Nothing
  • November 16, 2011: Added the Limitations section to the article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

ifdefdebug

Portugal Portugal
Coding since 1982

Comments and Discussions

 
General5 stars PinmemberMember 399175224-Feb-14 7:46 
QuestionExcelente código. Pinmemberpdrobravo25-Jun-13 7:40 
QuestionC# version? Pinmemberlambertwm18-Feb-12 0:48 
AnswerRe: C# version? Pinmemberifdefdebug24-Feb-12 0:28 
AnswerRe: C# version? PinmemberKindDragon25-Apr-12 12:55 
QuestionLimitation and a question Pinmemberherves16-Nov-11 0:10 
AnswerRe: Limitation (1) Pinmemberifdefdebug16-Nov-11 11:38 
GeneralRe: Limitation (1) Pinmemberherves16-Nov-11 22:20 
AnswerRe: ... and a question (2) Pinmemberifdefdebug16-Nov-11 11:54 
GeneralRe: ... and a question (2) Pinmemberherves16-Nov-11 22:52 
GeneralRe: ... and a question (2) PinmemberKindDragon26-Apr-12 14:11 
QuestionMouseWheelRedirect Pinmembergeoyar14-Nov-11 8:48 
AnswerRe: MouseWheelRedirect Pinmemberifdefdebug15-Nov-11 5:12 
GeneralMy vote of 5 PinmemberMember 46152968-Nov-11 23:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 16 Nov 2011
Article Copyright 2011 by ifdefdebug
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid