tags:

views:

34

answers:

1

I would like to create one common handler of all right clicks (or possibly some other unique behavior like middle button click, etc.) happening in my application. They would invoke the same action, e.g. fire up dialog to customize control that was clicked or display help dialog for it.

Is there a mechanism, which would allow me to intercept all click events in application, each providing reference to control over which the click happened? Brute force solution would be to use reflection to iterate over all controls in every form I'm creating and attach a handler there, but I'm looking for something more strightforward.

+1  A: 

You could try implementing the IMessageFilter interface on your form. There are several other discussions and documentation on it. One possible solution for you might look like (create a form, place a button on it, add the necessary code from below, run it and try right clicking on the form and on the button):

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

namespace WindowsApplication1
{
   public partial class Form1 : Form, IMessageFilter
   {
      private const int WM_RBUTTONUP = 0x0205;

      [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
      public static extern IntPtr GetCapture();

      public Form1()
      {
         InitializeComponent();
         Application.AddMessageFilter(this);
      }

      public bool PreFilterMessage(ref Message m)
      {
         if (m.Msg == WM_RBUTTONUP)
         {
            System.Diagnostics.Debug.WriteLine("pre wm_rbuttonup");

            // Get a handle to the control that has "captured the mouse".  This works
            // in my simple test.  You can read the documentation and do more research
            // on it if you'd like:
            // http://msdn.microsoft.com/en-us/library/ms646257(v=VS.85).aspx
            IntPtr ptr = GetCapture();
            System.Diagnostics.Debug.WriteLine(ptr.ToString());

            Control control = System.Windows.Forms.Control.FromChildHandle(ptr);
            System.Diagnostics.Debug.WriteLine(control.Name);

            // Return true if you want to stop the message from going any further.
            //return true;
         }

         return false;
      }
   }
}