6

How can I create an application that performs an action with keyboard shortcut (App must be unvisible). For example Shows MessageBox when user press Ctrl + Alt + W.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Togrul Ceferli
  • 121
  • 1
  • 10
  • You need to include more information about what you are trying to accomplish. Technology (winforms, wpf, etc.). Also your question seems to imply that it should be background task trying to hook the keyboard, but it isn't clear. – Steve Mitcham Aug 25 '10 at 17:50
  • 1
    Yes i want it to work on background. And Winforms – Togrul Ceferli Aug 25 '10 at 18:02

2 Answers2

13

One solution would be to use interop and use the Win32 RegisterHotKey API. Here is a quick and dirty example I just put together so it is not well tested and I am not sure that there are no unexepcted side effects, but it should work.

First here is a simple HotKeyManager this takes care of the basic interop, provides a hidden window to handle the native Windows messages (WM_HOTKEY) which is translated into a .NET event HotKeyPressed

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

  public class HotKeyManager
  {
    public static event EventHandler<HotKeyEventArgs> HotKeyPressed;

    public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
    {
      int id = System.Threading.Interlocked.Increment(ref _id);
      RegisterHotKey(_wnd.Handle, id, (uint)modifiers, (uint)key);
      return id;
    }

    public static bool UnregisterHotKey(int id)
    {
      return UnregisterHotKey(_wnd.Handle, id);
    }

    protected static void OnHotKeyPressed(HotKeyEventArgs e)
    {
      if (HotKeyManager.HotKeyPressed != null)
      {
        HotKeyManager.HotKeyPressed(null, e);
      }
    }

    private static MessageWindow _wnd = new MessageWindow();

    private class MessageWindow : Form
    {
      protected override void WndProc(ref Message m)
      {
        if (m.Msg == WM_HOTKEY)
        {
          HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
          HotKeyManager.OnHotKeyPressed(e);
        }

        base.WndProc(ref m);
      }

      private const int WM_HOTKEY = 0x312;
    }

    [DllImport("user32")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

    [DllImport("user32")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    private static int _id = 0;
  }


  public class HotKeyEventArgs : EventArgs
  {
    public readonly Keys Key;
    public readonly KeyModifiers Modifiers;

    public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
    {
      this.Key = key;
      this.Modifiers = modifiers;
    }

    public HotKeyEventArgs(IntPtr hotKeyParam)
    {
      uint param = (uint)hotKeyParam.ToInt64();
      Key = (Keys)((param & 0xffff0000) >> 16);
      Modifiers = (KeyModifiers)(param & 0x0000ffff);
    }
  }

  [Flags]
  public enum KeyModifiers
  {
    Alt = 1,
    Control = 2,
    Shift = 4,
    Windows = 8,
    NoRepeat = 0x4000
  }

The following shows a simple windows forms application which will keep the main form hidden and respond to the hot key events. I did not handle the closing of the application and the unregistering of the hot key, you can handle that.

using System;
using System.Windows.Forms;

namespace HotKeyManager
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      HotKeyManager.RegisterHotKey(Keys.A, KeyModifiers.Alt);
      HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);     
    }

    void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e)
    {
      MessageBox.Show("Hello");
    }

    protected override void SetVisibleCore(bool value)
    {      
      // Quick and dirty to keep the main window invisible      
      base.SetVisibleCore(false);
    }
  }
}
Rory
  • 40,559
  • 52
  • 175
  • 261
Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
  • I'm using this solution and it sort of works. However, I have an issue where it seems like keys (randomly) doesn't work. I have ALTGR + F1 up to F12 as hotkeys, and when the program's running, for instance, ALTGR + F3 doesn't work. Then you can close the program at open it again, it will then start working. Can you help me out as to why this is happening? – wads May 02 '22 at 12:22
-5

Add this to KeyPress event of your form:

if(e.KeyCode == (char)Keys.W && e.Modifiers == Keys.Control && e.Modifiers = Keys.Alt)
{
    MessageBox.Show("I think this is a homework and that you should study instead of asking for an already cooked up answer on programming websites","Cheater");
}
Wildhorn
  • 926
  • 1
  • 11
  • 30