Examples

Introduction

The InputManager library allows you to take control over the whole user common input. From tracking (hooking) user input to simulating user input. It allows you to send and receive global mouse and keyboard messages, in one easy to use library. It supports DirectX input simulation, which means you can send mouse or keyboard messages to any DirectX game you want, and the game will register it correctly.

With this library, you can create a complete macro recording application; it's well documented, and can be easily used with any application.

Background

Starting my way to create my own Macro Recording application, today known as Mouse Recorder Pro, I needed to find a way to register mouse and keyboard messages and track them down. After a number of version updates for Mouse Recorder Pro, and after improving my own coding skills, I made this library to help others.

The hook classes in this library were not written by me (but they were modified by me) to be honest. I don't remember the person who helped with it, but if I am able to track him, I will update this article.

The other classes were written by me, with some research and a lot of reading. The main problem I had was to be able to register user input in DirectX games, which I managed to accomplish afterwards.

The Concept (Or, How it Works)

The library was written in VB.NET, and tested on many systems (as part of its use in the Mouse Recorder Pro commercial application).

The keyboard and mouse messages are being sent with the SendInput API, which is a bit more flexible than other APIs. With the SendInput API, your application can send mouse and keyboard messages in a low level (as DirectX is). This allows you to register those messages in any DirectX game.

The mouse and keyboard hook classes allow you to track the user input. The classes use the SetWindowsHookEx API. This API "binds" any new mouse or keyboard message to a specific method in the hook classes. Every time a new message arrives, Windows calls that method. Within that method, an event is raised to inform you that a new input message has arrived.

Mouse Recorder Pro 2 - it uses the InputManager library!

Using the code

To use this library, we first need to add a reference for it in our project; download the InputManager library from the link above, and extract it. Now do the following:

Open up your project.

Right click on "References" and "Add Reference".

Select the "Browse" tab and select the extracted "InputManager.dll".

Accept all dialogs.

To make this project work in Debug mode, double click on Properties, go to "Debug", and uncheck "Enable the Visual Studio hosting process".

I wasn't able to use the class hook classes (used for tracking) with .NET Framework 4, so if you are using .NET Framework 4, please change the target framework to 3.5 or any framework below by going to the project properties and selecting a different version of the .NET Framework.

Now, let's add the "using" statement to make it a bit easier for coding. Add the following using statement:

using InputManager;

OK, let's get to know how to use this library.

Tracking User Mouse and Keyboard Messages

Download this hook example at the top

To track the user mouse and keyboard messages, we need to set up a hook. How do we do that? With InputManager, it's pretty easy.

The first two lines allow us to track the keyboard messages. This is done by two methods we will create to handle those events. The third line tells the InputManager library to set up a hook and start reading the keyboard messages.

Now let's add the two methods we talked about earlier:

void KeyboardHook_KeyUp(int vkCode)
{
//Everytime the users releases a certain key up,
//your application will go to this line
//Use the vKCode argument to determine which key has been released
}
void KeyboardHook_KeyDown(int vkCode)
{
//Everytime the users holds a certain key down,
//your application will go to this line
//Use the vKCode argument to determine which key is held down
}

To convert those keys to a string instead of a virtual key code, use this simple technique:

The first three lines tell the InputManager library to add event handlers for each mouse message type (mouse button events, mouse move event, and wheel scrolled event). We will add the methods that handle those messages below. The fourth line tells the InputManager class to install the hook and start receiving the messages.

Let's add the methods that handle those messages:

void MouseHook_WheelEvent(MouseHook.MouseWheelEvents wEvent)
{
//Event time the wheel was scrolled the application will go to this line
//Using the wEvent argument we can detect
//if the mouse was scrolled forward or backward
}
void MouseHook_MouseMove(MouseHook.POINT ptLocat)
{
//Everytime the mouse moved, the application will go to this line
//Using the ptLocat arguments you can detect
//which point the mouse cursor moved to
}
void MouseHook_MouseEvent(MouseHook.MouseEvents mEvent)
{
//Everytime a mouse button changed it's state
//(from up to down or down to up) the application will go to this line
//Using the mEvent argument we can detect which button changed it's state
}

To detect if the wheel was scrolled up or down within the MouseHook_WheelEvent method, we use the MouseHook.MouseWheelEvents enum:

To send mouse messages (mouse key strokes, mouse movements, wheel scroll), we use the Mouse class in the InputManager library.

To move the mouse to a certain location (in screen coordinates), we use the Mouse.Move method:

Mouse.Move(Point.X, Point.Y);
//Moves the mouse to a certain location on the screen

To perform a mouse click message, we use the Mouse.PressButton method:

Mouse.PressButton(Mouse.MouseKeys.Left); //Performing a left click

To send mouse button down or up messages, we use the Mouse.ButtonDown/Mouse.ButtonUp methods:

Mouse.ButtonDown(Mouse.MouseKeys.Left); //Holding the left mouse down
Mouse.ButtonUp(Mouse.MouseKeys.Left); //Releasing the left mouse button

To scroll up or down, we use the Mouse.Scroll method:

Mouse.Scroll(Mouse.ScrollDirection.Down); //Scroling down
Mouse.Scroll(Mouse.ScrollDirection.Up); //Scrolling up

Download this input simulating example at the top

Points of Interest

Writing this library (parts of it) was really fun and a bit challenging. There are other ways of sending mouse and keyboard messages with different APIs which don't support DirectX and are easier to use, but I wanted to simplify it and create my own library, so you don't even need to know what API means. With this library, you can send and receive input messages easily!

History

13.10.2010: Added an explanation on how the library works (the concept behind it).

Share

About the Author

My name is Shay and I'm 21 years old.At age 16 I created Nemex Studios (www.byshynet.com), an application development "company" (not official).I'm the developer of "Mouse Recorder Pro", "Mouse Shaker" and many other applications, developed to help the community.

Comments and Discussions

Is the application you are trying to type in is running as Administrator? if so, This type of method cannot work as windows disables applications running as administrator from getting anyvirtual events using this method.

The application I'm running is not running as Administrator. It acts the same whether I'm editing a text file in Notepad, typing a URL in Chrome, or in a terminal, etc. When I'm playing a game, I'm able to keyDown 'w' to move forward as intended, but just in text fields it doesn't seem to repeat the key. This holds even for things like terminals in games (like the Source Engine terminal).

Running our application as administrator doesn't seem to help either.

Beyond doing something like

Keyboard.KeyDown(keyCode);

is there anything else that I need to do to have this sort of functionality?

Edit: I just realized that there are some issues outside of text fields as well, where if I'm on a page where I can scroll up and down with the arrow keys, doing Keyboard.KeyDown(DownKeyCode) it will scroll down one tick, and then stop.

Have you tried other keycodes? InputManager was not designed for games though it does work on them.InputManager just wraps up the windows apis, I don't think there is any changes in the code I can makeit work except writing a whole driver that simulates a keyboard - which is pretty low level.

I have been working on this class, and I've tweaked some stuff and successfully made it work with Windows 8.1 and Net Framework 4.5.1! I used the Load Library and also tweaked some bits of code and some comments, so hopefully it's a little easier to understand! If anybody wants to use it here ya go!

Try to use the Keyboard class instead, though I'm not sure it will work. The Ctrl + Alt + Delete should not work as they cannot be simulated (Windows does not allow applications to simulate important system shortcuts, as the logon shortcut).

I want hook the arrow key press and mouse click events such that no other process should get it. Block those input events from all other applications. Only my currently running process should get that specified keystrokes and mouse click events. How can I do that?

You can do that simply by using WinAPI's and call the "GetForegroundWindow()" method to see if it's your own application currenly being interacted with and no other window. Another method of doing this is by handling all events of the current window and see when it loses focus - then simply unhooking.

Hi Shay, first I want to say that this code is awesome, but there is one question I'd like to ask:

I've dowloaded the source code just because I don't want to have a separated DLL with my program because it's small, but when I add the InputManager.vb file to my project and run it, the scroll command won't work and also it won't register the events (like mouse click, etc.)

My project is just a form with a textbox and a listbox full of crap, to test the scroll. When the dll is added as a reference everything works wonderfully, but the problem begins when I add the .vb file directly to my project.

Please, answer me as soon as posible. Thanks again for this awesome code.

Hello, thanks a lot for this awesome library. I am using it with success in .net 3.5 but unfortunately i now have to design the GUI for my application in .net 4, using this version's specific controls. Could you please post a version of this library that is supported in .net 4?

Using the library and sending some keys once I quit the application, my mouse function is being changed: scrolling the wheel leads to zoom in/out, clicking left -> double click. Same with the keyboard.

It seems wierd. This is not supposed to be happening. Did you make sure you recorded the correct keys? zoom in\out suppose to happen only when you click Ctrl + Wheel scroll. Does this happen on other computers?

How did you make sure you did move exactly one pixel? Have you used the relative mouse movement method or static method? Download "Mouse Recorder Pro" and record yourself playing. Then play the script. MRP uses this library and it should repeat the game the same as you did. Did it repeated your game exactly as you played it?

Hi there! just wanna thank you alot, i spent like 3 days trying different stuff to make a Midi To Keyboard utility, and i wasn't having good results sending the keystrokes. In apps like Notepad, everyone worked, but in a DX environment, they didn't, until i tried this one. Finally i figured it out that using KeyPress with a delay < 10, it won't work at all in DX (in my case at least), but increasing it, it worked flawlessly

Sub KeyboardHook_KeyUp(Byval vkCode asInteger)
'Everytime the users releases a certain key up,
'your application will go to this line
'Use the vKCode argument to determine which key has been released
EndSub

I'm actually using this project to accomplish another project of mine.In which, use this library to intercept all keyboard input (tested on barcode scanner and it is working!).So that, I can duplicate the same input and running in multiple program to perform different task!

I'm sorry. The only input you can get is Mouse or Keyboard input with this library. If you attach a key_down or key_up events it means it's a keyboard type event. If you attach Mouse_? events it means you can get mouse events from the attached event method.

I am using it currently and finding it very useful. Is there a way to totally ignore the mouse clicks? For e.g I want to capture the right click and do my stuff rather than showing the context menu. The program right now does my stuff and also shows the context menu.

Can you please tell me how to not allow the right click to show the context menu?

Hello and thank you so much for your great words! You cannot make other windows "ignore" your input with this library - but maybe otherWindows APIs can "consume" these windows messages - I don't have an experience with it so I'm sorry.