Click here to Skip to main content
13,249,174 members (34,086 online)
Click here to Skip to main content
Add your own
alternative version

Stats

265.9K views
8.7K downloads
221 bookmarked
Posted 3 Aug 2007

Global Windows Hooks

, 24 Sep 2010
Rate this:
Please Sign up or sign in to vote.
A single component that contains various Windows hooks

Introduction

The WindowsHookLib is a single library to hook the mouse, keyboard and the clipboard system wide. WindowsHookLib library has been rewritten in C# and therefore it uses Common Language Runtime (CLR). This means that the library can be referenced from various projects in .NET. The mouse and keyboard hooks are low level so you can use the Handled property of the MouseEventArgs or the KeyboardEventArgs to prevent the windows messages being passed to the other applications. Note you need to use the DLL file, not the classes in your projects; otherwise they might not work correctly.

  • Clipboard hook
  • Keyboard hook
  • Mouse hook

This component differs from what I have seen in other similar articles, by providing two more things:

  1. Preventing a message to be passed to other windows
  2. Raising the MouseClick and MouseDoubleClick events (I have never seen implementation of this in other low level hooks!)

Mouse Hook

The MouseHook class of the 'WindowsHookLib' library is designed to hook the mouse globally and raise some useful events. Since this hook is low level and low level mouse hooks don't get the MouseClick and MouseDoubleClick messages, it simulates these events. In order to use these events, the class object variable should be declared with the WithEvents keyword.

The MouseDown, MouseUp, MouseWheel, and MouseMove event handlers have a WindowsHookLib.MouseEventArgs class object which provides all the relevant information about the mouse as does the System.Windows.Forms.MouseEventArgs, and two additional properties, Handled and Control. You can set the Handled property to True to prevent the message from being passed to the other windows. The Control property provides the handle of the control under the mouse pointer. If you decide to set the Handled property in the MouseUp event, then it is recommended to set it in the MouseDown event as well for application performance. Conversely, if you decide to set the Handled property in the MouseDown event, then it is recommended to set it in the MouseUp event.

Note: If you set the Handled property in the mentioned events unconditionally, then you might not be able to use the mouse. To condition (block the mouse message to be passed to other windows or controls), you should compare the Control property's value against allowed control handle(s). If the allowed controls' handle list doesn't contain the Control property value, then you can set the Handled property to True; otherwise, don't set it. You can check the demo project's examples to see how you can condition the mouse handled process.

Note: Before you exit your application, you must call the hook object's Dispose method to uninstall the hook and free the class variables.

Keyboard Hook

The KeyboardHook class of the 'WindowsHookLib' library can be used to hook the keyboard globally. The class provides three events whose KeyDown and KeyUp event handlers contain a WindowsHookLib.KeyEventArgs object that has all the relevant information about the key as the System.Windows.Forms.KeyEventArgs. As with the mouse hook, you can set the Handled property to True in the KeyDown and KeyUp event handlers to prevent the message from being passed to other windows.

Clipboard Hook

The ClipboardHook class of the 'WindowsHookLib' library can be used to hook a window to the clipboard chain. The class provides two events, ClipbordChanged and StateChanged. The ClipboardChanged event handler contains a WindowsHookLib.ClipboardEventArgs object that has all the relevant information about the event.

Using the Code

Note: You need to use the DLL file by referencing it in your project, not the classes; otherwise, they might not work correctly. If you need the method descriptions, then you need to copy the 'WindowsHookLib.xml' file into your project folder.

Imports WindowsHookLib

'Class level declarations
Dim WithEvents kHook As New KeyboardHook
Dim WithEvents mHook As New MouseHook
Dim WithEvents cHook As New ClipboardHook

'Allowed control handle list
Dim alowedList As New List(Of IntPtr)

Try
    'Install the hooks
    kHook.InstallHook()
    mHook.InstallHook()
    cHook.InstallHook(Me) 'takes a window as its parameter.
Catch ex As Exception
    Console.WriteLine(ex.Message)
End Try

Try
    'Remove the hooks
    kHook.RemoveHook()
    mHook.RemoveHook()
    cHook.RemoveHook()
Catch ex As Exception
    Console.WriteLine(ex.Message)
End Try

Private Sub kHook_KeyDown( _
  ByVal sender As Object, _
  ByVal e As WindowsHookLib.KeyEventArgs) Handles kHook.KeyDown
    'Block Alt+PrintScreen key combination
    e.Handled = (e.Modifiers = Keys.Alt AndAlso _
                 e.KeyCode = Keys.PrintScreen)
End Sub

Private Sub mHook_MouseDown( _
  ByVal sender As Object, _
  ByVal e As WindowsHookLib.MouseEventArgs) Handles mHook.MouseDown
    'Set the Handled property for the mouse down event
    'to block the mouse down message for the 
    'controls that are not in the alowedList.
    e.Handled = Not Me.alowedList.Contains(Ctype(sender,IntPtr))
    'Do some other things here
    '...
    '...
End Sub

Private Sub mHook_MouseUp( _
  ByVal sender As Object, _
  ByVal e As WindowsHookLib.MouseEventArgs) Handles mHook.MouseUp
    'Set the Handled property for the mouse up event
    'to block the mouse up message for the 
    'controls that are not in the alowedList.
    e.Handled = Not Me.alowedList.Contains(Ctype(sender,IntPtr))
    'Do some other things here
    '...
    '...
End Sub

Private Sub cHook_ClipboardChanged( _
  ByVal sender As Object, _
  ByVal e As WindowsHookLib.ClipboardEventArgs) _
  Handles cHook.ClipboardChanged
    'The clipboard content is changed, do something about it.
    '...
    '...
End Sub

For more examples, check out the source code and demo files.

Background

In the core of this component lies the API methods. All hooks use some API methods to hook and monitor for Windows messages. The following list is the API methods that have been used:

  • SetWindowsHookEx
  • UnhookWindowsHookEx
  • CallNextHookEx
  • WindowFromPoint
  • SendInput
  • SetClipboardViewer
  • ChangeClipboardChain

Points of Interest

I learned many things from this project like how to make a DLL file component that can be used in various projects (VB.NET, C#, C++, J#) in the .NET environment. Also, how to apply attributes to classes or methods that will make a component professional.

Since low level mouse hooks don't get the MouseClick and MouseDoubleClick event messages (which I believe are generated by a window that gets the MouseDown and MouseUp messages), I tried to simulate these events such that they are generated in the same pattern as the Windows MouseClick and MouseDoubleClick events.

WindowsHookLib Information

  • Author: Arman Ghazanchyan
  • Current assembly version: 1.1.1.2
  • Current file version: 1.0.0.6
  • WindowsHookLib webpage

History

  • Updated assembly version 1.1.0.1. This update addresses all hooks.
    • The WindowsHookLib assembly is signed.
    • A clipboard hook is added - New
  • Updated assembly version 1.1.0.2. This update addresses the Keyboard hook.
    • Small change in the KeyEventArgs class
  • Updated assembly version 1.1.0.5. This update addresses to all hooks.
    • Small changes and fixes
  • Updated assembly version 1.1.1.0. This update addresses to all hooks.
    • Some changes and fixes
  • Updated assembly version 1.1.1.2. This update addresses to all hooks, the update is highly recommended.
    • The library is rewritten in C# language.
    • There are many fixes and optimizations to the library.
    • Clipboard Hook bug fix. The hook was not implementing correctly in the previous versions which would lead to breaking up the windows clipboard chain. This version fixes the problem.
    • This version of the library is smaller in size than the previous versions.

License

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

Share

About the Author

Arman Ghazanchyan
Software Developer (Senior) ZipEdTech
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralRe: Running WindowsHookLib.dll from a service. Pin
The_Mega_ZZTer14-Mar-08 19:10
memberThe_Mega_ZZTer14-Mar-08 19:10 
GeneralRe: Running WindowsHookLib.dll from a service. Pin
Farquar de St.John1-Apr-08 23:28
memberFarquar de St.John1-Apr-08 23:28 
QuestionStrange problem Pin
Gooberstain23-Dec-07 15:32
memberGooberstain23-Dec-07 15:32 
GeneralRe: Strange problem Pin
VBDT10-Jan-08 20:48
memberVBDT10-Jan-08 20:48 
GeneralBrilliant! Pin
MagicPantsMan30-Oct-07 18:59
memberMagicPantsMan30-Oct-07 18:59 
QuestionIs this possible?File Path retrival Pin
mohandilli12-Oct-07 19:39
membermohandilli12-Oct-07 19:39 
GeneralRe: Is this possible?File Path retrival Pin
The_Mega_ZZTer14-Mar-08 19:16
memberThe_Mega_ZZTer14-Mar-08 19:16 
QuestionTrying the code out Pin
Per Sderberg1-Oct-07 4:10
memberPer Sderberg1-Oct-07 4:10 
Hi,
This will be a superb feature to have, so I wrote the following test programme:
-----------------------------------------
Public Class Form1
'Class level declarations
Friend WithEvents gkh As New LLKeyboardHook

Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
Try
'Remove the keyboard hook
gkh.RemoveHook()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Me.gkh.Dispose()
End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Console.WriteLine("Keyboard Hook " & Me.gkh.GetState.ToString)
End Sub

Private Sub gkh_StateChanged(ByVal sender As Object, ByVal e As WindowsHookLib.StateChangedEventArgs) Handles gkh.StateChanged
'Print the keyboard hook state in the KeyboardGroupBox name

If e.State = WindowsHookLib.HookState.Uninstalled Then
'Clear the Handle Keyboard checkbox

End If
End Sub


Private Sub gkh_KeyDown( _
ByVal sender As Object, _
ByVal e As WindowsHookLib.KeyEventArgs) Handles gkh.KeyDown

e.Handled = (e.Modifiers = Keys.LWin Or e.Modifiers = Keys.RWin)
e.Handled = (e.Modifiers = Keys.Alt AndAlso e.KeyCode = Keys.Escape)
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
'Install the keyboard hook
gkh.InstallHook()

Catch ex As Exception
Console.WriteLine("Message:")
Console.WriteLine(ex.Message)
Console.WriteLine("Source:")
Console.WriteLine(ex.Source)
Console.WriteLine("StackTrace:")
Console.WriteLine(ex.StackTrace)

MessageBox.Show("Failed to install the keyboard hook!." _
& Environment.NewLine & ex.Message, "Keyboard Hook Error!", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Console.WriteLine(ex.Message)
End Try
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Try
'Remove the mouse hook
gkh.RemoveHook()
Catch ex As Exception
Console.WriteLine("Message:")
Console.WriteLine(ex.Message)
Console.WriteLine("Source:")
Console.WriteLine(ex.Source)
Console.WriteLine("StackTrace:")
Console.WriteLine(ex.StackTrace)
End Try

End Sub
End Class
----------------------------------------------
And added the source files and library according to the demo as enclosed. The demo I got to work perfectly.
My aim is to prevent the windows logo button to be used and I wish to block LWIN, RWIN and ctrl-esc
However when running the above programme and hitting the button1 gives an system.componentmodel.win32exception.
Something went wrong in the environment. I run under XP pro.
Any idea on what can be wrong would be greatly appriciated.

Per in Sweden
AnswerRe: Trying the code out Pin
VBDT1-Oct-07 7:50
memberVBDT1-Oct-07 7:50 
AnswerRe: Trying the code out Pin
Per Sderberg1-Oct-07 22:56
memberPer Sderberg1-Oct-07 22:56 
GeneralRe: Trying the code out Pin
VBDT2-Oct-07 7:39
memberVBDT2-Oct-07 7:39 
GeneralRe: Trying the code out Pin
Per Sderberg2-Oct-07 22:26
memberPer Sderberg2-Oct-07 22:26 
GeneralRe: Trying the code out [modified] Pin
VBDT3-Oct-07 1:00
memberVBDT3-Oct-07 1:00 
GeneralRe: Trying the code out Pin
dasprdav7-Apr-08 12:07
memberdasprdav7-Apr-08 12:07 
GeneralRe: Trying the code out Pin
VBDT7-Apr-08 14:06
memberVBDT7-Apr-08 14:06 
QuestionAltering key vales Pin
companyit20-Aug-07 22:45
membercompanyit20-Aug-07 22:45 
AnswerRe: Altering key vales [modified] Pin
VBDT5-Oct-07 18:48
memberVBDT5-Oct-07 18:48 
GeneralWindowsHookLib Source Files Pin
shabyb17-Aug-07 11:00
membershabyb17-Aug-07 11:00 
GeneralRe: WindowsHookLib Source Files Pin
shabyb18-Aug-07 5:17
membershabyb18-Aug-07 5:17 
GeneralExactly what I needed! Pin
StefanTheProgrammer14-Aug-07 23:29
memberStefanTheProgrammer14-Aug-07 23:29 
GeneralPerfect... Pin
Vasssek14-Aug-07 22:07
memberVasssek14-Aug-07 22:07 
GeneralRe: Perfect... [modified] Pin
VBDT15-Aug-07 10:39
memberVBDT15-Aug-07 10:39 
GeneralC # equivalent Pin
Niels Penneman6-Aug-07 21:01
memberNiels Penneman6-Aug-07 21:01 
QuestionVista? Pin
joemerchant6-Aug-07 10:56
memberjoemerchant6-Aug-07 10:56 
AnswerRe: Vista? Pin
VBDT6-Aug-07 12:35
memberVBDT6-Aug-07 12:35 

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

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

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 24 Sep 2010
Article Copyright 2007 by Arman Ghazanchyan
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid