# VBForums CodeBank > CodeBank - Visual Basic .NET >  Global hooks

## VBDT

Some times I update the component and post the updated date and the assembly version number so it is recommended to check it once a while.
I created this project as a single utility to hook the mouse, keyboard and the clipboard system wide. It is a library file 'WindowsHookLib' dll that can be referenced into various projects. The mouse and keyboard hooks are low level so you can use the 'Handled' property of the 'WindowsHookLib.MouseEventArgs' or the 'WindowsHookLib.KeyEventArgs' to prevent the windows messages be 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.

*Note*, if you use any of these hooks than you *MUST* call their dispose methods when the application exits. The method will remove the hook and free the memory that is used by the hook component.

*MOUSE HOOK*

The 'LLMouseHook' class from 'WindowsHookLib' is designed to hook the mouse globally and fire some useful events. Since this hook is low level and low level mouse hook doesn't get MouseClick and MouseDoubleClick messages it simulates these events.
I provided the 'Handled' property to 'MouseDown', 'MouseUp', 'MouseWheel' and 'MouseMove' event handlers. 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 the application performance.

*Warning*! If you set the 'Handled' property in the mentioned events unconditionally than you might not be able to use the mouse. You can check the 'WindowsHookLib Demo Project' examples to see how you can condition the mouse handled process.

*Class methods:*
InstallHook – Installs the mouse hook globally (has no parameters).RemoveHook – Removes the mouse hook (has no parameters).Dispose – Unhooks the mouse (if it is hooked) and frees the memory used by the component (has no parameters).SynthesizeMouseDown - Synthesizes a mouse down event system wide.SynthesizeMouseUp - Synthesizes a mouse up event system wide.SynthesizeMouseWheel - Synthesizes a mouse wheel event system wide.SynthesizeMouseMove - Synthesizes a mouse move event system wide.
*Class properties:*
State – Gets the hook state.
*Class events:*
StateChanged – Fires the event if the mouse hook is installed/uninstalled.MouseDown – Fires the event if the mouse button is down.MouseMove – Fires the event if the mouse is moved.MouseUp – Fires the event if the mouse button is up.MouseWheel – Fires the event if the mouse vertical/horizontal wheels are rotated.MouseClick – Fires the event if the mouse is clicked.MouseDoubleClick – Fires the event if the mouse is double-clicked.

*KEYBOARD HOOK*

The 'LLKeyboardHook' class from 'WindowsHookLib' can be use to hook the keyboard globally.

*Class methods:*
InstallHook – Installs the keyboard hook globally (has no parameters).RemoveHook – Removes the keyboard hook (has no parameters).Dispose – Unhooks the keyboard (if it is hooked) and frees the memory used by the component (has no parameters).
*Class properties:*
State – Gets the hook state.AltKeyDown – Gets a Boolean value indicating if the ALT key is down.CtrlKeyDown – Gets a Boolean value indicating if the CTRL key is down.ShiftKeyDown– Gets a Boolean value indicating if the SHIFT key is down.
*Class events:*
StateChanged – Fires the event if the keyboard hook is installed/uninstalled.KeyDown – Fires the event if a keyboard button is down.KeyUp – Fires the event if the keyboard button is up.

*CLIPBOARD HOOK*

The 'ClipboardHook' class from 'WindowsHookLib' can be use to add a window to the clipboard chain and fire clipboard changed event.

*Class methods:*
InstallHook – Adds a window to the clipboard chain (has no parameters).RemoveHook – Removes the  window from the clipboard chain (has no parameters).Dispose – Removes the window from the clipboard chain and frees the memory used by the component (has no parameters).
*Class properties:*
State – Gets the hook state.HWnd – Gets the hooked window handle.
*Class events:*
StateChanged – Fires the event if the clipboard hook is installed/uninstalled.ClipboardChanged– Fires the event when the clipboard contents is changed (redrawn).

The code examples are in the demo project with comments. You can run the project and test the hooks before you use them. If you need the methods' discriptions, than you need to copy the 'WindowsHookLib.xml' file into your project folder too.
By the way, the mouse hook and the clipboard hook are used in the Easy Screen Shot tool app. You can see the main use of mouse hook when you capture an object (window, control, windows shortcut menus etc.) images. The clipboard hook is used to enable the clipboard captur button.

*Update History:*

Assembly Version 1.1.0.7
File Version 1.0.0.1
Some internal changes.The namespace _WindowsHookLib_ is changed to _WindowsHook_.
Assembly Version 1.1.1.0
File Version 1.0.0.4
Minor internal improvements.
Download the latest version *here*

----------


## Traps

> This class is designed to hook the mouse globally and fire some useful events. The class uses Api functions to hook the mouse. Since this hook is low level and low level mouse hook doesnt get MouseClick and MouseDoubleClick messages the class simulates these events.



Why do you say low level mouse hook doesnt capture click events?  Sure it does.  Not only single and double clicks, but also the delta value for scroll wheel.  Your class to simulate this is not needed.

----------


## VBDT

> Why do you say low level mouse hook doesnt capture click events?  Sure it does.  Not only single and double clicks, but also the delta value for scroll wheel.  Your class to simulate this is not needed.


Because it doesnt!
This is the only windows massages that the window gets when it hooked low level



> wParam
> [in] Specifies the identifier of the mouse message. This parameter can be one of the following messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, or WM_RBUTTONUP.


MSDN

----------


## Traps

> Because it doesnt!
> This is the only windows massages that the window gets when it hooked low level
> MSDN



Just debugged my hook program and your right!!!  Looks like I could remove those from my select case statement for checking mouse messages.  Cant believe I didnt notice that when I wrote my program.


Sorry.  Maybe a MOD can delete our posts. Dont mean to junk up your thread.   :wave:

----------


## svefro

How can i see the difference if im rolling up or down with my mouse?

the e.Delta is the same when i roll up as down. (always 424)

----------


## VBDT

The Delta value is the value that the window gets by the WM_MOUSEWHEEL message. The value should be the same except that if you roll up it is positive and when you roll down it is negative.
The value should be 120 or -120 roll up and down respectivly. Now, if you want to get the total rolled value you can have a class level variable and add the delta value to it in the MouseWheel event. Here is an example:

vb Code:
Imports WindowsHookLib
 Public Class Form1
     Dim WithEvents gmh As New LLMouseHook
    Dim delta As Integer
     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'Dispose the object (it will uninstall the hook first)
        Me.gmh.Dispose()
    End Sub
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            'Install the mouse hook
            Me.gmh.InstallHook()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
     Private Sub gmh_MouseWheel(ByVal sender As Object, ByVal e As WindowsHookLib.MouseEventArgs) Handles gmh.MouseWheel
        'Add the delta value to the variable
        Me.delta += e.Delta
        Console.WriteLine(Me.delta)
    End Sub
End Class

----------


## slk486

Thanks for the code, it works great, except that it seems to return the same sender handle regardless of what is actually clicked.

Any ideas?

----------


## VBDT

> Thanks for the code, it works great, except that it seems to return the same sender handle regardless of what is actually clicked.
> 
> Any ideas?


What kind of control is it? My guess is that it is a User Control that has some controls in it. In this case the sender has the handle of the User Control not the controls that it includes.

----------


## slk486

Thanks for your quick reply  :Smilie: 

The app uses normal VB forms and a context menu opened from a notfyicon in the tray.

Even when i Click elsewhere on the desktop, the sender handle is the same..

The main form is hidden and only the tray icon is visible. when the user clicks the tray icon a context menu appears and from the context menu the user can open a form. It doesn't matter if I click the menu, the icon, the form or in any other (other apps) window on the desktop.

----------


## VBDT

Really, that sounds weird. In the class I use the WindowFromPoint Api function to get the handle of the control. If it gives the same handle for everything you click then there must be some problem with your project or with Visual Studio I am not sure.
Have you tried the demo I have posted? Does it work as it spouse to?
Also I would suggest you to install the Screen Shot application in my signature and try to capture objects for a test. The app uses this class to capture controls and when you move the mouse, a red rectangle is being drawn around the controls which were passable to do with the Api function I mentioned above.

----------


## slk486

OK...

The demo gave me the window full of buttons that I could navigate with the keyboard and find the correct 2, to unlock the mouse (no mouse movement at first, then no mouse clicking) - i believe that is the intended functionality?

The Screen Shot app was rather weird. First time i couldn't click anything, then all of a sudden a red border appeared around a window and I could capture window images but not click anything in the Screen shot menu (i can click the images and they appear pressed, but nothing happens). Second time I could capture the windows I clicked on - no red border however, and I couldn't click anything in the Screen shot menu - not even cancel capture.

Had to kill the process.

Could this have anything to do with the fact that I'm using Windows XP x64 or dual monitors?

----------


## VBDT

> OK...
> 
> The demo gave me the window full of buttons that I could navigate with the keyboard and find the correct 2, to unlock the mouse (no mouse movement at first, then no mouse clicking) - i believe that is the intended functionality?
> 
> The Screen Shot app was rather weird. First time i couldn't click anything, then all of a sudden a red border appeared around a window and I could capture window images but not click anything in the Screen shot menu (i can click the images and they appear pressed, but nothing happens). Second time I could capture the windows I clicked on - no red border however, and I couldn't click anything in the Screen shot menu - not even cancel capture.
> 
> Had to kill the process.
> 
> Could this have anything to do with the fact that I'm using Windows XP x64 or dual monitors?


In the demo at least you should be able to move the mouse inside the form and be able to click some not all the buttons. If you cant then there has to be some problems with the fact that you mentioned. I am using xp too so that shouldn't be problem but i am not sure about x64 and dual monitors!

The Screen Shot app works great in my computer and the others I tested. The problem you are having is effecting to Screen Shot too.

One more suggestion, in the event that the sender is giving the same handle fore windows and controls use the GetLastApiError function of the GlobalMouseHook class to retrieve the last error accrued in the Api dlls and see what it says if there is one.

One more thing! I posted the dll file 'WindowsHook' that is basicly the same code except the dll gets the module handl by reflection instead of Api wich in your case it may have giving a wrong one. Also the MS documentation states that it must be in the dll.

----------


## meraydin

Hello VBDT

I have a question regarding to your last post, saying "_One more thing! I posted the dll file 'WindowsHook' that is basicly the same code except the dll gets the module handl by reflection instead of Api wich in your case it may have giving a wrong one. Also the MS documentation states that it must be in the dll."_;

Is this the reason I cannot produce a single assembly (without WindowsHookLib.dll)? I've copy/pasted the files in WindowsHookLib to Test folder but it throws an exception at ghk.InstallHook. 

Or do I miss something else?

----------


## VBDT

> Hello VBDT
> 
> I have a question regarding to your last post, saying "_One more thing! I posted the dll file 'WindowsHook' that is basicly the same code except the dll gets the module handl by reflection instead of Api wich in your case it may have giving a wrong one. Also the MS documentation states that it must be in the dll."_;
> 
> Is this the reason I cannot produce a single assembly (without WindowsHookLib.dll)? I've copy/pasted the files in WindowsHookLib to Test folder but it throws an exception at ghk.InstallHook. 
> 
> Or do I miss something else?


I mentioned it in the introduction in #1 post 


> "Note you need to use the dll not the classes in your projects; otherwise they might not work correctly."


All you need to do is to copy the two files (WindowsHookLib.dll & WindowsHookLib.xml) in the "WindowsHookLib.zip" in to your project folder and add reference to the "WindowsHookLib.dll" file from your project and add "Imports WindowsHookLib" on top of your class or form.

----------


## Half

How would one get the raw wparam and lparam? I need to 'copy' a wm_mousewheel in order to send it elsewhere but reconstructing the parameters from e.X, e.Y, e.Button etc seems kind of tricky.

----------


## 5applerush

Hi VBDT,
I was in need of a keyboard hook procedure, and this class is superior to anything I would have been able to come up with myself.  So firstly, thanks for posting it.

If I many ask a few questions:

1.) In this class, you use the WH_KEYBOARD_LL hook for the keyboard.  This hook is available only as a global hook, whereas the WH_KEYBOARD hook is available as a thread specific, or global - so at first glance, it sounds like the latter is a more versatile version. The help docs don't offer any information (at least initially) as to the difference.  Are there any advantages to the _LL version?

2.) The docs say to use global hooks only when necessary.  Could two thread-specific hooks be used in place of one global hook if an app involves two separate processes? (mine is a cad-like app with separate procs for menu and window).

Thanks very much,
Danny

----------


## VBDT

Hi 5applerush,
1) I would say the only advantage I see is that the LL hook gets a keyboard message before any window, where else none LL hook gets the message when the window got the message and will process it. Honestly, I dont see any reason for creating thread specific hook since with framework 2 maybe in earlier versions you can set the forms KeyPreview property which will fire when a key is down or up regardless what control has the focus, which is similar to the thread specific hook. But there is no way to get the keyboard messages regardless what app has the focus unless using LL keyboard hook.

2) Yes, they could, you can do it the way I described above or you can write thread specific keyboard hook but then there is no good reason for it.

VBDT  :Smilie:

----------


## 5applerush

Ahhh, I think I understand.  At first I couldn't quite see the difference after reading over the descriptions of each on MSDN.  After your post I read them again, and noticed that the callback procedure for LL returns much more information in wParam and lParam - namely the KBDLLHOOKSTRUCT.  Is this accurate?

I also have a noob question:  The amount of code in your module is much more extensive than any other examples of hooks that I've found.  Everything seems to be set up quite formally.  Is this the type of code that one writes when they wish to "productionize" their code?  I've always wondered because I often see working examples of concepts where the author throws in a disclaimer like, "This isn't production code, but it works..."

Thanks,
Danny

----------


## VBDT

Yes, I forgot to mention that LL hook returns a structure with the info. My component is based on the info values and they are very accurate.

As why my code Is more then others, simply because I covered every possible angle, also you might noticed that the component fires to additional events Mouse Click and Mouse DoubleClick which I have never seen in any other mouse hook example. Also I added some attributes to the methods and classes to make the component more professional. I just tried to make the component close to .net components as much as it is possible.
Did I have to apply this attributes? No, but I wanted to do it so that you can see how it is done. And yes, if you want to make a professional component then you should apply attributes to your methods and classes to make the componen as close to .net components as it is posible. The reason is that most of the developers are familiar with the .Net classes and methods and I think that they like to see components that behave the same way as in .Net (this includes naming, applying attributs etc.)

----------


## 5applerush

Thanks for the help VBDT.  I'm out of reputation right now, but I'll certainly pass some along when I can!  And thanks again for posting this excellent code.

Danny

----------


## Orkidea

Wonderful! Thank you very much

----------


## cablehead

Im trying to use this in a C# project. Works fine.

...Except my project is whining for a signed assembly.

IS there anyway you can compile and send me signed version. 

TIA

----------


## VBDT

> Im trying to use this in a C# project. Works fine.
> 
> ...Except my project is whining for a signed assembly.
> 
> IS there anyway you can compile and send me signed version. 
> 
> TIA


Hi, I updated the WindwosHookLib with a signed assembly version.  :Smilie:   Pleas let me know if it works.

----------


## cablehead

I managed to compile a signed version. Works great.

Now I need to hunt down info on wheel "ticks"...

I need to hold off on the wheel event until I can procress how many wheel turns there are before setting a value.

Thanks

----------


## Jaex

Thanks for library and simple demo.

I'm trying to do like that thing :


vb Code:
Private Sub MouseHook_(ByVal sender As System.IntPtr, ByVal e As WindowsHookLib.MouseEventArgs) Handles MouseHook.MouseDown, MouseHook.MouseClick, MouseHook.MouseUp        If Handle = MouseHook.MouseDown Then            TextBox1.Text &= "MouseDown" & vbCrLf        ElseIf Handle = MouseHook.MouseClick Then            TextBox1.Text &= "MouseClick" & vbCrLf        ElseIf Handle = MouseHook.MouseUp Then            TextBox1.Text &= "MouseUp" & vbCrLf        End If    End Sub

That code just explain what i want.
Will be like that thing too :

    Private Sub MouseHook_(ByVal sender As System.IntPtr, ByVal e As WindowsHookLib.MouseEventArgs) Handles MouseHook.MouseDown, MouseHook.MouseClick, MouseHook.MouseUp
        TextBox1.Text &= Handle & vbCrLf
    End Sub

But i can't figure out how can i do.

----------


## Lionsitaly

I have discovered that if there is a long time operation during event keydown the ALT ( may be other control key ) seems pressed in the next keydown event .
Code sample is more easy I change the demo KeyDown event adding a time consuming on ALT F2 .
If I press ALT-F2 the next F2 comes with ALT also if press only F2 without ALT.
If I press ALT alone the situation reset normal.

Here the piece of code I change 

Private Sub KeyboardHook_KeyDown(ByVal sender As Object, ByVal e As WindowsHookLib.KeyEventArgs) Handles KeyboardHook.KeyDown

'Set the key down Handled property
e.Handled = Me.HandleKeyboardCheckBox.Checked
If e.KeyCode = Keys.F2 And e.Alt Then
Me.DisplayTextBox.AppendText(Environment.NewLine)
Me.DisplayTextBox.AppendText("===================== Sleep 1000")
System.Threading.Thread.Sleep(1000)
End If
.
.
. 
I hope I have well explanied .

----------


## VBDT

> I have discovered that if there is a long time operation during event keydown the ALT ( may be other control key ) seems pressed in the next keydown event .
> Code sample is more easy I change the demo KeyDown event adding a time consuming on ALT F2 .
> If I press ALT-F2 the next F2 comes with ALT also if press only F2 without ALT.
> If I press ALT alone the situation reset normal.
> 
> Here the piece of code I change 
> 
> Private Sub KeyboardHook_KeyDown(ByVal sender As Object, ByVal e As WindowsHookLib.KeyEventArgs) Handles KeyboardHook.KeyDown
> 
> ...


Hi Lionsitaly,

According to MS the global hook subs should not have long time operations. If they do then according to them windows pass the message to the other applications without waiting to return from the sub. In this case the sub is the keydown event handler. Anyways, I like to examine the problem and want to ask you for the exact steps to produce the problem.
Thanks VBDT.

----------


## Lionsitaly

ok many thanks for support !
I try !
Open change the event keydown in this way



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

        'Set the key down Handled property
        e.Handled = Me.HandleKeyboardCheckBox.Checked
        If e.KeyCode = Keys.F2 And e.Alt Then
            Me.DisplayTextBox.AppendText("===================== Sleep 1000")
            System.Threading.Thread.Sleep(1000)
        End If        'Print the key down data
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== KeyDown")
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("Handled: " & e.Handled)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("KeyCode: " & e.KeyCode.ToString)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("KeyValue: " & e.KeyValue)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("KeyData: " & e.KeyData.ToString)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("Alt: " & e.Alt)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("Control: " & e.Control)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("Shift: " & e.Shift)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("Modifiers: " & e.Modifiers.ToString)
        Me.DisplayTextBox.AppendText(Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== End KeyDown")

    End Sub
```

Now run the demo press ALT-F2 and is ok after press ALT-F1 and ALT is lost in keydata.
I hope to be clear ...
You can also contact me on msn Lions_italyAThotmail.com and skype lionsitaly, many thanks for the library and support !
 :wave:  Ciao from italy

----------


## obi1kenobi

Firstly, I'd like to thank VBDT for an excellent piece of code.

But, I've discovered a slightly embarassing typing error:
In the ClickCheckBox object, the text says "Press *sh***it + C* to click me" (disregard the ***, I've written it this way to avoid the automatic replacement) instead of "Press *Shift + C* to click me".

Also, GroupBox1's text is missing an 'e' in 'mouse'.

----------


## VBDT

> Firstly, I'd like to thank VBDT for an excellent piece of code.
> 
> But, I've discovered a slightly embarassing typing error:
> In the ClickCheckBox object, the text says "Press *sh***it + C* to click me" (disregard the ***, I've written it this way to avoid the automatic replacement) instead of "Press *Shift + C* to click me".
> 
> Also, GroupBox1's text is missing an 'e' in 'mouse'.


 :Big Grin:  Corrected; thanks 
VBDT

----------


## obi1kenobi

Something weird is happening in my application:

When the mouse is hooked, upon right-clicking on a control, its context menu shows up normally, however the MouseDown event of that control doesn't fire.

When the mouse is not hooked, the context menu shows normally, AND the MouseDown event is fired.

IMHO, it must be connected to the MouseHook in some way. What do I do to fix this?

----------


## VBDT

> Something weird is happening in my application:
> 
> When the mouse is hooked, upon right-clicking on a control, its context menu shows up normally, however the MouseDown event of that control doesn't fire.
> 
> When the mouse is not hooked, the context menu shows normally, AND the MouseDown event is fired.
> 
> IMHO, it must be connected to the MouseHook in some way. What do I do to fix this?


Hi obi1kenobi, I tested the hook and I couldn’t find any problems with it. In general when you right click on a form that has a ContextMenuStrip the right click is not fired; this is a normal windows behavior.  :Smilie:

----------


## obi1kenobi

> Hi obi1kenobi, I tested the hook and I couldnt find any problems with it. In general when you right click on a form that has a ContextMenuStrip the right click is not fired; this is a normal windows behavior.


Strange, I rebuilt the project and now both the ContextMenuStrip is shown and the right click is fired. I don't get it... But, since we're talking about a Microsoft product, everything is possible... :big yellow:

----------


## gozillasnack

Hey there,

I'm trying to use your dll file in a Windows Mobile 5.0 VB application, but when I try to load the application, this is the error message it gives me. "File or assembly name 'System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089', or one of its dependencies, was not found."

could you shed some light on this, perhaps?
Thanks

----------


## obi1kenobi

Try adding a reference to System.Windows.Forms in your project. (I'm not sure whether the assembly exists in the CF version...) Right-click the project, then select Properties, then the References tab and then press Add and select the System.Windows.Forms assembly.

----------


## VBDT

> ok many thanks for support !
> I try !
> Open change the event keydown in this way
> 
> 
> 
> ```
>    Private Sub gkh_KeyDown(ByVal sender As Object, ByVal e As WindowsHookLib.KeyEventArgs) Handles gkh.KeyDown
> 
> ...


Hi, do not use Dialog boxes or Thread sleep in the hook event subs.

----------


## bagstoper

how would i go about recompiling your DLL so that the e.keycode.tostring of backspace is {backspace}? i also want to do this for all the other non alphanumeric keycodes.

----------


## VBDT

> how would i go about recompiling your DLL so that the e.keycode.tostring of backspace is {backspace}? i also want to do this for all the other non alphanumeric keycodes.


Hi, that is a custom string and the hook doesn’t return value with that format. The only way is to handle the key event and format the string according to the key value return by the "e.KeyCode".

----------


## bagstoper

Ok i was afraid that was what i would have to do. but thanks anyways for the good keyboard, mouse, and clipboard hook.

----------


## pedromorfeu

Hi VBDT,

WindowsHookLib doesn't support the "Windows Key" as a modifier. Is this viable? Do you intend to develop that?

Thanks. :Smilie:

----------


## VBDT

> Hi VBDT,
> 
> WindowsHookLib doesn't support the "Windows Key" as a modifier. Is this viable? Do you intend to develop that?
> 
> Thanks.


Hi pedromorfeu, I am not sure what you mean by Windows Key. Do you mean the window keyboard key? Just to be clear the WindowsHookLib supports all the keys. Can you be more specific about what you are trying to achieve?

----------


## pedromorfeu

Hi VBDT,


Thanks for replying. Yes, I meant the windows keyboard key. What I want to get is to use that key as a modifier like Control, Alt or Shift in order to make combinations with other keys. Most of the times the windows keyboard key is used as a modifier (WIN+E to open explorer, for instance) but in programming it is not included in the modifiers. When I get a KeyDown event I need to know if windows key is also pressed.

Thanks.  :Thumb:

----------


## VBDT

Hi pedromorfeu, the WIN key is not a modifier in Visual Studio environment. The only modifiers are Alt, Control and Shift. But what I would sagest to do is having a class level Boolean variable let say called *isWinDown* that would be set to true in *KeyDown* event if the win key is pressed. And when it is released you set it false in the *KeyUp* event. In this way you can know the win key status at any time.

I hope this can be helpful.

----------


## apopka_pilot

Hi VBDT, thank you for this fantastic piece of code.

I'm trying to get you lib file to return the actual key that was pressed. Example, if I press the "4" key, I currently get "D4" & if I press the "f" key, it returns "F" (capital F). See below.



```
Private Sub kHook_KeyDown(ByVal sender As Object, ByVal e As WindowsHookLib.KeyBoardEventArgs) Handles kHook.KeyDown
        My.Application.DoEvents()

        Dim KeyThatWasPressed As String = e.KeyCode.ToString
        MsgBox(KeyThatWasPressed)

        My.Computer.FileSystem.WriteAllText("C:\Test.txt", KeyThatWasPressed, True)


    End Sub
```

Thanks in advance for your help.  :Thumb:

----------


## bagstoper

I had the same problem. But I just set up select case statement and i think it went something like this:



```
        Select Case e.keycode
            Case d1
                Dim KeyThatWasPressed As String = "1"
                MsgBox(KeyThatWasPressed)
        End Select
```

----------


## apopka_pilot

sounds pretty simple but LONG. If that what needs to be done then I'll have @ it. Thanks for your help :wave:

----------


## bagstoper

It was long but it works and I couldn't think of any other way around it.

----------


## TommyB83

Hello,
First of all thanks for this great work  :Smilie: 

Forgive me my stupid question, but where are the LL* classes now? Or can I use the KeyboardHook / MouseHook classes now?
I have used version 1.1.0.2 before and want to upgrade it.

Also is it possible to catch mouse wheel events if using the scroll area of a touch pad? This haven't worked in the old version.

Thanks

----------


## obi1kenobi

@VBDT:
Ok I just upgraded to the latest version and now the hook doesn't work:

I'm using both a keyboard and a mouse hook and I'm installing them properly but they aren't raising any events. =/ Secondly, sometimes upon trying to remove the hook, I get the following exception:

WindowsHookLib.KeyboardHookException: Invalid hook handle
   at WindowsHookLib.KeyboardHook.RemoveHook()

Any help would be greatly appreciated.

----------


## VBDT

Hi obi1kenobi,
I have updated the component to the version 1.1.0.7 some time ago and forgot to update it in here. I don’t know why I didn’t update here maybe for some reason but I can’t remember it if there is one. I normally update a component if I know there are no issues with it. Anyway, I have tested and updated the component so you can download the new version and see if it works without any problems. Unfortunately I don’t have 1.1.0.5 version to see what the problem is but I think one of the reasons that I have updated it to 1.1.0.7 might be for the problem you are having. So try the new version and let me know if it works without any problems. 
Note the components namespace is changed from WindowsHookLib to WindowsHook so you will need to change it in your project. When you reference the new version in your project the name WindowsHookLib will be underlined in your code as it can’t find it. You just need to change it to WindowsHook.

Best regards,
VBDT

----------


## obi1kenobi

Will do. I have a lot of work to do at the moment, I'll update to the new version as soon as I can. I'll post the results here as well.

----------


## obi1kenobi

I just updated to the newest version. The KeyUp and MouseUp events fire just fine, however the MouseWheel event is not raised when the mouse wheel is turned.

----------


## VBDT

> I just updated to the newest version. The KeyUp and MouseUp events fire just fine, however the MouseWheel event is not raised when the mouse wheel is turned.


Obi1kenobi thanks for testing. I think there is some thing is wrong with your project. Try to run the demo project I posted and see if the MouseWheel event fires. I tried it and I dont see any problem with it.

----------


## obi1kenobi

I will do that as well, however what could be wrong with my project?

There is only one thing I can think of: this time I used a notebook computer and the scrolling action was due to the side region of the touchpad, so it was being synthesized by the mouse driver - there was no actual scrolling. Could this have anything to do with it?

----------


## obi1kenobi

I just downloaded the Demo and I'm sorry to say that it doesn't register the mouse wheel events either.

Btw, the dll is missing in your demo app, I had to download it separately.

----------


## VBDT

> I just downloaded the Demo and I'm sorry to say that it doesn't register the mouse wheel events either.
> 
> Btw, the dll is missing in your demo app, I had to download it separately.


Hmm, obi1kenobi I have downloaded the demo and the hook .dll and tested it. It works as it spouse to. Here is the screenshot of it. I really dont know why it doesnt work for you.

----------


## obi1kenobi

That really is weird... Btw I notice you used XP to test the app. ATM, I'm using Vista. Could that be the cause? Anything else I could do to fix the issue?

----------


## VBDT

> That really is weird... Btw I notice you used XP to test the app. ATM, I'm using Vista. Could that be the cause? Anything else I could do to fix the issue?


Maybe that could be a reason. I should see the specifications of the API functions for vista. Maybe there are some changes that I dont know. If I find something, than I will post it here.

----------


## obi1kenobi

Thanks  :Smilie:  Your help is appreciated  :Smilie:

----------


## Erco21

since im not too familiar with library's, could you explain me how the code should look if i want my timer to run all the time LMB is down and LMB is up again to stop the timer

----------


## obi1kenobi

After installing the hook, test the MouseDown event for the left mouse button and start the timer if so. In the MouseUp event, test for the left mouse button and stop the event. See the example given in post #1 for detailed info as to how to install the hook and handle the events.

----------


## Erco21

i cant get it to work, if u know how exactly it should look plz post it here

----------


## gep13

Hey,

My question would be, as per your other thread, what have you tried?

It is not enough to simply say that it does not work.  Myself, Obi and VBDT have all used the library to do variations of what you are asking, so it definitely DOES work.

Here are the steps that you need to follow:

1) Add a reference to the library in your project (Right Click on the Project in the solution explorer and select Add Reference, and browse to the DLL)
2) Create two buttons and put the following in their click events:



```
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Try
            'Install the mouse hook
            Me.MouseHook1.InstallHook()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Form1.Log.WriteException(ex, TraceEventType.Error)
        End Try
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        Try
            'Remove the mouse hook
            Me.MouseHook1.RemoveHook()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Form1.Log.WriteException(ex, TraceEventType.Error)
        End Try
    End Sub
```

And then you will need to create two events handlers similar to these:



```
Private Sub MouseHook1_MouseDown(ByVal sender As Object, ByVal e As WindowsHook.MouseEventArgs) Handles MouseHook1.MouseDown

        'Set the mouse down Handled property
        e.Handled = Me.HandleMouseCheckBox.Checked And Not Me.mList.Contains(CType(sender, IntPtr))
        'Print the mouse down data
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== MouseDown")
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Handled: " & e.Handled)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Button: " & e.Button.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Clicks: " & e.Clicks)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Delta: " & e.Delta)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Location: " & e.Location.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Control Handle: " & sender.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== End MouseDown")

    End Sub

    Private Sub MouseHook1_MouseUp(ByVal sender As Object, ByVal e As WindowsHook.MouseEventArgs) Handles MouseHook1.MouseUp

        'Set the mouse up Handled property
        e.Handled = Me.HandleMouseCheckBox.Checked And Not Me.mList.Contains(CType(sender, IntPtr))
        'Print the mouse up data
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== MouseUp")
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Handled: " & e.Handled)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Button: " & e.Button.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Clicks: " & e.Clicks)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Delta: " & e.Delta)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Location: " & e.Location.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("Control Handle: " & sender.ToString)
        Me.DisplayTextBox.AppendText(System.Environment.NewLine)
        Me.DisplayTextBox.AppendText("===================== End MouseUp")

    End Sub
```

These event handlers handle the events that are raised by the library.  You will obviously need to remove the code which writes to the textbox, and rather start and stop your timer instead.

You will also need the following code to declare an instance of MouseHook:



```
Friend WithEvents MouseHook1 As WindowsHook.MouseHook
```

Gary

----------


## obi1kenobi

In the Button3_Click and Button4_Click event handlers, it would also be wise to check the proper state of the hook - you wouldn't want to try and install a hook which has already been installed.

----------


## Erco21

can i put the hook to install on openning and close on exiting the form?

----------


## gep13

Hey,

Sure, there is nothing to stop you putting the installation of the hook somewhere else, but as obi mentioned, you should make sure that the hook isn't already registered.

Gary

----------


## Erco21

ok, i put two buttons, and when i click to install hook this comes up:

and, when not debugging theres no errors

----------


## gep13

Hey,

What does the IDE tell you is going wrong?  There has got to be an error generated?!?

What is it?

Did you follow all the steps as I laid them out?

Gary

----------


## Erco21

it says: NullReferenceException was unhandled
and, i followed all the steps u said

----------


## gep13

Hey,

Not meaning to be blunt, but if you have followed all the steps that I have lined out, then the application should be working.

To recap, here are the exact steps that I have just carried out, and the application is working as I expect it to....

1) Create a new project
2) Add a reference to the WindowsHookLib.dll
3) Added a New Object called MouseHook1 and a New Timer called myTimer
4) Created event handlers for the Form Load and Form Closing Event
5) Added code to Install and Remove the hook in these event handlers
6) Created the event handlers for the global mouse up and down events
7) Added code to Start and Stop the Timer in these event handlers
8) Ran the application
9) It works

Here is the final code (obviously, this is a basic version that doesn't account for error handling and which will need to be modified):



```
Public Class Form1

    Dim WithEvents MouseHook1 As New WindowsHook.MouseHook
    Dim myTimer As New Timer

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Me.MouseHook1.RemoveHook()
        Me.MouseHook1.Dispose()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.MouseHook1.InstallHook()
    End Sub

    Private Sub MouseHook1_MouseDown(ByVal sender As Object, ByVal e As WindowsHook.MouseEventArgs) Handles MouseHook1.MouseDown
        myTimer.Start()
    End Sub

    Private Sub MouseHook1_MouseUp(ByVal sender As Object, ByVal e As WindowsHook.MouseEventArgs) Handles MouseHook1.MouseUp
        myTimer.Stop()
    End Sub
End Class
```

Gary

----------


## Erco21

i followed those steps, and checked about 10 times the code but this keeps coming up when i try to start the form: NullReferenceException was unhandled

----------


## gep13

Have you copied and pasted the code that I have just given you?

I have literally just run that code, and it works fine.

Gary

----------


## Erco21

i wrote the SAME code earlier and it wont work

----------


## obi1kenobi

Try adding the New keyword when declaring the hook.

Instead of


```
Dim MouseHook1 As MouseHook
```

use


```
Dim MouseHook1 As New MouseHook
```

----------


## Erco21

this was the problem (i finnaly got it working now):
firs i declared this:
    Friend WithEvents MouseHook1 As WindowsHook.MouseHook
and now i used obi1kenobi's way
thx, works great

----------


## gep13

> i wrote the SAME code earlier and it wont work


You are missing my point, you can't have written the SAME code!!  All other things being equal, the code that I have posted works, your doesn't.

Gary

----------


## obi1kenobi

@gep13: In post #63, you seem to have missed the constructor call and the MouseHook was never instantiated, thus leading to the exception.

----------


## gep13

Hey,

The sample application seems to have separated the instantiation of the MouseHook into two separate lines, hence, what I put in post #63 does not have the New Keyword, and that was an oversight on my part.

However, you will see that the code in post #70 does have the New Keyword declared, and copying and pasting of this code would have resulted in it working.

Gary

----------


## Calab

Is there any chance that this example could be updated to support VB 2010 ?

Thanks!

----------


## VBDT

> Is there any chance that this example could be updated to support VB 2010 ?
> 
> Thanks!


Hi,
I am not aware of any issues with framework 4. If there is one than provide the error please.

----------


## Horatis

Hi VBDT,
its fascinating. I downloaded ya Code cause I thought, I'm to stupid. Seems so. First of all: I use VB.Net 2010 Express under Win7. Well. I opened ya source and started it. Works perfect. I can hook and all. I wrote similar code on my own and it didn't work. Now I took your code and copied it into a classes and stuff under 2010. Well. Guess what. It doesn't work. Can you confirm or perhaps even solve me that riddle?

----------

