HowTo: Crear un hook de teclado para registrar una hotkey en nuestra aplicación

hook

Hola de nuevo,

En los grupos de MSDN suele haber bastantes preguntas acerca de crear hooks de teclado, para que nuestra aplicación pueda ejecutar alguna acción determinada, en respuesta a alguna pulsación de teclado, aunque no esté activa.

He creado una pequeña clase llamada WindowsShell que contiene el código necesario para registrar una hotkey y asociarla a un formulario:

   1: using System;

   2: using System.Runtime.InteropServices;

   3: using System.Windows.Forms;

   4:  

   5: namespace TestRegisterHotKey

   6: {

   7:     public class WindowsShell

   8:     {

   9:         public enum ModifierEnum

  10:         {

  11:             MOD_ALT = 0x1,

  12:             MOD_CONTROL = 0x2,

  13:             MOD_SHIFT = 0x4,

  14:             MOD_WIN = 0x8

  15:         }

  16:  

  17:         private static int keyId;

  18:         public static int WM_HOTKEY = 0x312;

  19:  

  20:         [DllImport("user32.dll")]

  21:         private static extern bool RegisterHotKey(

  22:             IntPtr hWnd, int id, int fsModifiers, int vlc);

  23:  

  24:         [DllImport("user32.dll")]

  25:         private static extern bool UnregisterHotKey(

  26:             IntPtr hWnd, int id);

  27:  

  28:         public static void RegisterHotKey(Form f, Keys key)

  29:         {

  30:             int modifiers = 0;

  31:             if ((key & Keys.Alt) == Keys.Alt)

  32:                 modifiers = modifiers | (int)WindowsShell.ModifierEnum.MOD_ALT;

  33:             if ((key & Keys.Control) == Keys.Control)

  34:                 modifiers = modifiers | (int)WindowsShell.ModifierEnum.MOD_CONTROL;

  35:             if ((key & Keys.Shift) == Keys.Shift)

  36:                 modifiers = modifiers | (int)WindowsShell.ModifierEnum.MOD_SHIFT;

  37:             Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

  38:             f.Invoke(new Action(() =>

  39:             {

  40:                 keyId = f.GetHashCode();

  41:                 RegisterHotKey((IntPtr)f.Handle, keyId, modifiers, (int)k);

  42:             }));

  43:         }

  44:  

  45:         public static void UnregisterHotKey(Form f)

  46:         {

  47:             try

  48:             {

  49:                 f.Invoke(new Action(() =>

  50:                 {

  51:                     UnregisterHotKey(f.Handle, keyId);

  52:                 }));

  53:             }

  54:             catch (Exception)

  55:             {

  56:                 throw;

  57:             }

  58:         }

  59:  

  60:     }

  61: }

Posteriormente, para poder usar esta clase en un formulario cualquiera debemos interceptar el bucle de mensajes de Windows, y preguntar si se ha producido el mensaje en cuestión, y si la pulsación corresponde a nuestra hotkey:

   1: using System;

   2: using System.Windows.Forms;

   3:  

   4: namespace TestRegisterHotKey

   5: {

   6:     public partial class Form1 : Form

   7:     {        

   8:         public Form1()

   9:         {

  10:             InitializeComponent();

  11:             this.Shown += Form1_Shown;

  12:             this.FormClosed += Form1_FormClosed;

  13:         }

  14:  

  15:         void Form1_FormClosed(object sender, FormClosedEventArgs e)

  16:         {

  17:             WindowsShell.UnregisterHotKey(this);

  18:         }

  19:  

  20:         void Form1_Shown(object sender, EventArgs e)

  21:         {

  22:             Keys k = Keys.A | Keys.Control;

  23:             WindowsShell.RegisterHotKey(this, k);

  24:         }

  25:  

  26:         protected override void WndProc(ref Message m)

  27:         {

  28:             if (m.Msg == WindowsShell.WM_HOTKEY)

  29:             {

  30:                 Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);

  31:                 WindowsShell.ModifierEnum modifier = 

  32:                     (WindowsShell.ModifierEnum)((int)m.LParam & 0xFFFF);

  33:                 if (key == Keys.A && modifier == WindowsShell.ModifierEnum.MOD_CONTROL)

  34:                     showForm();

  35:             }

  36:             base.WndProc(ref m);

  37:         }

  38:  

  39:         private void showForm()

  40:         {

  41:             this.Text = 

  42:                 String.Format("Hokey pressed at: {0}", 

  43:                 DateTime.Now.ToLongTimeString());

  44:             this.Show();

  45:             if (this.WindowState == FormWindowState.Minimized)

  46:                 this.WindowState = FormWindowState.Normal;

  47:         }

  48:     }

  49: }

 

Espero que a más de uno le sirva,

HYEI :-)

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>