Ver Mensaje Individual
  #6 (permalink)  
Antiguo 04/11/2005, 04:40
Avatar de Jose_minglein2
Jose_minglein2
 
Fecha de Ingreso: noviembre-2004
Mensajes: 2.344
Antigüedad: 19 años, 6 meses
Puntos: 8
Bien aquí pongo un codigo que detecta el click izquierdo del mouse en cualquier parte de windows, (incluso en el administrador de tareas), para ello implemento en una dll la siguiente clase ( que es una mezcla de la que saque de codeproject y del guille):

Código:
using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Rep
{
	/// <summary>
	/// Descripción breve de Class1.
	/// </summary>
	public class Mouse
	{
		public Mouse()
		{
			//
			// TODO: agregar aquí la lógica del constructor
			//
		}
		# region "API"
		private const int HC_ACTION = 0;
		private const int WH_MOUSE_LL = 14;
		private const int WM_MOUSEMOVE = 0x0200;
		static int hHook = 0;
		public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
		public const int WH_MOUSE = 7;
		HookProc MouseHookProcedure;
		[StructLayout(LayoutKind.Sequential)]
			public class POINT
		{
			public int x;
			public int y;
		}

		[StructLayout(LayoutKind.Sequential)]
			public class MouseHookStruct
		{
			public POINT pt;
			public int hwnd;
			public int wHitTestCode;
			public int dwExtraInfo;
		}
		[DllImport("user32.dll",CharSet=CharSet.Auto,
			 CallingConvention=CallingConvention.StdCall)]
		public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
			IntPtr hInstance, int threadId);

		//This is the Import for the UnhookWindowsHookEx function.
		//Call this function to uninstall the hook.
		[DllImport("user32.dll",CharSet=CharSet.Auto,
			 CallingConvention=CallingConvention.StdCall)]
		public static extern bool UnhookWindowsHookEx(int idHook);

		//This is the Import for the CallNextHookEx function.
		//Use this function to pass the hook information to the next hook procedure in chain.
		[DllImport("user32.dll",CharSet=CharSet.Auto,
			 CallingConvention=CallingConvention.StdCall)]
		public static extern int CallNextHookEx(int idHook, int nCode,
			IntPtr wParam, IntPtr lParam);

		
		public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
		{
			//Marshall the data from the callback.
			MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

			if (nCode < 0)
			{
				return CallNextHookEx(hHook, nCode, wParam, lParam);

			}
			else
			{
				//Create a string variable that shows the current mouse coordinates.
				if (wParam.ToString() == "513")
				{
					this.Click(this, new EventArgs());
				}				
				return CallNextHookEx(hHook, nCode, wParam, lParam);
			}
		}
		#endregion
		# region PUBLICAS
		public event EventHandler Click;

		protected virtual void OnClick(EventArgs e)
		{
			if(Click != null)
				Click(this, e);
		}

		public bool Activa()
		{
			if (hHook==0)
			{
				MouseHookProcedure = new HookProc(MouseHookProc);

				hHook = SetWindowsHookEx(WH_MOUSE_LL,
					MouseHookProcedure,
					Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
					0);
				return true;
			}
			else
				return false;
		}
		public bool Desactiva()
		{
			bool ret = UnhookWindowsHookEx(hHook);
			//If the UnhookWindowsHookEx function fails.
			if(ret == false )
			{
				return false;
			}
			hHook = 0;
			return true;
		}
		#endregion
		
	}
}
Lo que hace es detectar si wParam es 513 y entonces lanza un evento. Luego en la aplicación (winform) que la usemos, tras compilar y agregar la dll generada hacemos

Código:
protected withevents My_controlMouse as Mouse

private sub Form_Load(...)
My_controlMouse = new Mouse()
My_controlMouse.Activa()
end sub

private sub Form_closing()
My_controlMouse.Desactiva()
end sub
private sub Mouse_Click(byval sender as object, byval e as eventargs) handles My_ControlMouse.Click

'Código que queramos que para cuando detecte cualquier click
end sub
Se puede aumentar la funcionalidad agregando elementos como posición, click derecho........, pero yo sólo he implementado eso. Quizá el code no sea del todo óptimo pues es una especie de parche a los código mencionados. Así que, si alguién descubre como optimizarlo, por aquí andamos.
Ah se me olvidaba!!!!
La funciones Activa y Desactiva son necesarias para asignar/desasignar este "control" al form (o aplicación que queramos).

Por último agradecer al foro, a elguille y a codeproject la publicación de su codigo.

Un saludo.