Foros del Web » Programación para mayores de 30 ;) » .NET »

Control del mouse

Estas en el tema de Control del mouse en el foro de .NET en Foros del Web. Buenas, llevo un par de dias buscando y probando, lo que necesito es controlar los eventos del mouse en windows (es decir, inclusive los de ...
  #1 (permalink)  
Antiguo 20/10/2005, 08:59
Avatar de Jose_minglein2  
Fecha de Ingreso: noviembre-2004
Mensajes: 2.344
Antigüedad: 19 años, 5 meses
Puntos: 8
Control del mouse

Buenas, llevo un par de dias buscando y probando, lo que necesito es controlar los eventos del mouse en windows (es decir, inclusive los de fuera de mi aplicación), es decir, si alguien hace click fuera de la ventana que tambien lo registre.

Se que es con las APIS de windows más exactamente con
SetWindowsHookEx y SetWindowsHook

pero no encuentro forma de utilizarlas de manera util.Si alguien tiene algo por ahí estaría muy agradecido.
  #2 (permalink)  
Antiguo 26/10/2005, 10:03
Avatar de Jose_minglein2  
Fecha de Ingreso: noviembre-2004
Mensajes: 2.344
Antigüedad: 19 años, 5 meses
Puntos: 8
Bien he conseguido detectar la posición, es decir que devuelva la posición x e y del ratón con respecto a la pantalla, pero siempre dentro del formulario, pero no consigo ni detectar el de fuera, ni que se detecte el click, el code con el que he conseguido la x y la "y" es de codeproject:

Código:
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 static 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.
				String strCaption = "x = " +
					MyMouseHookStruct.pt.x.ToString("d") +
					"  y = " +
					MyMouseHookStruct.pt.y.ToString("d");
				string a = MyMouseHookStruct.wHitTestCode.ToString();
				//You must get the active form because it is a static function.
				Form tempForm = Form.ActiveForm;

				//Set the caption of the form.
				tempForm.Text = a;
				return CallNextHookEx(hHook, nCode, wParam, lParam);
			}
		}
  #3 (permalink)  
Antiguo 26/10/2005, 21:32
 
Fecha de Ingreso: octubre-2005
Mensajes: 7
Antigüedad: 18 años, 6 meses
Puntos: 0
hola pues una idea seria que crees algun juego o algo asi.
O algo que creas tu que sea util ya sea para ti o para alguien mas.
Yo tenia un ejemplo de eso.
Aver si lo encuentro o si encuentro la pagina de donde lo tenia.
O mira no se si se pueda.
Crea un formulario invisible que abarque toda la pantalla y ahi obten la informacion y luego por medio de modulos mandala a otro formulario que al muestre.
La verdad no si se funcione (espero que si).
Bye
Saludos
  #4 (permalink)  
Antiguo 28/10/2005, 09:06
Avatar de Andres95
Colaborador
 
Fecha de Ingreso: diciembre-2004
Mensajes: 1.802
Antigüedad: 19 años, 4 meses
Puntos: 38
checa esta page...

da los eventos del mouse a nivel global...

Saludos!

http://www.elguille.info/colabora/pu..._MouseHook.htm
  #5 (permalink)  
Antiguo 28/10/2005, 12:30
Avatar de Jose_minglein2  
Fecha de Ingreso: noviembre-2004
Mensajes: 2.344
Antigüedad: 19 años, 5 meses
Puntos: 8
Muy bueno, muchisimas gracias, (pues había dado mil vueltas al elguille y no lo habia encontrado). Gracias de nuevo
  #6 (permalink)  
Antiguo 04/11/2005, 04:40
Avatar de Jose_minglein2  
Fecha de Ingreso: noviembre-2004
Mensajes: 2.344
Antigüedad: 19 años, 5 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.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:22.