Click here to Skip to main content
Click here to Skip to main content

A Simple C# Global Low Level Keyboard Hook

By , 30 May 2007
 
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)

About the Author

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

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralRe: MDA error garbage collected delegatememberkendolew23 Oct '09 - 5:43 
QuestionHow to use this for capturing all the keys?memberMember 475432628 Jan '09 - 9:46 
AnswerRe: How to use this for capturing all the keys?memberStormySpike13 Mar '09 - 14:41 
AnswerRe: How to use this for capturing all the keys?memberjwainer6 Aug '09 - 14:33 
GeneralRe: How to use this for capturing all the keys?memberBuggingMe22 Mar '10 - 6:54 
AnswerRe: How to use this for capturing all the keys?memberShrish Pandit25 Mar '11 - 15:51 
GeneralNot capturing after random number of key strokes !memberMember 475432611 Jan '09 - 20:38 
GeneralMy vote of 1memberMember 407286520 Dec '08 - 8:29 
GeneralMy vote of 1memberMember 407286520 Dec '08 - 7:00 
GeneralReplace keystroke with another keymemberMember 56468673 Nov '08 - 5:51 
GeneralRe: Replace keystroke with another keymemberStormySpike10 Nov '08 - 9:07 
GeneralClarion MDI child window in C#memberNino Mrdjen22 Oct '08 - 23:37 
GeneralRe: Clarion MDI child window in C#memberStormySpike10 Nov '08 - 9:12 
There is not a way that I am familiar with, Interop between Managed code and Clarion tends to be pretty hard. You may be able to create a Clarion Dll and use pinvoke to call a method in the dll to create the window, passing in the handle to the C# window should allow you to tell the Clarion window that it is a child and it can reference it's parent via the handle. Most of the time when I have to do interop between the two I'm consuming Managed code from Clarion by creating a COM visible lib in C# and then using it thru OLE in Clarion, so I don't do much in this direction.
GeneralRe: Clarion MDI child window in C#memberNino Mrdjen13 Nov '08 - 22:52 
GeneralNullReferenceException for SetWindowsHookExmemberWayne Walter19 Oct '08 - 17:34 
GeneralRe: NullReferenceException for SetWindowsHookExmemberWayne Walter19 Oct '08 - 19:20 
GeneralHooked Keys cannot be usedmembersashdude8 Aug '08 - 8:16 
GeneralRe: Hooked Keys cannot be usedmemberMichaelwh8 Aug '08 - 10:32 
QuestionHow do I do it without forms?memberdjcouture29 Jul '08 - 5:06 
AnswerRe: How do I do it without forms?memberStormySpike9 Aug '08 - 5:18 
GeneralRe: How do I do it without forms?memberdjcouture14 Aug '08 - 8:18 
QuestionHow to use HookedKeys.addrange?memberQSE15 May '08 - 9:09 
AnswerRe: How to use HookedKeys.addrange?memberStormySpike15 May '08 - 9:34 
GeneralRe: How to use HookedKeys.addrange?memberQSE15 May '08 - 11:56 
GeneralRe: How to use HookedKeys.addrange?memberBuggingMe22 Mar '10 - 7:07 
QuestionHow disabled Win KeymemberASysSolvers3 Apr '08 - 20:01 
QuestionMissing Code and Examples?memberMember 361497712 Dec '07 - 9:44 
AnswerRe: Missing Code and Examples?memberStormySpike21 Dec '07 - 2:21 
Questionkey combinationmemberjosephlawrencecarpio16 Sep '07 - 17:47 
AnswerRe: key combinationmemberUB90913 Jan '08 - 2:24 
QuestionRe: key combinationmemberDregor27 Apr '08 - 9:37 
GeneralRe: key combinationmemberMaxWalter20 Aug '08 - 11:23 
QuestionRe: key combinationmemberDiamonddrake29 Dec '08 - 17:21 
GeneralThanksmemberNasenbaaer24 Jul '07 - 6:42 
GeneralCallbackOnCollectedDelegatememberdubious_mauvo21 Jul '07 - 7:18 
QuestionRe: CallbackOnCollectedDelegatememberLenFH13 Aug '07 - 11:28 
AnswerRe: CallbackOnCollectedDelegatememberdubious_mauvo15 Aug '07 - 2:07 
GeneralRe: CallbackOnCollectedDelegatememberkirillkornyakov2 Feb '10 - 22:50 
GeneralRe: CallbackOnCollectedDelegatememberhaitham hamed housin30 Mar '10 - 7:41 
GeneralRe: CallbackOnCollectedDelegatememberjrbosch2 Jan '11 - 22:52 
GeneralRe: CallbackOnCollectedDelegatememberrafinhacsm27 Dec '11 - 1:01 
GeneralRe: CallbackOnCollectedDelegatememberdullan27 Feb '12 - 15:46 
AnswerRe: CallbackOnCollectedDelegatememberjeanlucvalestin16 Nov '08 - 1:14 
GeneralRe: CallbackOnCollectedDelegatememberjeanlucvalestin16 Nov '08 - 1:16 
GeneralRe: CallbackOnCollectedDelegatememberOzan Müyesseroğlu29 Dec '11 - 14:31 
GeneralSet hooked key by variablemember~Rob9 Jul '07 - 5:03 
AnswerRe: Set hooked key by variablememberStormySpike10 Jul '07 - 16:36 
GeneralRe: Set hooked key by variablememberlancesh3 Apr '08 - 4:55 
GeneralRe: Set hooked key by variablememberStormySpike16 Apr '08 - 5:00 
GeneralWindows Vistamembernone47 Jul '07 - 2:29 

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 30 May 2007
Article Copyright 2007 by StormySpike
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid