Controlando tu computadora con el Wiimote mediante C# Parte III

En esta entrega se trata el tema del control de los dispositivos de teclado y ratón mediante C#, con el fin de enlazar el conocimiento anterior de la conexión entre la computadora y el mando de wii. Primero se tiene que ahondar un asunto. Las librerías .NET no brindan de manera  nativa una interfaz para enviar señales de teclado o de ratón. Por esta razón es necesario utilizar los mecanismos para interactuar con las librerías  de Windows desde C#. El mecanismo provisto por Microsoft para permitir la interacción de código nativo con plataformas de código manejado como la Plataforma .NET  se conoce como Servicios de Invocación de Plataforma o P/Invoke (Del Inglés  Platform Invoke Services).
Para utilizar una librería nativa desde código C#, primero se necesita incluir la librería que provee los servicios de Invocación de Plataforma, para esto basta introducir la sentencia: using System.Runtime.InteropServices; en la sección donde se incluyen las librerías de nuestro código.
Existen muchas librerías que pueden ser enlazadas de esta manera pero, para mantener el hilo conductor del tema se utilizará la librería “user32.dll” que es la librería encargada de, entre muchas funciones, manejar eventos producidos por el teclado y el ratón dentro del sistema operativo. Esto nos resulta muy beneficioso pues los movimientos realizados usando esta librería serán interpretados de la misma manera que si fueran producidos por el teclado o el ratón “reales”.
Para más información sobre las posibilidades de  uso de p/invoke  y de la librería user32.dll pueden visitar: http://www.pinvoke.net/.
Con el fin de poder controlar los movimientos de ratón, será necesario hacer referencia al método mouse_event de la librería "user32.dd". Para hacer uso del método externo escribimos lo siguiente
[DllImport("user32.dll")]
        public static extern void mouse_event(
            int dwFlags,
            int dx, int dy,
            int dwData,
            IntPtr dwExtraInfo
        );
Aquí DllImport("") es la función usada por el CLR para saber que librería adjuntar. En el ejemplo anterior se incluye a "user32.dll".
Como paso siguiente se escribe el método externo a utilizar así como sus parámetros si es que existen. Como dato a destacar se tiene la utilización del modificador extern para indicarle al compilador que la implementación del método se encuentra en una librería externa al mismo.
El método mouse_event representa a todos los eventos que puede experimentar un ratón.
El atributo dwFlags   especifica varios aspectos del movimiento del ratón y de sus botones. Este parámetro puede ser una combinación de los siguientes valores.
Los valores que especifican el estado de los botones del ratón se encuentran configurados para indicar cambios en el estado del ratón, no para representar condiciones repetidas. Un ejemplo de esto puede ser que si se presiona el botón izquierdo del ratón y se sostiene, la condición MOUSEEVENTF_LEFTDOWN se activa cuando el botón izquierdo se presiona por primera vez pero no para movimientos siguientes. De una manera similar la condición MOUSEEVENTF_LEFTUP se activa solo cuando el botón se suelta.
Un detalle importante es que no se puede especificar las condiciones  MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN o MOUSEEVENTF_XUP de manera simultánea debido a que requieren el uso del parámetro dwData.
Esta es una tabla con los atributos disponibles así como su valor hexadecimal, que es el que utilizaremos en su aplicación:
Nombre del Atributo
Valor Hexadecimal
Función
MOUSEEVENTF_ABSOLUTE 0x8000 Especifica que los parámetros dx y dy contienen coordenadas absolutas normalizadas. Si no se incluye este atributo, esos parámetros contienen datos relativos (El cambio desde la última posición anterior reportada). Este atributo puede ser incluido sin importar el tipo de ratón o similares que se encuentren conectados.
MOUSEEVENTF_MOVE 0x0001 Especifica que ocurrió un movimiento.
MOUSEEVENTF_LEFTDOWN 0x0002 Especifica que el botón izquierdo ha sido presionado.
MOUSEEVENTF_LEFTUP 0x0004 Especifica que el botón izquierdo ha sido soltado.
MOUSEEVENTF_RIGHTDOWN 0x0008 Especifica que el botón derecho ha sido presionado.
MOUSEEVENTF_RIGHTUP 0x0010 Especifica que el botón derecho ha sido soltado.
MOUSEEVENTF_MIDDLEDOWN 0x0020 Especifica que el botón medio ha sido presionado.
MOUSEEVENTF_MIDDLEUP 0x0040 Especifica que el botón medio ha sido soltado.
MOUSEEVENTF_WHEEL 0x0800 Windows NT/2000/XP: Especifica que  la rueda del botón ha sido movida, si el ratón posee rueda. El movimiento es especificado en el parámetro dwData.
MOUSEEVENTF_XDOWN 0x0080 Windows 2000/XP: Especifica que un botón X ha sido presionado.
MOUSEEVENTF_XUP 0x0100 Windows 2000/XP: Especifica que un botón X ha sido soltado.
El parámetro dx especifica  la posición absoluta del ratón en el eje X, o la cantidad de movimiento desde que el último evento de ratón fue generado, esto dependiendo de si el atributo MOUSEEVENTF_ABSOLUTE fue incluido en el parámetro dwFlags.
El parámetro dy realiza la misma función que el parámetro dx, solo que para el eje Y.
El parámetro dwdata puede especificar varias cosas:
• Si se incluyó al atributo MOUSEEVENTF_WHEEL en dwFlags, entonces el parámetro especifica la cantidad de movimiento ejercido en la rueda del ratón Un valor positivo indica movimiento hacia adelante en dirección contraria al usuario mientras que un valor negativo indica un movimiento inverso. Un clic en la rueda se identifica mediante el valor WHEEL_DELTA, que corresponde al entero 120.
• Si se incluyó al atributo MOUSEEVENTF_XDOWN o MOUSEEVENTF_XUP en dwFlags, entonces dwData especifica que botones X son los que están siendo presionados o soltados. Este atributo es una combinación de los valores de los botones involucrados. (El primer botón XButton1 con valor hexadecimal 0x0001, o el botón XButton2 con el valor 0x0002).
• Si dwFlags no incluye a MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN o a MOUSEEVENTF_XUP, entonces el valor de  dwData debe ser cero.
El parámetro dwExtraInfo contiene datos adicionales relacionados al evento del ratón. Para este caso no será de utilidad así que en lo posible será asignado con valor nulo.
Para los valores de entrada del teclado se utiliza la misma lógica, primero se hace referencia al metodo que maneja el evento de presionar teclas:
[DllImport("user32.dll")]
        public static extern void keybd_event(
            byte bVk,
            byte bScan,
            int dwFlags,
            IntPtr dwExtraInfo
        );
Los parámetros para este método son:
El parámetro bVk especifica un código de tecla virtual. Este código debe corresponder a un valor en un rango entre 1 y 254. Los códigos de teclas virtuales y sus respectivos valores se pueden observar desde Esta Dirección. Para este artículo se utiliza el enum Keys incluido en la librería System.Windows.Forms, este enumerado contiene gran variedad de teclas y sus valores son correspondientes a las teclas virtuales.
El parámetro bScan permite incluir un código de hardware relacionado con la tecla, para este caso no se utiliza, se establece su valor como cero.
 dwFlags se comporta de la misma manera que el parámetro de mouse_event, permitiendo definir una serie de aspectos de la operación de la función. Se pueden incluir los siguientes atributos.





KEYEVENTF_EXTENDEDKEY: Si se incluye este atributo, el código especificado en bScan esta precedido por un prefijo de valor 0xE0 (224)







KEYEVENTF_KEYUP: Si se incluye este atributo,  la tecla está siendo soltada, de lo contrario esta siendo presionada.


Por último, el parámetro dwExtraInfo contiene datos adicionales relacionados al evento del ratón. Para este caso no será de utilidad así que en lo posible será asignado con valor nulo.

Mediante estas funciones es posible emular las acciones de un teclado  y un mouse, para ilustrar mejor la utilización de estas funciones he preparado el ejemplo siguiente.

Ejemplo de control de ratón utilizando nunchuk: EjemploNunchukMouse.zip


0 comentarios:

Publicar un comentario