Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I capture the mouse move event

Tags:

c#

winforms

I would like to capture the mouse move event in my main form. Although I am able to wire up the MouseEventHandler for the main form, the event no longer fires when the cursor is over a UserControl or any other control. How do I ensure that I always have the mouse position.

like image 288
fishhead Avatar asked Jan 14 '10 12:01

fishhead


2 Answers

You could use a low level mouse hook. See this example and check for the WM_MOUSEMOVE mesage in HookCallback.

You could also use the IMessageFilter class to catch the Mouse Events and trigger an event to get the position (note: this will only get the position over the window, not outside of it):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace GlobalMouseEvents
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         GlobalMouseHandler gmh = new GlobalMouseHandler();
         gmh.TheMouseMoved += new MouseMovedEvent(gmh_TheMouseMoved);
         Application.AddMessageFilter(gmh);

         InitializeComponent();
      }

      void gmh_TheMouseMoved()
      {
         Point cur_pos = System.Windows.Forms.Cursor.Position;
         System.Console.WriteLine(cur_pos);
      }
   }

   public delegate void MouseMovedEvent();

   public class GlobalMouseHandler : IMessageFilter
   {
      private const int WM_MOUSEMOVE = 0x0200;

      public event MouseMovedEvent TheMouseMoved;

      #region IMessageFilter Members

      public bool PreFilterMessage(ref Message m)
      {
         if (m.Msg == WM_MOUSEMOVE)
         {
            if (TheMouseMoved != null)
            {
               TheMouseMoved();
            }
         }
         // Always allow message to continue to the next filter control
         return false;
      }

      #endregion
   }
}
like image 133
SwDevMan81 Avatar answered Sep 28 '22 10:09

SwDevMan81


Here is the solution. Although I can see another answer with a similar approach. But since I wrote it I want to post it. Here MouseMessageFilter has a static event call MouseMove which you can subscribe from anywhere within the application.

static class Program
{
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);            
        Application.AddMessageFilter(new MouseMessageFilter());
        MouseMessageFilter.MouseMove += new MouseEventHandler(OnGlobalMouseMove);

        Application.Run(new MainForm());
    }

    static void OnGlobalMouseMove(object sender, MouseEventArgs e) {
        Console.WriteLine(e.Location.ToString());
    }
 }

class MouseMessageFilter : IMessageFilter
{
    public static event MouseEventHandler MouseMove = delegate { }; 
    const int WM_MOUSEMOVE = 0x0200;

    public bool PreFilterMessage(ref Message m) {

        if (m.Msg == WM_MOUSEMOVE) {

            Point mousePosition = Control.MousePosition;

            MouseMove(null, new MouseEventArgs(
                MouseButtons.None, 0, mousePosition.X, mousePosition.Y,0));
        }    
        return false;
    }
}
like image 41
particle Avatar answered Sep 28 '22 11:09

particle