Question

J'ai un problème avec MouseEvents sur mon application WinForm C #.

Je souhaite obtenir tous tous les clics de souris sur mon application, mais je ne souhaite pas insérer d'écouteur dans chaque composant enfant ni utiliser le crochet de souris de Windows.

Sur Flash, je pourrais mettre un auditeur sur scène pour obtenir tous les MouseEvents du film.

Y at-il une telle chose sur C #? Un MouseListener global?

Modifier:

Je crée cette classe à partir de IMessageFilter et utilisé 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;
    }
}

Et placez ce code sur les contrôles nécessitant des clics globaux pour listen:

GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);
Était-ce utile?

La solution

Une façon simple de procéder consiste à ajouter un filtre de boucle de message en appelant Application.AddMessageFilter et en écrivant une classe qui implémente l'interface IMessageFilter .

Via IMessageFilter.PreFilterMessage , votre classe a la possibilité de voir les messages d'entrée qui passent par la boucle de messages de votre application. PreFilterMessage détermine également s'il convient de transmettre ces messages au contrôle spécifique auquel ils sont destinés.

Cette approche introduit une complexité supplémentaire dans le traitement des messages Windows, via la structure Message transmise à votre méthode PreFilterMessage . Cela signifie que vous ferez référence à la documentation Win32 dans WM \ _LBUTTONDOWN, WM \ _MOUSEMOVE , WM \ _LBUTTONUP , etc., au lieu du MouseDown , Événements MouseMove et MouseUp .

Autres conseils

Exemple de classe

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
}

Consultez cet article . Il ramasse récursivement tous les événements de contrôle et les diffuse. Vous pouvez également remplacer WndProc dans votre formulaire.

Si vous ne souhaitez pas gérer les messages en remplaçant Form.PreProcessMessage ou Form.WndProc, vous pouvez sous-classer Form pour connecter un gestionnaire d'événements à tous les événements MouseClick des différents contrôles du formulaire.
EDIT: oublié de recurse à travers les contrôles enfants des contrôles sur le formulaire.

    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();
      }
   }

Vos formulaires devraient alors dériver de MousePreviewForm et non de System.Windows.Forms.Form.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top