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

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

VBDT
Software Developer (Senior) ZipEdTech
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberDwayne J. Baldwin8-Feb-11 14:05 
GeneralNot capturing exect Character Pinmembereg_Anubhava30-Jan-11 21:06 
GeneralRe: Not capturing exect Character PinmemberVBDT31-Jan-11 16:54 
GeneralRe: Not capturing exect Character Pinmembereg_Anubhava4-Feb-11 23:48 
QuestionIt is not working for me PinmemberMatchlighter15-Dec-10 15:42 
AnswerRe: It is not working for me PinmemberVBDT16-Dec-10 18:53 
GeneralRe: It is not working for me PinmemberMatchlighter17-Dec-10 15:36 
GeneralRe: It is not working for me PinmemberVBDT17-Dec-10 19:32 
GeneralRe: It is not working for me PinmemberMatchlighter17-Dec-10 20:03 
QuestionEvents Stop Firing in Win7 PinmemberJon Gross4-Nov-10 4:25 
AnswerRe: Events Stop Firing in Win7 PinmemberVBDT4-Nov-10 17:49 
GeneralRe: Events Stop Firing in Win7 PinmemberJon Gross5-Nov-10 4:05 
GeneralRe: Events Stop Firing in Win7 PinmemberJon Gross5-Nov-10 7:03 
GeneralRe: Events Stop Firing in Win7 PinmemberVBDT6-Nov-10 9:49 
GeneralRe: Events Stop Firing in Win7 PinmemberVBDT6-Nov-10 9:42 
AnswerRe: Events Stop Firing in Win7 PinmemberDuddits11-May-11 8:03 
GeneralAn additional question Pinmemberambaraba11114-Oct-10 22:43 
GeneralRe: An additional question [modified] PinmemberVBDT16-Oct-10 16:21 
GeneralRe: An additional question Pinmemberambaraba11118-Oct-10 22:33 
GeneralHooking other events Pinmemberambaraba1111-Oct-10 1:23 
GeneralRe: Hooking other events PinmemberVBDT3-Oct-10 15:35 
GeneralRe: Hooking other events [modified] Pinmemberambaraba1116-Oct-10 5:20 
GeneralKeyhook dll PinmemberJefry boycot30-Sep-10 19:59 
GeneralRe: Keyhook dll PinmemberVBDT3-Oct-10 15:24 
GeneralMy vote of 5 PinmemberJamal Alqabandi28-Sep-10 1:32 
GeneralRe: My vote of 5 PinmemberVBDT3-Oct-10 15:36 
QuestionHook only in my application Pinmemberluka8227-Sep-10 20:41 
AnswerRe: Hook only in my application PinmemberVBDT27-Sep-10 21:37 
GeneralRe: Hook only in my application Pinmemberluka8227-Sep-10 23:59 
GeneralRe: Hook only in my application PinmemberVBDT3-Oct-10 15:19 
GeneralRe: Hook only in my application Pinmemberluka823-Oct-10 22:54 
GeneralRe: Hook only in my application [modified] PinmemberVBDT4-Oct-10 7:22 
GeneralSeems really cool :) PinmemberAnt210024-Sep-10 8:46 
GeneralNot working with framework 4 Pinmemberarchitecton23-Jun-10 9:18 
GeneralRe: Not working with framework 4 Pinmemberjake07230-Sep-10 4:33 
GeneralRe: Not working with framework 4 Pinmemberjake07230-Sep-10 4:49 
GeneralRe: Not working with framework 4 PinmemberVBDT17-Oct-10 10:39 
GeneralRe: Not working with framework 4 Pinmemberjake07219-Oct-10 3:03 
GeneralRe: Not working with framework 4 PinmemberVBDT19-Oct-10 6:09 
GeneralRe: Not working with framework 4 [modified] PinmemberVBDT3-Oct-10 15:11 
GeneralRe: Not working with framework 4 PinmemberVBDT17-Oct-10 10:43 
GeneralReally great stuff :-) PinmemberSrikanth. Vemulapalli5-Mar-10 22:59 
GeneralRe: Really great stuff :-) PinmemberVBDT6-Mar-10 6:36 
QuestionHow do you make it stop? PinmemberSkymir25-Jan-10 2:56 
QuestionKey problem PinmemberMiutubevids23-Dec-09 18:42 
Generaltouch lcd panel of mobile phone Pinmembercheertek11-Oct-09 15:35 
QuestionThreading question Pinmemberjmurmel7-Sep-09 12:18 
Dear Arman,
 
Thanks for your great software!
 
I have a question:
 
I am writing a program that does some heavy GUI stuff.
As the result, if MouseHook is installed, the mouse gets stuck at the times when my main thread is busy working on GUI.
 
I tried installing the MouseHook on a separate thread, but that did not really work.
 
Here's my code:
 
Imports System.Threading
Imports System.ComponentModel
 
Public Class MouseHooker
    Dim _mouseHook As MouseHook
    Private _worker As BackgroundWorker
 
    Public Sub New()
    End Sub
 
    Public Sub DoHook()
        _worker = New BackgroundWorker()
        AddHandler _worker.DoWork, AddressOf worker_DoWork
 
        _worker.RunWorkerAsync()
    End Sub
 
    Private Sub _mouseHook_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Windows.Forms.MessageBox.Show("Mouse Clicked")
    End Sub
 
    Private Sub _mouseHook_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
        Windows.Forms.MessageBox.Show("Mouse Moved")
    End Sub
 
    Private Sub worker_DoWork(ByVal sender As Object, ByVal param As System.ComponentModel.DoWorkEventArgs)
        _mouseHook = New MouseHook()
        AddHandler _mouseHook.MouseMove, AddressOf _mouseHook_MouseMove
        AddHandler _mouseHook.MouseClick, AddressOf _mouseHook_MouseClick
        _mouseHook.InstallHook()
 
        Thread.Sleep(Timeout.Infinite)
        
    End Sub
End Class
 
I will greatly appreciate your guidance.
 
Kind regards,
 
jmurmel
QuestionPassing Events [modified] PinmemberRennie Johnson9-Aug-09 6:01 
AnswerRe: Passing Events PinmemberVBDT9-Aug-09 6:37 
GeneralRe: Passing Events PinmemberRennie Johnson9-Aug-09 7:21 

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.140827.1 | Last Updated 24 Sep 2010
Article Copyright 2007 by VBDT
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid