Mouse Hook del sistema Fecha: 02/Dic/2004 (2-Diciembre-2004)
|
Hola, quer�a compartir con todos ustedes, una manera bien sencilla de escuchar todos los eventos del mouse, pero a nivel global. Com�nmente estamos acostumbrados a capturar los eventos del mouse dentro de un control en espec�fico, pero cuando queremos extender esta funcionalidad a todo el sistema, tenemos que usar el mecanismo de hooks que nos brinda el sistema operativo. Para ello he usado la tecnolog�a P/Invoke de .NET y marshaling.
A continuaci�n las declaraciones necesarias:
private const int HC_ACTION = 0; private const int WH_MOUSE_LL = 14; private const int WM_MOUSEMOVE = 0x0200; private delegate int HookProc(int nCode, int wParam, int lParam); struct MSLLHOOKSTRUCT { public POINT pt; public uint mouseData; public uint flags; public uint time; public IntPtr dwExtraInfo; } public struct POINT { public int x; public int y; } [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall, SetLastError = true)] private static extern bool UnhookWindowsHookEx(IntPtr hHook); [DllImport("user32.dll", EntryPoint="CallNextHookEx", CharSet=CharSet.Auto , SetLastError = true)] public static extern int CallNextHookEx(int hHook, int nCode, int wParam, int lParam); private IntPtr hHook = IntPtr.Zero; int n = 0; private int LowLevelMouseProc(int nCode, int wParam, int lParam) { if (nCode < 0) return CallNextHookEx(0, nCode, wParam,lParam); if (n == 0) { if (nCode == HC_ACTION) { if (wParam == WM_MOUSEMOVE) { MSLLHOOKSTRUCT data = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(new IntPtr(lParam), typeof(MSLLHOOKSTRUCT)); string s = "X: " + data.pt.x + "\tY:" + data.pt.y + "\r\n"; textBoxOut.Text = s + textBoxOut.Text; } } } n = (n + 1) % 10; return CallNextHookEx(0, nCode, wParam, lParam); }Con todas estas declaraciones, solo nos queda ubicar lo siguiente en los eventos de la forma principal:
private void MainForm_Load(object sender, System.EventArgs e) { hHook = SetWindowsHookEx(WH_MOUSE_LL, new HookProc(LowLevelMouseProc), Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); } private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e) { UnhookWindowsHookEx(hHook); }
Fichero con el c�digo de ejemplo: aldenml_MouseHook.zip - 7 KB