leave c# winforms mousewheel

mouse leave c#



Evento de rueda del mouse(C#) (8)

No puedo obtener el evento Mouse Wheel en el formulario principal.

Como demostración, se me ocurrió un ejemplo simple:

public partial class Form1 : Form { public Form1() { InitializeComponent(); this.panel1.MouseWheel += new MouseEventHandler(panel1_MouseWheel); this.panel1.MouseMove += new MouseEventHandler(panel1_MouseWheel); Form2 f2 = new Form2(); f2.Show(this); } private void panel1_MouseWheel(object sender, MouseEventArgs e) { if(e.Delta != 0) Console.Out.WriteLine(e.Delta); } } public partial class Form2 : Form { public Form2() { InitializeComponent(); this.MouseMove += new MouseEventHandler(Form2_MouseMove); this.MouseWheel += new MouseEventHandler(Form2_MouseMove); } private void Form2_MouseMove(object sender, MouseEventArgs e) { if(e.Delta != 0) Console.Out.WriteLine(e.Delta); } }

Obtengo el evento de la rueda del mouse en Form2 pero no en Form1 ninguna idea?

Aclamaciones,

James


Sospecho que el OP desea obtener eventos de desplazamiento cuando solo el mouse está sobre el panel aunque el panel no tenga el foco.

Una forma de lograr este comportamiento se explica aquí:

http://social.msdn.microsoft.com/forums/en-US/winforms/thread/eb922ed2-1036-41ca-bd15-49daed7b637c/

y aquí:

http://social.msdn.microsoft.com/forums/en-US/winforms/thread/6bfb9287-986d-4c60-bbcc-23486e239384/

Uno de los fragmentos de código tomados del foro vinculado:

using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsApplication1 { public partial class Form1 : Form, IMessageFilter { public Form1() { InitializeComponent(); Application.AddMessageFilter(this); } public bool PreFilterMessage(ref Message m) { if (m.Msg == 0x20a) { // WM_MOUSEWHEEL, find the control at screen position m.LParam Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16); IntPtr hWnd = WindowFromPoint(pos); if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) { SendMessage(hWnd, m.Msg, m.WParam, m.LParam); return true; } } return false; } // P/Invoke declarations [DllImport("user32.dll")] private static extern IntPtr WindowFromPoint(Point pt); [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); } }

Este código básicamente interceptará todos los eventos de wm_mousewheel y los redirigirá al control sobre el que se encuentra el mouse actualmente. El panel ya no necesita tener el foco para recibir los eventos de la rueda.


Creo que has malinterpretado un poco mi problema. En mi formulario principal con el siguiente código, no recibo el evento MouseWheel:

public Form1() { InitializeComponent(); this.panel1.MouseWheel += new MouseEventHandler(panel1_MouseWheel); this.panel1.MouseMove += new MouseEventHandler(panel1_MouseWheel); }

Pero consigo el evento con:

public Form1() { InitializeComponent(); this.MouseWheel += new MouseEventHandler(panel1_MouseWheel); }

Espero que sea más claro sin la confusión de Form2. Simplemente estoy tratando de obtener eventos MouseWheel en un Panel en mi formulario principal.

Aclamaciones,

James


El Panel no puede tener el foco en sí mismo, solo un elemento colocado dentro del panel puede tener el foco. El panel solo recibirá el evento MouseWheel una vez que se coloque algo dentro de él y esa cosa tenga el foco. Simplemente mirando sobre el panel y moviendo la rueda del mouse se enviará el evento al formulario, no al panel.

Esta es la diferencia entre tus dos ejemplos.


Su problema surge del hecho de que form1 tiene foco, no panel1. ... lo que por supuesto significa que son los eventos de form1 los que se dispararán, no los eventos de panel1.

Recreé tu escenario con los siguientes cambios al constructor en Form1 y verifiqué que se dispara el evento de la rueda de desplazamiento.

public Form1() { InitializeComponent(); /* --- Old code that don''t work --- this.panel1.MouseWheel += new MouseEventHandler(panel1_MouseWheel); this.panel1.MouseMove += new MouseEventHandler(panel1_MouseWheel); */ this.MouseWheel += new MouseEventHandler(panel1_MouseWheel); this.MouseMove += new MouseEventHandler(panel1_MouseWheel); Form2 f2 = new Form2(); f2.Show(this); } }


Tal vez esto funcione para usted?

public partial class Form1 : Form { public Form1() { InitializeComponent(); Form2 f2 = new Form2(); f2.MouseWheel += new MouseEventHandler(panel1_MouseWheel); f2.MouseMove += new MouseEventHandler(panel1_MouseWheel); f2.Show(this); } private void panel1_MouseWheel(object sender, MouseEventArgs e) { if(e.Delta != 0) Console.Out.WriteLine(e.Delta); } }


Agregue otro evento del panel MouseEnter y en su función Callback obtenga el foco de entrada:

void MouseEnterEvent() { this.Panel.Focus(); }


Gracias a la respuesta de @nitrogenycs, escribí una clase genérica simple para abordar fácilmente el problema:

using System; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Drawing; namespace MyNamespace { public class MouseWheelManagedForm : Form, IMessageFilter { private bool managed; public MouseWheelManagedForm () : this (true) { } public MouseWheelManagedForm (bool start) { managed = false; if (start) ManagedMouseWheelStart(); } protected override void Dispose (bool disposing) { if (disposing) ManagedMouseWheelStop(); base.Dispose(disposing); } /************************************ * IMessageFilter implementation * *********************************/ private const int WM_MOUSEWHEEL = 0x20a; // P/Invoke declarations [DllImport("user32.dll")] private static extern IntPtr WindowFromPoint (Point pt); [DllImport("user32.dll")] private static extern IntPtr SendMessage (IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); private bool IsChild (Control ctrl) { Control loopCtrl = ctrl; while (loopCtrl != null && loopCtrl != this) loopCtrl = loopCtrl.Parent; return (loopCtrl == this); } public bool PreFilterMessage (ref Message m) { if (m.Msg == WM_MOUSEWHEEL) { //Ensure the message was sent to a child of the current form if (IsChild(Control.FromHandle(m.HWnd))) { // Find the control at screen position m.LParam Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16); //Ensure control under the mouse is valid and is not the target control //otherwise we''d be trap in a loop. IntPtr hWnd = WindowFromPoint(pos); if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) { SendMessage(hWnd, m.Msg, m.WParam, m.LParam); return true; } } } return false; } /**************************************** * MouseWheelManagedForm specific methods * **************************************/ public void ManagedMouseWheelStart () { if (!managed) { managed = true; Application.AddMessageFilter(this); } } public void ManagedMouseWheelStop () { if (managed) { managed = false; Application.RemoveMessageFilter(this); } } } }

Desde allí, solo necesita heredar su Formulario de esta clase en lugar de Formulario para cada formulario en el que necesita que MouseWheel sea "administrado":

using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows.Forms; namespace MyApp { public partial class MyForm : MyNamespace.MouseWheelManagedForm { public MyForm () { InitializeComponent(); } } }

Espero que esto ayude a alguien más (que a mí).


this.MouseWheel += pictureBox1_MouseWheel; //tanımlama void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { if (Convert.ToString(e.Delta) == "120") { //yukarı } else if (Convert.ToString(e.Delta) == "-120") { //aşağı } }