2009-06-12 7 views
7

Ich muss erkennen, wenn der Benutzer die Maus über das Formular und alle seine untergeordneten Steuerelemente bewegt und auch wenn es das Formular verlässt. Ich versuchte, die MouseEnter und MouseLeave Ereignisse des Formulars, ich versuchte, die WM_MOUSEMOVE & WM_MOUSELEAVE und WM_NCMOUSEMOVE & WM_NCMOUSELEAVE Paare von Windows-Meldungen, aber keine scheinen zu arbeiten, wie ich will ...Wie erkennen Sie, ob sich die Maus innerhalb des gesamten Formulars und der untergeordneten Steuerelemente befindet?

Die meisten meiner Form von Kind Kontrollen besetzt ist von Viele Arten, es ist nicht viel Client-Bereich sichtbar. Dies bedeutet, dass wenn ich die Maus sehr schnell bewege, die Mausbewegung nicht erkannt wird, obwohl sich die Maus in der Form befindet.

Zum Beispiel habe ich eine TextBox, die an der Unterseite und zwischen dem Desktop und der TextBox angedockt ist, gibt es nur eine sehr kleine Grenze. Wenn ich die Maus schnell von unten nach oben in die TextBox verschiebe, wird die Mausbewegung nicht erkannt, aber die Maus befindet sich innerhalb der TextBox, also innerhalb des Formulars.

Wie kann ich erreichen, was ich brauche?

Antwort

13

Sie können die Hauptnachrichtenschleife einhängen und jede Nachricht (WM_MOUSEMOVE) vorverarbeiten/nachbearbeiten, was Sie wollen.

public class Form1 : Form { 
    private MouseMoveMessageFilter mouseMessageFilter; 
    protected override void OnLoad(EventArgs e) { 
     base.OnLoad(e); 

     this.mouseMessageFilter = new MouseMoveMessageFilter(); 
     this.mouseMessageFilter.TargetForm = this; 
     Application.AddMessageFilter(this.mouseMessageFilter); 
    } 

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

     Application.RemoveMessageFilter(this.mouseMessageFilter); 
    } 

    class MouseMoveMessageFilter : IMessageFilter { 
     public Form TargetForm { get; set; } 

     public bool PreFilterMessage(ref Message m) { 
      int numMsg = m.Msg; 
      if (numMsg == 0x0200 /*WM_MOUSEMOVE*/) { 
       this.TargetForm.Text = string.Format("X:{0}, Y:{1}", Control.MousePosition.X, Control.MousePosition.Y); 
      } 

      return false; 
     } 

    } 
} 
+0

, dass nur sie die andere Art und Weise macht arbeiten ... ich meine, jetzt erkennt es, wenn die Maus über das Formular ist Kind steuert, aber nicht das Formular selbst. Ich möchte das Ganze erkennen. Ich muss auch erkennen, wann die Maus das Formular eingegeben hat und wann es gegangen ist, nicht nur, dass es sich innerhalb des Formulars bewegt. –

+0

Nun, ich fand genau das, was ich in diesem Beispiel gesucht habe: http://netcode.ru/dotnet/?lang=&katID=30&skatID=283&artID=7862. Es verwendet das gleiche Prinzip wie Ihre Antwort, der IMessageFilter. Und es ermöglicht mir zu erkennen, wann die Maus das Formular betritt und verlässt. Ich muss mich einfach anpassen und den Code so streichen, wie ich möchte. Wie auch immer, wenn Sie Ihre Antwort auf dem IMessageFilter ausarbeiten können, was es ist, wie es funktioniert und all das, werde ich diese Antwort als die akzeptierte markieren. Und bitte fügen Sie eine Notiz hinzu, um die Kommentare für andere Leute zu überprüfen, die nach einer Lösung für genau das gleiche Problem suchen. –

+0

Haben Sie meine Anfrage TcKS überhaupt gesehen? Vielleicht machst du diese Zeit ... Könntest du bitte deinen Beitrag bearbeiten und ein wenig über das ganze IMessageFilter-Ding und wie es funktioniert? –

2

Wie wäre es damit: In Ihrem OnLoad des Formulars rekursiv alle untergeordneten Kontrollen durchlaufen (und ihre Kinder) und die MouseEnter- Ereignis anschließen.

Wenn die Maus einen Nachkommen eingibt, wird der Ereignishandler aufgerufen. Auf ähnliche Weise können Sie MouseMove- und/oder MouseLeave-Ereignisse verbinden.

protected override void OnLoad() 
{ 
    HookupMouseEnterEvents(this); 
} 

private void HookupMouseEnterEvents(Control control) 
{ 
    foreach (Control childControl in control.Controls) 
    { 
     childControl.MouseEnter += new MouseEventHandler(mouseEnter); 

     // Recurse on this child to get all of its descendents. 
     HookupMouseEnterEvents(childControl); 
    } 
} 
+0

Ich würde das eine "Abhilfe" und nicht die Lösung nennen, also keine ... –

+0

Es wird nicht funktionieren, wenn die Steuerelemente während der Lebensdauer des Formulars ändern. – TcKs

0

Auf Ihrer Benutzersteuerung erstellen ein MouseHover-Ereignis für das Steuerelement wie diese (oder eine anderen Ereignis-Typen) wie diese

private void picBoxThumb_MouseHover(object sender, EventArgs e) 
{ 
    // Call Parent OnMouseHover Event 
    OnMouseHover(EventArgs.Empty); 
} 

Auf Ihrem WinFrom, die die Usercontrol Gastgeber dies für den Usercontrol Griff die Mouseover in Ihrem Designer.cs

this.thumbImage1.MouseHover += new System.EventHandler(this.ThumbnailMouseHover); 

, die dieses Verfahren auf Ihrem WinForm ruft

private void ThumbnailMouseHover(object sender, EventArgs e) 
{ 

    ThumbImage thumb = (ThumbImage) sender; 

} 

Wo ThumbImage die Art der Usercontrol ist

0

quick and dirty Lösung:

private bool MouseInControl(Control ctrl) 
{ 
    return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition)); 
} 
Verwandte Themen