Debido a un accidente navideño con el teclado del ordenador, que incluyó el agravante de la sidra ecológica, tenemos desde hace poco uno nuevo, inalámbrico, que con estas ideas brillantes para abaratar costes, resulta que no tiene LEDs indicadores del estado de las teclas de bloqueo de mayúsculas, numérico y de desplazamiento. A resultas de esto, me ha picado el gusanillo de la programación rápida, y he creado una aplicacioncita en .NET que se encarga de controlar el estado de esas teclas e informa al usuario mediante un icono de notificación en la barra de sistema.
La verdad es que es una aplicación bastante simple, pero ya que hacÃa tiempo que no subÃa nada de programación al blog, me ha parecido interesante dejarla aquà por si interesa a alguien y, de paso para recabar la opinión de los incondicionales
. Su nombre es KeyLed.
También incluyo la parte relevante del código, que no es demasiado extenso: Se trata de un WinForm que muestra el estado de las teclas en varios checkboxes, y que al ser minimizada queda en el systray. En todo momento, muestra un bocadillo con el estado de las teclas de bloqueo, mediante el uso de un temporizador que va comprobándolo cada cierto tiempo (500 milisegundos). He probado utilizando un delegado para el evento Idle de la aplicación, pero no se refresca tan a menudo como debiera, de ahà el uso final del temporizador.
-
{
-
public partial class KeyLed : Form
-
{
-
const int Interval = 500;
-
-
public KeyLed()
-
{
-
InitializeComponent();
-
-
KeyLedTimer.Interval = Interval;
-
KeyLedTimer.Enabled = true;
-
}
-
-
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
-
public static extern short GetKeyState(int keyCode);
-
-
private void KeyNotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
-
{
-
//Hacemos visible el formulario
-
this.Show();
-
this.WindowState = FormWindowState.Normal;
-
//Ocultamos el icono de la bandeja de sistema
-
KeyNotifyIcon.Visible = false;
-
}
-
-
private void KeyLed_Resize(object sender, EventArgs e)
-
{
-
//Si el estado actual de la ventana es "minimizado"...
-
if (this.WindowState == FormWindowState.Minimized)
-
{
-
//Ocultamos el formulario
-
this.Hide();
-
//this.Visible = false;
-
//Hacemos visible el icono de la bandeja del sistema
-
KeyNotifyIcon.Visible = true;
-
}
-
}
-
-
private void KeyLedTimer_Tick(object sender, EventArgs e)
-
{
-
-
KeyNotifyIcon.ShowBalloonTip(Interval, "", _numLock + _capsLock + _scrollLock, ToolTipIcon.Info);
-
}
-
}
Se me ocurren diversas mejoras, por ejemplo, que muestre la información de los leds cambiando el icono asociado al objeto NotifyIcon, de hecho funciona sin problema. Pero crear ocho iconos para esto me parece un pasote. Como con System.Drawing no he tenido que pelearme demasiado, a ver si existe una opción más eficiente que la que os presento. A partir del icono inicial, es posible usar el método ToBitmap() de la clase Icon para obtener un BMP en memoria sobre el que trabajar (por ejemplo, cambiando el color de un determinado pixel con SetPixel. Sin embargo, me parece poco adecuado tratar dinámicamente el icono, porque posiblemente sea mayor el tiempo de volver a dibujar el estado de los leds que cargar un icono distinto. ¿Alguna opinión al respecto? ¿Monto ambos sistemas y le hacemos pasar unos pocos benchmarks? ¿Merece la pena, realmente, todo esto? Jajaja.
Un saludo.
Actualización:
Acabo de darme cuenta, al encender el altavoz, del molesto efecto de "pop, pop" en el refresco del estado, al volver a pintar el bocadillo. Asà las cosas, me da que no hay más opción que diseñarme el icono adecuado y actualizarlo dinámicamente. Asà las cosas, vuelvo a la pregunta que planteaba al final de la entrada: ¿lo "repinto" en memoria, o cargo uno de una colección de iconos previamente almacenados?
Entradas relacionadas:
Etiquetas: .net, Programación


