Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations

By Hook or by Crook

While trying to implement custom shortcut keys in Outlook, I came across an old column by Dino Esposito on implementing custom Windows hooks in .NET. At first I wanted to use it as reference and inspiration only, and only when I finished did I notice I simply rewrote, from scratch, most of the code he offers in his article. The main difference is that he supplies a base, generic WindowsHook class and a derived CBTHook class to handle window opening/closing/etc events, while I implemented my generic parent class and a derived KeyboardHook class for keyboard events. This is implemented as thread-local hooks on the currently running process, rather than expensive global system hooks.

The basic premise is simple - keep all the Win32 P/Invoke code well hid inside the private implementation, and have the WindowsHook class simply raise an event when the hook function is invoked, passing the hook function paraemeters as event args to the HookInvoked event.

However, since the hook parameters are different for each kind of hook, the KeyboardHook class also raises a different event, KeyPressed, that parses the hook parameters and gives more intelligble and specific meaning to the parameters - which key was pressed, as well as the state of the Control, Alt and Shift keys.

Additionally, the KeyboardHook class allows setting filters, so that the event will only be raised for specific keystrokes. This allows us to get only the keystrokes we want (say, our chosen keyboard shortcut keys).

Code such as this sample will raise the KeyPressed event whenever the user presses Ctrl-Shift-F, or Alt-F6:

KeyboardHook hook;
private void Form1_Load(object sender, System.EventArgs e)
{
  hook = new KeyboardHook();
  hook.AddFilter(Keys.F, true, false, true);
  hook.AddFilter(Keys.F6, false, true, false);
  hook.KeyPressed +=new KeyboardHookEventHandler(hook_KeyPressed);
  hook.Install();
}

KeyboardHook hook;
private void Form1_Load(object sender, System.EventArgs e)
{
  hook = new KeyboardHook();
  hook.AddFilter(Keys.F, true, false, true);
  hook.AddFilter(Keys.F6, false, true, false);
  hook.KeyPressed +=new KeyboardHookEventHandler(hook_KeyPressed);
  hook.Install();
}

private void hook_KeyPressed(object sender, KeyboardHookEventArgs e)
{
  this.label1.Text = "Found " + e.KeyStroke.ToString();
}

void hook_KeyPressed(object sender, KeyboardHookEventArgs e)
{
  this.label1.Text = "Found " + e.KeyStroke.ToString();
}

Full code for this class can be found in the attached ZIP file.

And thanks, again, to Dino Esposito for the inspiration, not to mention blatant plagiarism. :)

Attachment: HookLibrary.zip
Posted: Oct 06 2005, 02:42 PM by AvnerK | with 8 comment(s)
Filed under: ,

Comments

Bassam said:

Sorry...where is the class..??

# October 14, 2006 3:35 PM

Dan said:

# October 11, 2007 1:27 PM

Steave said:

Great story as for me. It would be great to read something more concerning this topic.

# October 25, 2009 11:43 PM

Jim said:

Among other things, the best way to protect yourself from spy devices and irritative calls is to use <a href="www.jammer-store.com/.../a>. Jam mobiles around you.

# November 1, 2009 1:08 PM

High class London escorts said:

It was certainly interesting for me to read this post. Thanks for it. I like such topics and everything connected to them. I would like to read a bit more on that blog soon.

# November 22, 2009 9:26 PM

BeautifulMonster said:

Don't stop posting such themes. I love to read stories like this. Just add some pics :)

# January 23, 2010 4:06 PM

Jimmy said:

Any example of WindowHook? I want to minimize Outlook on close button click also.

# June 3, 2010 6:14 AM

singapore escorts said:

I always charge out of reading eminence articles by means of an individual who is simply up to snuff on their chosen subject. I’ll be watching this thread with much interest. Keep up the great produce, dream of you next time

# January 11, 2011 3:53 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)