Pregunta

necesito para detectar cuando el usuario mueve el ratón sobre el formulario y todos sus controles secundarios y también cuando sale de la Forma. Probé los eventos MouseEnter y MouseLeave del formulario, probé el WM_MOUSEMOVE y WM_MOUSELEAVE y WM_NCMOUSEMOVE y WM_NCMOUSELEAVE pares de mensajes de ventanas pero ninguno parece funcionar como quiero ...

La mayor parte de mi Formulario está ocupada por los controles secundarios de muchas clases, no hay área mucho más visibles cliente. Esto significa que si muevo el ratón muy rápidamente, no se detectará el movimiento del ratón, a pesar de que el ratón está dentro del formulario.

Por ejemplo, tengo un cuadro de texto que se acopla en la parte inferior y entre el escritorio y el cuadro de texto, sólo hay una pequeña frontera. Si rápidamente muevo el ratón desde la parte inferior en el cuadro de texto, no se detectará el movimiento del ratón, pero el ratón está dentro del cuadro de texto, por lo tanto, dentro del formulario.

¿Cómo puedo lograr lo que necesito?

¿Fue útil?

Solución

Puede enlazar el mensaje principal de bucle y postproceso alguno (WM_MOUSEMOVE) Mensaje de preproceso / lo que quiere.

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

    }
}

Otros consejos

¿Qué tal esto:. En OnLoad de su forma, de manera recursiva pasar por todos los controles secundarios (y sus hijos) y conectar el evento MouseEnter

A continuación, cada vez que el ratón entra en cualquier descendiente, será llamado el controlador de eventos. Del mismo modo, se podría conectar MouseMove y / o eventos MouseLeave.

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

En el control de usuario crear un Evento MouseHover para el control de este tipo, (u otro tipo de evento) como esto

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

En su WinFrom que alberga el control de usuario tiene esto para el control de usuario para manejar el MouseOver en su Designer.cs

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

que llama a este método en su WinForm

private void ThumbnailMouseHover(object sender, EventArgs e)
{

    ThumbImage thumb = (ThumbImage) sender;

}

Donde ThumbImage es el tipo de usercontrol

solución rápida y sucia:

private bool MouseInControl(Control ctrl)
{
    return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition));
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top