Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Forms: capturing MouseWheel

I have a Windows Form (working in C#.NET).

The form has a couple of panels top-side and some ComboBoxes and DataGridViews bottom-side.

I want to use the scroll events on the top-side panels, but if selecting a e.g. ComboBox the focus is lost. The panels contain various other controls.

How could I always receive the mouse wheel events when the mouse is over any of the panels ? So far I tried to use the MouseEnter / MouseEnter events but with no luck.

like image 741
n0ter Avatar asked Jan 22 '11 18:01

n0ter


1 Answers

What you describe sounds like you want to replicate the functionality of for example Microsoft Outlook, where you don't need to actually click to focus the control to use the mouse wheel on it.

This is a relatively advanced problem to solve: it involves implementing the IMessageFilter interface of the containing form, looking for WM_MOUSEWHEEL events and directing them to the control that the mouse is hovering over.

Here's an example (from here):

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication1 {
  public partial class Form1 : Form, IMessageFilter {
    public Form1() {
      InitializeComponent();
      Application.AddMessageFilter(this);
    }

    public bool PreFilterMessage(ref Message m) {
      if (m.Msg == 0x20a) {
        // WM_MOUSEWHEEL, find the control at screen position m.LParam
        Point pos = new Point(m.LParam.ToInt32());
        IntPtr hWnd = WindowFromPoint(pos);
        if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) {
          SendMessage(hWnd, m.Msg, m.WParam, m.LParam);
          return true;
        }
      }
      return false;
    }

    // P/Invoke declarations
    [DllImport("user32.dll")]
    private static extern IntPtr WindowFromPoint(Point pt);
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
  }
}

Note that this code is active for all the forms in your application, not just the main form.

like image 192
Jon Grant Avatar answered Sep 20 '22 00:09

Jon Grant