Frage

Ich habe ein Problem mit meinem WinForm auf Mouseevent C # Anwendung.

Ich will bekommen alle Mausklicks auf meine Anwendung, aber ich möchte nicht, einen Zuhörer in jedem Kind Komponente setzen weder Windows-Maus-Hook verwenden.

Ein Flash I einen Zuhörer auf der Bühne konnte alle Mausevents auf dem Film zu erhalten.

Gibt es so etwas auf C #? Ein globaler Mouselistener?


Edit:

Ich schaffe diese Klasse von IMessageFilter ans verwendet 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;
    }
}

Und diesen Code setzen auf die Steuerelemente, die globale Klicks hören müssen:

GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);
War es hilfreich?

Lösung

Eine einfache Möglichkeit, dies zu tun, ist ein Nachricht Schleifenfilter hinzufügen, indem Application.AddMessageFilter Aufruf und eine Klasse zu schreiben, die den IMessageFilter-Schnittstelle implementiert.

Via IMessageFilter.PreFilterMessage, Ihre Klasse bekommt alle Eingänge Nachrichten zu sehen, die Ihre Anwendung der Nachrichtenschleife durchlaufen. PreFilterMessage wird auch zu entscheiden, ob diese Meldungen an die spezifische Steuerung passieren, an die sie bestimmt sind.

Ein Stück Komplexität, dass dieser Ansatz einführt wird mit Windows-Nachrichten umgehen, über die Nachricht an Ihrer PreFilterMessage Methode übergeben Struct. Das bedeutet, die sich auf die Win32-Dokumention auf WM\_LBUTTONDOWN, WM\_MOUSEMOVE, WM\_LBUTTONUP usw., anstelle der konventionellen MouseDown, MouseMove und MouseUp Ereignisse.

Andere Tipps

Proben Klasse

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
}

einen Blick auf diesen Artikel nehmen. Es hoooks rekursiv alle Steuerungsereignisse und sendet sie. Sie könnten auch außer Kraft setzen WndProc in Ihrem Formular.

Wenn Sie die Nachrichten nicht durch zwingende Form.PreProcessMessage oder Form.WndProc handhaben möchten dann Sie Formularunterklasse könnte einen Event-Handler für alle Ereignisse Mouseclick aus den verschiedenen Steuerelemente auf dem Formular einzuhaken.
EDIT: vergessen haben, durch Kinder Kontrollen der Kontrollen auf dem Formular Rekursion

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

Ihre Formulare müssen dann von MousePreviewForm nicht System.Windows.Forms.Form abzuleiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top