Захват событий мыши от каждого компонента - PullRequest
30 голосов
/ 30 апреля 2009

У меня проблема с MouseEvents в моем приложении WinForm C #.

Я хочу получить всех щелчков мышью в моем приложении, но я не хочу помещать слушатель в каждый дочерний компонент и не использовать ловушку мыши Windows.

На Flash я мог бы поставить слушателя на сцену, чтобы получить все MouseEvents в фильме.

Есть ли такая вещь на C #? Глобальный MouseListener?


Изменить:

Я создаю этот класс из IMessageFilter и используемого Application.AddMessageFilter.

public class GlobalMouseHandler : IMessageFilter{

    private const int WM_LBUTTONDOWN = 0x201;

    public bool PreFilterMessage(ref Message m){
        if (m.Msg == WM_LBUTTONDOWN) {
            // Do stuffs
        }
        return false;
    }
}

И поместите этот код в элементы управления, которые должны прослушивать глобальные щелчки:

GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);

Ответы [ 4 ]

15 голосов
/ 30 апреля 2009

Один простой способ сделать это - добавить фильтр цикла сообщений, вызвав Application.AddMessageFilter и написав класс, который реализует интерфейс IMessageFilter.

Через IMessageFilter.PreFilterMessage ваш класс может видеть любые входные сообщения, которые проходят через цикл сообщений вашего приложения. PreFilterMessage также решает, передавать ли эти сообщения конкретному элементу управления, которому они предназначены.

Одна сложность, которую представляет этот подход, заключается в том, что приходится иметь дело с сообщениями Windows через структуру Message, передаваемую в ваш метод PreFilterMessage. Это означает обращение к документации Win32 по WM\_LBUTTONDOWN, WM\_MOUSEMOVE, WM\_LBUTTONUP и т. Д. Вместо обычных событий MouseDown, MouseMove и MouseUp.

5 голосов
/ 10 декабря 2010

Класс образцов

class CaptureEvents : IMessageFilter
{
    #region IMessageFilter Members
    public delegate void Callback(int message);
    public event Callback MessageReceived;

    IntPtr ownerWindow;
    Hashtable interestedMessages = null;
    CaptureEvents(IntPtr handle, int[] messages)
    {
        ownerWindow = handle;
        for(int c = 0; c < messages.Length ; c++)
        {
            interestedMessages[messages[c]] = 0;
        }
    }
    public bool PreFilterMessage(ref Message m)
    {
        if (m.HWnd == ownerWindow && interestedMessages.ContainsKey(m.Msg))
        {
            MessageReceived(m.Msg);
        }
        return true;
    }

    #endregion
}
3 голосов
/ 30 апреля 2009

Если вы не хотите обрабатывать сообщения путем переопределения Form.PreProcessMessage или Form.WndProc, то вы можете создать подкласс Form, чтобы подключить обработчик событий ко всем событиям MouseClick из различных элементов управления в форме. РЕДАКТИРОВАТЬ: забыли использовать через дочерние элементы управления в форме.

    public class MousePreviewForm : Form
    {
      protected override void OnClosed(EventArgs e)
      {
         UnhookControl(this as Control);
         base.OnClosed(e);
      }

      protected override void OnLoad(EventArgs e)
      {
         base.OnLoad(e);

         HookControl(this as Control);
      }

      private void HookControl(Control controlToHook)
      {
         controlToHook.MouseClick += AllControlsMouseClick;
         foreach (Control ctl in controlToHook.Controls)
         {
            HookControl(ctl);
         }      
      }

      private void UnhookControl(Control controlToUnhook)
      {
         controlToUnhook.MouseClick -= AllControlsMouseClick;
         foreach (Control ctl in controlToUnhook.Controls)
         {
            UnhookControl(ctl);
         }
      }

      void AllControlsMouseClick(object sender, MouseEventArgs e)
      {
         //do clever stuff here...
         throw new NotImplementedException();
      }
   }

Тогда ваши формы должны быть получены из MousePreviewForm, а не System.Windows.Forms.Form.

3 голосов
/ 30 апреля 2009

Взгляните на эту статью . Он рекурсивно обрабатывает все контрольные события и транслирует их. Вы также можете переопределить WndProc в вашей форме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...