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

Global Mouse and Keyboard Library

By , 8 Aug 2008
 

Introduction

This article explains how to use the mouse and keyboard library that I have created. This library consists of two things: global mouse and keyboard hooks, and global mouse and keyboard simulators.

The global hooks contain a set of events that follow the .NET event model, so they should be very simple to use if you've done anything with events before.

The simulators will actually simulate mouse movements, clicks, keyboard presses, etc. This can be useful for macro recording (which is one of the sample projects), and of course, messing with your friends. :)

Background

I've found a lot of hook and simulator code out there, but a lot of it was not very organized, and a bit hard to use. The goal here is to make a very simple and easy-to-use library for mouse and keyboard operations not natively supported by .NET.

Global Hooks

This section will explain how to use the global hooks which can capture mouse and keyboard events from any application. These events are very similar to the ones that appear on Windows controls, so they should look familiar.

Using the mouse hook:

// Create the mouse hook
MouseHook mouseHook = new MouseHook();

// Capture the events
mouseHook.MouseMove += new MouseEventHandler(mouseHook_MouseMove);
mouseHook.MouseDown += new MouseEventHandler(mouseHook_MouseDown);
mouseHook.MouseUp += new MouseEventHandler(mouseHook_MouseUp);
mouseHook.MouseWheel += new MouseEventHandler(mouseHook_MouseWheel); 

// Start watching for mouse events
mouseHook.Start();

...

// Stop watching (don't forget to do this before closing application!)
mouseHook.Stop();

Using the keyboard hook:

// Create the keyboard hook
KeyboardHook keyboardHook = new KeyboardHook();

// Capture the events
keyboardHook.KeyDown += new KeyEventHandler(keyboardHook_KeyDown);
keyboardHook.KeyUp += new KeyEventHandler(keyboardHook_KeyUp);
keyboardHook.KeyPress += new KeyPressEventHandler(keyboardHook_KeyPress);

// Start watching for keyboard events
keyboardHook.Start();

...

// Stop watching (don't forget to do this before closing application!)
keyboardHook.Stop();

Note: When you are setting the events, Visual Studio will name and create a blank method for you. You only need to type this much on the event ...

keyboardHook.KeyDown +=

...and then hit TAB two times. Visual Studio will finish the rest of the line, and will go out and create the blank method for you. This is a nice feature, and saves a lot of time; use it!

Simulators

This section will explain how to use the the mouse and keyboard simulators to simulate mouse clicks and keyboard key presses. Both the KeyboardSimulator and MouseSimulator classes are static, so they are pretty simple to use.

Simulating mouse events:

// Press Left Mouse Button Down
MouseSimulator.MouseDown(MouseButton.Left);

// Let Left Mouse Button Up
MouseSimulator.MouseUp(MouseButton.Left);

// Press down and Let up Left Mouse Button
// (equivalent to two lines above)
MouseSimulator.Click(MouseButton.Left);

// Double click Left Mouse button
// (equivalent to two Click()s above)
MouseSimulator.DoubleClick(MouseButton.Left);

The code above is used to simulate pressing and letting up a certain mouse button. The one parameter is just an enumeration of the three possible mouse buttons: Left, Right, and Middle.

Moving the mouse position:

// Move mouse cursor to Top Left of screen
MouseSimulator.X = 0;
MouseSimulator.Y = 0;

// Move the mouse cursor to the right by 20 pixels
MouseSimulator.X += 20;

The X and Y above are properties. You can use them to get the current position of the mouse cursor, or you can set them to move the mouse cursor to a new location.

Keyboard simulators:

// Press the A Key Down
KeyboardSimulator.KeyDown(Keys.A);

// Let the A Key back up
KeyboardSimulator.KeyUp(Keys.A);

// Press A down, and let up (same as two above)
KeyboardSimulator.KeyPress(Keys.A);

The code above will simulate keyboard key presses. You can press a key down (first line), which doesn't let it up yet. The second line, KeyUp, will release a key that has been pressed down, the third line with do both steps in one shot.

I also included some standard keyboard shortcuts. These can all be done with the code above, but it simplifies it a bit, and makes the code a bit more readable and obvious.

// Simulate (Ctrl + C) shortcut, which is copy for most applications
KeyboardSimulator.SimulateStandardShortcut(StandardShortcut.Copy);

// This does the same as above
KeyboardSimulator.KeyDown(Keys.Control);
KeyboardSimulator.KeyPress(Keys.C);
KeyboardSimulator.KeyUp(Keys.Control);

The code above does the exact same thing twice, except the first is a bit shorter and more obvious.

A Sample Application: Global Macro Recorder

A macro recorder is a great example for this library, since we can use the hooks to record the macro, and the simulators to play back.

Check out the Macro project in the downloadable source code.

Future Additions / Revisions

I'm going to edit and add to this library over time as I get feedback. If you think something should be added, changed, or find a problem, please post in the comments section, and I'll do what I can. Thanks. :)

Revision History

  • 7/23/08: Released first version in three versions of .NET.
  • 7/28/08: Added the Application.ApplicationExit event to make sure hooks stop.
  • 8/8/08: Got rid of the debug code in the Macro example, added the MouseWheel method to the MouseSimulator class, and got rid of the duplicate MousePoint class used in MouseSimulator.

License

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

About the Author

Brian Geiman
Software Developer RR Donnelley
United States United States
Member
No Biography provided

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

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionShif+LeftmemberMember 967060910 Dec '12 - 2:33 
Haw to simulate Shift + left or right ? it doesnt seems to work ( (win7x64 VS2012 NFW 4.5)
GeneralMy vote of 5memberdinhcongthang3 Dec '12 - 14:31 
very good
GeneralMy vote of 5memberjfln21 Nov '12 - 3:32 
A good, small library that does exactly what it says. Great documentation too. Thanks!
GeneralGreat Code - Great WorkmemberViraj Doshi1 Nov '12 - 23:22 
Hi,
This is really a great work from you. I have seen very few thing like this over the internet. Thanks for sharaing the code.
 
I think if you extend this little bit more than an automation software would emerge out of this.
GeneralVery Good!memberoiabc7 Sep '12 - 4:54 
Very Good!
QuestionMouseDown and Movememberarpego4 Aug '12 - 14:34 
Could you give me a example how to press the left button of the mouse and move it pressed, please?
 
Thanks in advance,
Arthur
GeneralMy vote of 5membercsharpbd3 Jul '12 - 1:20 
Nice articles....
GeneralMy vote of 5memberProEnggSoft7 Mar '12 - 18:44 
Good article
Questionproblem with right buttonmemberirFan917 Feb '12 - 13:38 
Hi
I managed to use the mouseup & mousedown sucessfully with the left button but for the right there seems to be some issue..
my code is..
if(some other conditions){....}// left clicks being called which works fine
else if (when condition1 is not met)
{
MouseSimulator.MouseUp(MouseButtons.Right);
}
else if (condition1)
{
MouseSimulator.MouseDown(MouseButtons.Right);
}
 
but when i run this the right button is always pressed even though when condition 1 is not being met..
please help.. thanks in advance :}
QuestionProblem with Ctrlmemberkirahvi1 Feb '12 - 0:23 
I succesfully used your library in last project. Great work! Thumbs Up | :thumbsup:
In my current project I must hook when user try copy && paste.
Using your library I can know when he presses ctrl+c, ctrl+v, shift+insert, but I can't detect when he presses right ctrl + insert.
Please, help me
AnswerRe: Problem with CtrlmemberAderele Joseph23 Oct '12 - 13:48 
See Global Shortcuts in WinForm and WPF
QuestionNice work!memberRoy Barina27 Jan '12 - 9:55 
may i use it in my codes please? (referring your article of course)
thanks Smile | :)
QuestionRequestmembermschotamaster16 Dec '11 - 17:12 
how can we save the recorded macro?
Questionhow can we save the recorded macro?membermschotamaster16 Dec '11 - 17:10 
It is a great tutorial i got alot from this article buti want to know how can we save the recorded macro?
QuestionGlobal Macro Record Example - Not responding itselfmemberPham Van Luan8 Dec '11 - 4:13 
Hi CodeSummoner,
 
Your project makes me impressively, It works well and smoothly
But I click Global Macro Record Example form, it met an error that was not responding itself.
You can debug this error because I got stuck.
 
Best Regards,
PVL
QuestionGlobal Mouse and Keyboard Librarymembershfitythrower6 Dec '11 - 6:35 
I liked the coding of global macro as it has the playback features. but it will be really helpful to me if it could save the recorded macro to a file for playing it back later sometime. I want to know how can we save these macro in a file kindly help me accomplishing this taks..
QuestionSolve my Problem Pleasemembershfitythrower6 Dec '11 - 6:32 
I liked the coding of global macro as it has the playback features. but it will be really helpful to me if it could save the recorded macro to a file for playing it back later sometime. I want to know how can we save these macro in a file kindly help me accomplishing this taks..
AnswerRe: Solve my Problem PleasememberPham Van Luan24 Dec '11 - 20:57 
Some people converts results to text then recorded to text file. (using StreamWriter class)
But I think you using "Serialization" for each class in this project.
However, I couldn't solve the error in MouseKeyArg.
 
Good luck,
PVL
GeneralRe: Solve my Problem Pleasemembershfitythrower15 Jan '12 - 19:43 
Can u help me in saving the events to a file so that i could play them like macro later. I am in urgent need of this example kindly help me with a working example....
Questionproblem when using with the float data type [modified]memberirFan9127 Oct '11 - 21:53 
hi
 
i am using the mouse simulator method with the microsoft kinect sdk methods for skeletal tracking where it returns float type of x & y position..
 
MouseSimulator.X =(int) skeleton.Joints[JointID.HandLeft].Position.X;
MouseSimulator.Y = (int)skeleton.Joints[JointID.HandLeft].Position.Y;
 
i actually uses the conversion to int but than my cursor got stuck at the top left
 
how do i uses this method with methods that returns a float data type?

modified 28 Oct '11 - 4:19.

QuestionCan't run normally in .net4.0memberhambor29 Aug '11 - 3:24 
hi, I want to compile ur programme in vs2010,but it can't run successfully, can you help me to figure it out?!
3Q!
AnswerRe: Can't run normally in .net4.0memberAuspexPT19 Nov '11 - 9:40 
Like stated in another comment below, you have to change one line of code in the hooking Start method:
 
Class GlobalHook
 
public void Start()
{
      if (!_isStarted && _hookType != 0)
            {
 
                // Make sure we keep a reference to this delegate!
                // If not, GC randomly collects it, and a NullReference exception is thrown
                _hookCallback = new HookProc(HookCallbackProcedure);
 
                _handleToHook = SetWindowsHookEx(
                    _hookType,
                    _hookCallback,
                    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress,
                    0);
 
                // Were we able to sucessfully start hook?
                if (_handleToHook != 0)
                {
                    _isStarted = true;
                }
 
            }
}

QuestionUsing this to create a Keyboard Layoutmembervinodonly8 Aug '11 - 2:37 
I'm trying to use this library on Win 7 to simulate a Non English keyboard (I have already checked MS Keyboard Layout creator, that is not working properly on new systems)..
 
So pressing a key will give letter of a differrent language.. I have few questions related with this :-
 
I have added following code in the Keypress event handler and then open a new document in word and press letter A :-
 
KeyboardSimulator.KeyPress(Keys.B);
e.Handled = true;
 
This is creating multiple B letters and plus even when e.handled is set to true still it is giving letter A also..
 
My question is on how to solve this thing..
 
2. If instead of sending normal english letters, i want to send Unicode letters then how to do that..
 
Pls help..
GeneralGreat workmemberizayoikagami29 Jul '11 - 6:31 
Thumbs Up | :thumbsup:
Thank you!
your excellent work saves me a lot of time.
 
Thank evolaz, too.
I can use these codes in Framework 4.0 now.
By the way, the simulation part works well~
Questionto use this code in .NET 4.0memberBillWoodruff5 Jul '11 - 18:50 
I was able to compile and run this in VS 2010 Pro on a Win 7-64 system: I used the replacement code for the 'Start' function in GlobalHook.cs provided in the comment here by Evolaz under the topic heading "My Vote of 2."
 
Like Evolaz, I have not tested the simulation demonstration.
 
+5 Thanks, Evolaz for the code, and +5 thanks to CodeSummoner for updating this article in 2008 so it was .NET 3.5 compatible !
 
best, Bill
"Reason is the natural order of truth; but imagination is the organ of
meaning." C.S. Lewis

QuestionHow can I press hotkey Ctrl + C and double clickmemberlampv0120327 Jun '11 - 6:44 
I got have two problem:
first: Press multiple hotkey "Ctrl + C". I set
 
    void keyboardHook_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.C)
        {
            MessageBox.Show(Clipboard.GetText());
        }
     }
    
I want to copy text with "Ctrl + C" and show this text without form. But it doesn't work.
 
the second: I want to double click to select a text and show that text selected (of couse without form). But I Don't know how? ^^... It like some path of dictionary software. Can you write an example about it?
Thanks!!!
GeneralIt's not work!memberrakkang18 Jun '11 - 2:20 
I add it by your method,but it's not work.With debug,I found:
 
_handleToHook = SetWindowsHookEx(
_hookType,
_hookCallback,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
0);
 
_handleToHook 's value always is 0.so
 
if (_handleToHook != 0)
{
_isStarted = true;
}
 
This code can't execute!
 
Confused | :confused: I want to know the reason! Thank you!
GeneralMy vote of 5memberjo le serb18 Jun '11 - 0:59 
really mega super cool >5
 
work with latest framework
QuestionCan I use this library in VB.net?memberManindra293 May '11 - 23:18 
Hi, I'm a newbie to .net and have done some basic programming in vb.net only. Can I use your library in my vb windows application? Please tell me the steps to import the library and use it, if possible.
GeneralMy vote of 2membercharles henington19 Apr '11 - 11:22 
doesn't work
GeneralRe: My vote of 2memberjacob_suibowen3 May '11 - 13:22 
The library works fine with .NET Framework 3.5. But it no longer works with .NET 4.0
GeneralRe: My vote of 2memberevolaz19 May '11 - 3:46 
Class GlobalHook
 
public void Start()
{
      if (!_isStarted && _hookType != 0)
            {
 
                // Make sure we keep a reference to this delegate!
                // If not, GC randomly collects it, and a NullReference exception is thrown
                _hookCallback = new HookProc(HookCallbackProcedure);
 
                _handleToHook = SetWindowsHookEx(
                    _hookType,
                    _hookCallback,
                    System.Diagnostics.Process.GetCurrentProcess().MainModule.BaseAddress,
                    0);
 
                // Were we able to sucessfully start hook?
                if (_handleToHook != 0)
                {
                    _isStarted = true;
                }
 
            }
}
 
to make it works on .NET 4.0, at least for the Hook part.... i've not tested the Simulation part.
 
(thanks to Patrick Klug on MSDN)
GeneralRe: My vote of 2memberAamir Butt3 Sep '11 - 7:20 
Thanks a lot. It worked perfectly with .NET framework 4.0
A year spent in artificial intelligence is enough to make one believe in God

QuestionHow to stop play eventsmemberStreetMan17 Apr '11 - 20:34 
I want stop playing events on Escape key, can you show me how do this on the code?
AnswerRe: How to stop play eventsmembercharles henington18 Apr '11 - 11:50 
Just Drop this in your cs file
 protected override void OnKeyDown(KeyEventArgs e)
        {
             if (e.KeyCode == Keys.Escape)
            {
                e.SuppressKeyPress = true;
                e.Handled = true;
            }
            base.OnKeyDown(e);            
        }

GeneralMy vote of 5memberAli Al Omairi(Abu AlHassan)13 Apr '11 - 19:58 
apologizes !!
GeneralMy vote of 1memberAli Al Omairi(Abu AlHassan)13 Apr '11 - 4:46 
Excellent Code
100 Rose | [Rose]
GeneralRe: My vote of 1membercharles henington13 Apr '11 - 5:18 
Ali Al Omairi(Abu AlHassan) wrote:
[B]Excellent Code[/B]
100 [Rose]

Why would you say Excellent Code? Which it is!! AND THEN VOTE A 1? What sense does that make?
GeneralRe: My vote of 1memberAli Al Omairi(Abu AlHassan)13 Apr '11 - 19:56 
i am sorry, i thought i voted with 5. i'll fix it up.
 
soryy again; Shucks | :->
Help people,so poeple can help you.

GeneralOutstandingmemberDavid H Robertson10 Apr '11 - 3:05 
Excellent code.
QuestionHow to save macros in file???? [modified]memberStreetMan31 Mar '11 - 3:28 
How to save macros in file????
modified on Thursday, March 31, 2011 11:03 AM

AnswerRe: How to save macros in file????membercharles henington13 Apr '11 - 5:29 
once you have the KeyCode,(the key that was pressed), convert the KeyCode to a String. Then save the String in an xmlFile then use Enum.Parse. here is a simple method to convert String to System.Windows.Forms.Keys.
 
            private Keys strKey(string value)
            {
                return (Keys)Enum.Parse(typeof(Keys), value);
            }

Generalnice workmemberReymonARG22 Mar '11 - 18:22 
nice, I was searching for this. Thanks!!
GeneralProblem with double chars like ^^ or ~~memberThiago Burgo17 Mar '11 - 7:37 
Hi CodeSummoner,
 
Great job!
 
I have a problem when I install hook, and a write a char (accents in special, ^ or ~) in other application (like notepad, visual studio or other text input), in this case the char ^ transform in ^^.
 

My keyboard is International English and my OS is Windows 7.
 
You know whats happening?
 
Thanks,
Generalawesome!mvpChrist Kennedy23 Feb '11 - 6:45 
this is really cool! thanks.
my code is perfect until i don't find a bug...

GeneralSaving List<> of events to a filememberHoracio Prada19 Feb '11 - 11:27 
Anyone know of a way to save the List of events to a file for future retreival and playback ?
GeneralSaving the recorded eventsmemberHoracio Prada19 Feb '11 - 4:59 
Is there any way to save the list of recorded mouse events in the property settings of the application ?
I'd like to replay the same sequence everytime the application is opened.

GeneralExcellentmemberKountree29 Dec '10 - 8:37 
This is an excellent example of hooks
GeneralMy vote of 5memberMatthew Dally21 Dec '10 - 1:38 
Exactly what I was looking for.
GeneralFantastic ! Brilliant solution to a problem !membervectoraudiouk27 Nov '10 - 5:20 
Fantastic ! Brilliant solution to a problem !

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 8 Aug 2008
Article Copyright 2008 by Brian Geiman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid