31

I have a application that runs in the background. I have to generate some event whenever a user press F12 at anytime. So what I need that to capture a key-press. In my application, if any time a user press F10 some event will be performed. I don't understand how to do that?

Have anyone any idea how to do that?

N:B: It is a winforms application. It doesn't need to have focus my form. My main window may remain in system tray but still it have to capture the keypress.

Otiel
  • 18,404
  • 16
  • 78
  • 126
ImonBayazid
  • 1,066
  • 3
  • 16
  • 41
  • possible duplicate of [handling function key press](http://stackoverflow.com/questions/1707040/handling-function-key-press) – James Hill Mar 14 '13 at 15:18
  • What kind of application? What does it mean to "run in the background?" What is "anytime" (does your application have focus)? – Wonko the Sane Mar 14 '13 at 15:19
  • Are you using a form to do the keypress? Is this a Console Application? – DJ Burb Mar 14 '13 at 15:19
  • It is a winform application.it doesnt need to have focus my form.my main window may be in system tray but still it have to capture the keypress. – ImonBayazid Mar 14 '13 at 15:21
  • 1
    @JamesHill: Not a duplicate of this one, since we are not talking of the same type of shortcut keys. – Otiel Mar 14 '13 at 15:24

2 Answers2

55

What you want is a global hotkey.

  1. Import needed libraries at the top of your class:

    // DLL libraries used to manage hotkeys
    [DllImport("user32.dll")] 
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
    [DllImport("user32.dll")]
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
  2. Add a field in your class that will be a reference for the hotkey in your code:

    const int MYACTION_HOTKEY_ID = 1;
    
  3. Register the hotkey (in the constructor of your Windows Form for instance):

    // Modifier keys codes: Alt = 1, Ctrl = 2, Shift = 4, Win = 8
    // Compute the addition of each combination of the keys you want to be pressed
    // ALT+CTRL = 1 + 2 = 3 , CTRL+SHIFT = 2 + 4 = 6...
    RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 6, (int) Keys.F12);
    
  4. Handle the typed keys by adding the following method in your class:

    protected override void WndProc(ref Message m) {
        if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID) {
            // My hotkey has been typed
    
            // Do what you want here
            // ...
        }
        base.WndProc(ref m);
    }
    
Otiel
  • 18,404
  • 16
  • 78
  • 126
  • 2
    As an aside, I'm not a big fan of global hotkeys - I think they are potentially "dangerous." What if two applications registered the same key? It could have unexpected consequences unless handled very carefully. And even if you handle yours carefully, there's nothing saying the other application does the same. Kind of like being a great driver, but having to worry about the other drivers on the road. – Wonko the Sane Mar 14 '13 at 15:26
  • 1
    @WonkotheSane: I totally agree with you. This is why (message to @DarkenShooter) applications using global hotkeys should provide a way for the user to customize its global hotkeys (like Skype or others do). – Otiel Mar 14 '13 at 15:32
  • @WonkotheSane look at the MSDN docs for RegisterHotkey, cite : RegisterHotKey fails if the keystrokes specified for the hot key have already been registered by another hot key. Anyway I agree with Otiel, user should be able customize keys used, and another thing, F12 key is reserver for debugger – Antonio Bakula Mar 14 '13 at 15:34
  • @DarkenShooter Keep in mind your hotkey will work with this method; but if another application utilizes the same key and isn't a hotkey. `F12` is fairly common- Your application will trump the application they may be in and trying to work correctly but can't because of your `Global Hotkey`. – Greg Mar 14 '13 at 15:34
  • I don't want to use any hotkey like Alt/Ctrl/Shift/Win.I just want to use(want to capture) the key like F10 or F9 @Otiel – ImonBayazid Mar 14 '13 at 15:54
  • @AntoniaBakula - ok, I understand. However, I still feel it's dangerous to rely entirely on a global hotkey - if registration fails, you're SOL, especially if you are not careful about what you do in that situation. – Wonko the Sane Mar 14 '13 at 16:02
  • @DarkenShooter: Then simply specify `0` as the modifier key: `RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F10);`. If it does not work, this is because F9/F10 is already used by another application on your computer. – Otiel Mar 14 '13 at 16:03
  • what is "const int MYACTION_HOTKEY_ID = 1;" why do i need this?? if i just use F10,F9,F8 will it need?? – ImonBayazid Mar 14 '13 at 16:16
  • @DarkenShooter: It is a constant used to identify the hotkey in the `WndProc` method. You could not use it, and use the same integer when registering the hotkey and when identifying `m.WParam.ToInt32()`. – Otiel Mar 14 '13 at 16:22
  • @DarkenShooter: Short answer: Yes. Long answer: you could not use it, but you should. – Otiel Mar 14 '13 at 16:27
  • 1 is for what in this line?? – ImonBayazid Mar 14 '13 at 16:33
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/26177/discussion-between-otiel-and-darkenshooter) – Otiel Mar 14 '13 at 16:52
  • 2
    I'm trying to register the Hotkey in main.cs in a windows application, as I don't want it to have any forms as such, but this.Handle does not exist in this context. Any ideas how to get it otherwise? – peter.swallow May 22 '17 at 18:16
  • 2
    How it use in console app ? i dont have this.Handle – nim Feb 27 '19 at 18:00
19

In case you have problem running Otiel's solution:

  1. You need to include:

     using System.Runtime.InteropServices; //required for dll import
    
  2. Another doubt for newbies like me: "top of the class" really means top of your class like this (not namespace or constructor):

    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifers, int vlc);
    
        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    }
    
  3. You don't need to add user32.dll as reference to the project. WinForms always load this dll automatically.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
baron_bartek
  • 1,073
  • 2
  • 20
  • 39