Vamos a programar #87 - Camino a KeyRemap, MessageTextBox .

Hola de nuevo a todos, el día de hoy vamos a empezar un programa que nos sirva para re- configurar las teclas de nuestro teclado.


En el post anterior vimos que es posible re-asignar algunas teclas, todo bien si conocemos cual es el código de la tecla que queremos cambiar (tanto la actual cómo la objetivo) pero actualmente existen teclados que tienen tantas teclas que no están dentro del estandar, que resulta difícil determinar el código buscando en Internet.

En este post veremos cómo es posible determinar el código de cada tecla usando un programa que escribiremos en C# (Si no te interesa, en el siguiente post veremos la versión final de este programa lista para usarse).

Para empezar, primero hay que saber cómo es que se "crean" las pulsaciones. En C# (y probablemente en windows) cuando presionamos una tecla, ocurren los siguientes tres:
  1. KeyDown
  2. KeyPress
  3. KeyUp
KeyDown es el momento en que presionamos la tecla, KeyPress ocurre el tiempo que mantenemos la tecla (usualmente una fracción de segundo pero cuenta aun) y KeyUp que es cuando soltamos la tecla. Windows envía un mensaje diciendo: "Se presiono la tecla con el código XXXX, ahora se mantiene la tecla con el código XXXX y se acaba de soltar la tecla con el código XXXX", cómo son mensajes del sistema operativo, es posible leerlos desde C#, para eso disponemos de dos formas. La primera de ellas es usando lo eventos "_KeyDown", "_KeyPress" y "_KeyUp", muchos de los controles que se pueden añadir a c# disponen de ellos, pero es mas común usarlos en controles "TextBox". Cuando se crea el procedimiento que maneja el evento, se usan dos parámetros, el primero del tipo "object" llamado "sender" y el segundo del tipo "KeyEventArgs" llamado "e"; en este, hay varios procedimientos que nos podrían ser de utilidad, uno de ellos llamado "KeyCode".

Supongamos que tenemos un control "ComboBox" llamado "MsCboKeyOut" al crear el manejador para el evento tendríamos algo cómo lo que sigue:
		private void MsCboKeyOut_KeyDown(object sender, KeyEventArgs e)
		{
			MessageBox.Show(e.KeyCode.ToString());
			e.SuppressKeyPress = true;
		}


Si accedemos al procedimiento "KeyCode" y presionamos la tecla de silencio (mute), esta nos devolverá un valor de 173. Si hacemos memoria, en el post anterior vimos que el código de esa tecla era E020 hexadecimal o 57376 decimal que dista mucho de lo que nos entrego. Incluso haciendo pruebas con varias teclas, el valor maximo que obtuve fue 255 decimal (FF hexadecimal) por lo que si queremos usar este procedimiento para saber el código de las teclas "no normales" simplemente no nos sera posible.

La manera correcta de  de saber el valor real de la tecla, es leyendo directamente el mensaje  lo lleva. En C#, podemos sobrecargar el procedimiento "WndProc" que básicamente sirve para leer los mensajes. Pero cómo queremos ser capaces de utilizar el valor cuando el formulario tiene el foco (que es lo mas común), crearemos un control sencillo con la sobrecarga para que asi podamos utilizarlo.


using System;
using System.Windows.Forms;

namespace KeyRemap
{
	class MessageTextBox : TextBox
	{
		public const int WM_KEYDOWN = 0x0100;
		private uint TheValue = 0;

		public string GetHexValue
		{
			get
			{
				return Convert.ToString(TheValue, toBase: 16);
			}
		}
		public uint ShowKeyCode(uint TheNumber)
		{
			uint KeyValue = TheNumber;
			uint KeyCode = ((KeyValue >> 16) % 256);
			uint IsExtendedKey = ((KeyValue >> 24) % 2);
			if (IsExtendedKey == 1)
			{
				KeyCode = FrmMain.EXTENDED_KEY_VALUE | KeyCode;
				return KeyCode;
			}
			else
				return KeyCode;
		}

		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
		protected override void WndProc(ref Message m)
		{
			switch (m.Msg)
			{
				case WM_KEYDOWN:
					base.Text = "";
					base.Text = Convert.ToString(ShowKeyCode((uint)m.LParam));
					TheValue = (uint)m.LParam;
					break;
			}
			base.WndProc(ref m);
		}
	}
}



Con este control será mas sencillo interceptar el mensaje que contiene el código de la tecla. Para usarlo, simplemente agrega una nueva clase a tu proyecto y  el evento "_KeyDown" del parámetro "e" , la propiedad "SuppressKeyPress" se debe de establecer el valor de "true" para que el texto que se escriba en el cuadro de texto, corresponda solamente al código de la tecla, si no se suprime la pulsación, si por ejemplo presionamos la tecla "u", en la caja de texto diría "uxx" (donde xx es el código de la tecla u).

Por ahora solo veremos esto y cómo aun falta implementar mucho código, la explicacion detallada vendrá en el siguiente post (junto con la versión ultra beta de "KeyRemap M"), por ahora si sabes programar en C# puede probar el control (y si algo anda mal me pueden avisar).

Los leo luego.

No hay comentarios.