Wednesday, September 14, 2011

How to check MouseDown event for all controls in WinForm

When a Form contains several child controls and nested UserControls, mouse click event is not propagated to parent form in WinForm. If one uses WPF, there is no need to add your code since WPF basically supports RoutedEvents. However, WinForm does not support Routed Events, so you have to manually implements the appropriate mechanism.

One way of doing is using Application.AddMessageFilter() method which basically add custom message filter to the application. Your custom MessageFilter should implement IMessageFilter interface which only has one method - IMessageFilter.PreFilterMessage(). In this method, you determine whether you want to filter out the message or you can add your custom code for specific message.

Here is an example of using MessageFilter. To check whether any control in the Form is clicked, I added a static property but this is only for simplified demonstration purpose, more options are available.

using System;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
   static class Program
   {
      [STAThread]
      static void Main()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);

         // Add Message Filter to precheck MouseDown
         IMessageFilter myFilter = new MyMessageFilter();
         Application.AddMessageFilter(myFilter);

         Application.Run(new Form1());
      }
   }

   public class MyMessageFilter : IMessageFilter
   {      
      public bool PreFilterMessage(ref Message m)
      {
         if (m.Msg == 0x201) //WM_LBUTTONDOWN
         {
            Form1.FormClicked = true; 
         }
         return false; // do not filter
      }
   }
}

namespace WindowsFormsApplication2
{
   public partial class Form1 : Form
   {            
      public static bool FormClicked {get; internal set;}      
      public Form1()
      {
         InitializeComponent();
      }
   }
}

No comments:

Post a Comment