Click here to Skip to main content
Click here to Skip to main content
Go to top

A Simple C# Global Low Level Keyboard Hook

, 30 May 2007
Rate this:
Please Sign up or sign in to vote.
A simple description and sample of creating a global low level keyboard hook in C#
Screenshot - key_preview.jpg

Introduction

This article discusses a class that I wrote that wraps a global low level keyboard hook. The sample hooks the A and B keys, just for demonstration.

Background

I was trying to find a way for an application that I am writing to restore itself when a combination of keys was pressed. This was born from searching around for the answer.

Using the Code

First download the source, and add globalKeyboardHook.cs to your project. Then add...

using Utilities;

... to the top of the file you are going to use it in. Next add an instance of globalKeyboardHook to your class:

globalKeyboardHook gkh = new globalKeyboardHook() ;

When a globalKeyboardHook is constructed, it automatically installs the hook, so all there is left to do is add some keys for it to watch, and define some event handlers for the KeyDown and KeyUp events. I usually do this on the main form's load event handler, like this:

private void Form1_Load(object sender, EventArgs e) {
    gkh.HookedKeys.Add(Keys.A);
    gkh.HookedKeys.Add(Keys.B);
    gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
    gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
} 

void gkh_KeyUp(object sender, KeyEventArgs e) {
    lstLog.Items.Add("Up\t" + e.KeyCode.ToString());
    e.Handled = true ;
}

void gkh_KeyDown(object sender, KeyEventArgs e) {
    lstLog.Items.Add("Down\t" + e.KeyCode.ToString());
    e.Handled = true ;
} 

Here I have chosen to watch for the A and B keys, and defined handlers for the KeyUp and KeyDown events that both log to a listbox called lstLog. So whenever the user presses the A or B keys, no matter what has focus, the application will be notified. Setting e.Handled to true makes it so no other notifications for this event go out, in the sample, this effectively stops the user from typing an A or B. This can be useful in ensuring that key combinations are not also typed out when used.

You can add hooks for as many keys as you would like, just add them like above. Don't get frustrated if you add a hook for a key and it doesn't work, many of them, like Keys.Shift show up as other more specific keys, like Keys.LShiftKey or Keys.RShiftKey. Keys.Alt shows up as Keys.LMenu or Keys.RMenu, Keys.Control shows up as Keys.LControl or Keys.RControl, just to name a few.

If you would like to hook or unhook the keyboard hook at any point, just call your globalKeyboardHook's hook and unhook methods, like so:

//unhook
gkh.unhook() 
//set the hook again
gkh.hook() 

Points of Interest

The bulk of the work in this code is done in the globalKeyboardHook class, although it is a fairly simple piece of code itself. The hardest part of doing this was finding the correct parameters for SetWindowsHookEx.

[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx
    (int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

The parameters were worked out to be:

IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);

The first parameter WH_KEYBOARD_LL is just saying that we want to hook the low level keyboard events, hookProc is the callback for the event, hInstance is a handle to User32.dll, where this event is first processed (I think). The last parameter is if you want to hook a specific thread, then you would just pass a thread id instead of using the hInstance.

History

  • 5/30/07 - First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

StormySpike
Software Developer
United States United States
I currently work as a Software Engineer for a company in North Carolina, mainly working with C#.

You may also be interested in...

Comments and Discussions

 
GeneralRe: All keys Pinmemberjrbosch2-Jan-11 21:47 
GeneralMy vote of 4 Pinmemberangelamerkel28-Jun-10 10:11 
GeneralMy vote of 1 PinmemberMember 356761318-Jun-10 1:38 
QuestionKey combination like CTRL+ALT+A? Pinmemberuhcafigdc4-Jun-10 9:03 
General[My vote of 2] Sorry not perfect... Pinmemberjohannesnestler25-May-10 23:50 
GeneralRe: [My vote of 2] Sorry not perfect... PinmemberVHong99923-Sep-11 16:45 
GeneralI get an error.... Pinmembermoni9425-May-10 0:42 
GeneralRe: I get an error.... Pinmembermahboobeh mohamadi31-Jan-11 20:08 
GeneralStrange problem concernign Arrow Keys [modified] Pinmembermuff997-Apr-10 1:28 
GeneralOverride F1 PinmemberFullmetal9901229-Mar-10 8:24 
GeneralApp locks up PinmemberFullmetal9901228-Mar-10 10:41 
GeneralKeyboard cant type! PinmemberBuggingMe22-Mar-10 10:57 
GeneralRe: Keyboard cant type! PinmemberStormySpike23-Mar-10 14:10 
GeneralEXCELLENT! [modified] Pinmemberalexis410-Dec-09 9:05 
WOW! This is PERFECT!!! Short, representative, well organized and after I changed some things I have read from the posts it's WORKING! Exactly what I needed, thanks!
 
modified on Friday, January 1, 2010 10:00 AM

GeneralSystem.NullReferenceException PinmemberMariusUt1-Dec-09 8:27 
GeneralExample worked, but in my program the most bizzare error... PinmemberPhill6425-Nov-09 2:11 
GeneralRe: Example worked, but in my program the most bizzare error... PinmemberPhill6425-Nov-09 10:30 
GeneralCallback Error PinmemberVoulnet29-Oct-09 5:38 
GeneralRe: Callback Error PinmemberVoulnet29-Oct-09 6:32 
GeneralRe: Callback Error Pinmemberpatawic27-Nov-10 19:59 
GeneralRe: Callback Error Pinmemberpatawic27-Nov-10 20:02 
GeneralGreat PinmemberRavenet9-Oct-09 7:24 
GeneralAlt + Q Pinmembera.xyz.b.16-Jul-09 7:40 
GeneralStops Capturing Keys PinmemberNate Shoffner24-May-09 12:23 
GeneralRe: Stops Capturing Keys Pinmemberberni270416-Oct-09 3:27 
Questiontransfor it to wpf Pinmembersonicred2-Apr-09 1:09 
AnswerRe: transfor it to wpf PinmemberStormySpike2-Apr-09 7:55 
GeneralRe: transfor it to wpf Pinmembersonicred3-Apr-09 13:48 
GeneralRe: transfor it to wpf PinmemberStormySpike20-Apr-09 13:47 
GeneralRe: transfor it to wpf Pinmemberpanoylhs22-Sep-09 4:42 
Generalunhook does not work, and when i capture the keyboard you cant type :( Pinmembermysquad13-Mar-09 5:26 
GeneralRe: unhook does not work, and when i capture the keyboard you cant type :( PinmemberStormySpike13-Mar-09 14:39 
GeneralRe: unhook does not work, and when i capture the keyboard you cant type :( PinmemberPhill6425-Nov-09 10:38 
GeneralMDA error garbage collected delegate PinmemberAzraelKans2-Feb-09 13:26 
GeneralRe: MDA error garbage collected delegate PinmemberStormySpike13-Mar-09 14:45 
GeneralRe: MDA error garbage collected delegate Pinmemberweso18-Aug-09 15:54 
GeneralRe: MDA error garbage collected delegate PinmemberMember 25165064-Oct-09 10:31 
GeneralRe: MDA error garbage collected delegate Pinmemberavihaydar1012-Oct-09 22:21 
GeneralRe: MDA error garbage collected delegate Pinmemberkendolew23-Oct-09 5:43 
QuestionHow to use this for capturing all the keys? PinmemberMember 475432628-Jan-09 9:46 
AnswerRe: How to use this for capturing all the keys? PinmemberStormySpike13-Mar-09 14:41 
AnswerRe: How to use this for capturing all the keys? Pinmemberjwainer6-Aug-09 14:33 
GeneralRe: How to use this for capturing all the keys? PinmemberBuggingMe22-Mar-10 6:54 
AnswerRe: How to use this for capturing all the keys? PinmemberShrish Pandit25-Mar-11 15:51 
GeneralNot capturing after random number of key strokes ! PinmemberMember 475432611-Jan-09 20:38 
GeneralMy vote of 1 PinmemberMember 407286520-Dec-08 8:29 
GeneralMy vote of 1 PinmemberMember 407286520-Dec-08 7:00 
GeneralReplace keystroke with another key PinmemberMember 56468673-Nov-08 5:51 
GeneralRe: Replace keystroke with another key PinmemberStormySpike10-Nov-08 9:07 
GeneralClarion MDI child window in C# PinmemberNino Mrdjen22-Oct-08 23:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 30 May 2007
Article Copyright 2007 by StormySpike
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid