2009-09-03 10 views

Respuesta

1

Solución 1

La suscripción a cada evento en cada control dentro de un formulario es sin duda el más simple enfoque más a tomar, ya que sólo tiene que utilizar el código dado por Ramesh.

Sin embargo, otra técnica implica anular el método predeterminado de procesamiento de mensajes de Windows ("WndProc") en el control principal, en este caso, el formulario que contiene todos los controles. Esto tiene un efecto secundario que no podrá detectar cuando el cursor del mouse se mueva sobre los controles contenidos dentro de otro control principal. Por ejemplo, no podrá detectar cuándo el cursor del mouse está sobre un TextBox que está dentro de un TabControl. Esto se debe a que TabControl continuará procesando todos los eventos del mouse.

Solución 2

La siguiente solución va a superar todos los problemas al tratar de detectar que controlan el cursor del ratón está sobre el uso de una técnica conocida como ventanas engancha.

Los ganchos esencialmente nos permiten atrapar los eventos de mouse y teclado incluso antes de que se envíen a la ventana con foco.

He aquí una muestra:

public enum HookType : int 
    { 
    WH_JOURNALRECORD = 0, 
    WH_JOURNALPLAYBACK = 1, 
    WH_KEYBOARD = 2, 
    WH_GETMESSAGE = 3, 
    WH_CALLWNDPROC = 4, 
    WH_CBT = 5, 
    WH_SYSMSGFILTER = 6, 
    WH_MOUSE = 7, 
    WH_HARDWARE = 8, 
    WH_DEBUG = 9, 
    WH_SHELL = 10, 
    WH_FOREGROUNDIDLE = 11, 
    WH_CALLWNDPROCRET = 12, 
    WH_KEYBOARD_LL = 13, 
    WH_MOUSE_LL = 14 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
    public int X; 
    public int Y; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct MouseHookStruct 
    { 
    public POINT pt; 
    public int hwnd; 
    public int hitTestCode; 
    public int dwExtraInfo; 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern int SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hInstance, uint dwThreadId); 

    [DllImport("user32.dll", SetLastError= true)] 
    static extern int CallNextHookEx(int hook, int code, IntPtr wParam, IntPtr lParam); 

    [DllImport("kernel32.dll")] 
    static extern int GetLastError(); 

    [DllImport("kernel32.dll")] 
    static extern int GetCurrentThreadId(); 

    public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); 
    private static int hHook; 

    public Form1() 
    { 
    InitializeComponent(); 

    hHook = SetWindowsHookEx(HookType.WH_MOUSE, MouseHookProc, IntPtr.Zero, (uint)GetCurrentThreadId()); 
    if (hHook == 0) 
    MessageBox.Show("GetLastError: " + GetLastError()); 
    } 

    private int MouseHookProc(int code, IntPtr wParam, IntPtr lParam) 
    { 
    //Marshall the data from the callback. 
    MouseHookStruct mouseInfo = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); 

    if (code < 0) 
    { 
    return CallNextHookEx(hHook, code, wParam, lParam); 
    } 
    else 
    { 
    //Create a string variable that shows the current mouse coordinates. 
    String strCaption = "x = " + mouseInfo.pt.X.ToString("d") + 
    " y = " + mouseInfo.pt.Y.ToString("d"); 

    //You must get the active form because it is a static function. 
    Form tempForm = Form.ActiveForm; 

    Control c = Control.FromHandle((IntPtr)mouseInfo.hwnd); 
    if (c != null) 
    label1.Text = c.Name; 
    else 
    label1.Text = "Control not found"; 

    //Set the caption of the form. 
    tempForm.Text = strCaption; 

    return CallNextHookEx(hHook, code, wParam, lParam); 
    } 
    } 
1

Otros controles en el formulario no pueden escuchar los controladores de eventos Mouse del formulario. Porque cada control tiene sus propios listadores de eventos de mouse.

Pero Usted puede suscribirse cada evento controles del ratón a los eventos del ratón formas

this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown);  
this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown); 
this.ListBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown); 

esta manera se puede tener un solo controlador para todos los eventos de los controles del ratón.

2

Me pareció que para ser la mejor solución para mis propósitos.

Crear una nueva clase derivada de IMessageFilter:

public class GlobalMouseHandler : IMessageFilter 
{ 

    private const int WM_LBUTTONDOWN = 0x201; 

    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.Msg == WM_LBUTTONDOWN) 
     { 
      // do something 
      ((YourMainForm)Form.ActiveForm).YourMainForm_Click(null, null); 
     } 
     return false; 
    } 
} 

Luego, en su forma principal añadir esto para registrar el filtro de mensajes:

GlobalMouseHandler globalClick = new GlobalMouseHandler(); 
Application.AddMessageFilter(globalClick); 

y añadir esta función para hacer lo que tiene que hacerlo, en su forma:

public void YourMainForm_Click(object sender, EventArgs e) 
{ 
    // do anything here... 
} 
Cuestiones relacionadas