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.
To track user keyboard messages, in your Form_Load
event handling method, add the following code:
KeyboardHook.KeyDown += new KeyboardHook.KeyDownEventHandler(KeyboardHook_KeyDown);
KeyboardHook.KeyUp += new KeyboardHook.KeyUpEventHandler(KeyboardHook_KeyUp);
KeyboardHook.InstallHook();
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)
{
}
void KeyboardHook_KeyDown(int vkCode)
{
}
To convert those keys to a string
instead of a virtual key code, use this simple technique:
string keyString = ((Keys)vkCode).ToString();
To track user mouse messages, in your Form_Load
event handling method, add the following code:
MouseHook.MouseEvent += new MouseHook.MouseEventEventHandler(MouseHook_MouseEvent);
MouseHook.MouseMove += new MouseHook.MouseMoveEventHandler(MouseHook_MouseMove);
MouseHook.WheelEvent += new MouseHook.WheelEventEventHandler(MouseHook_WheelEvent);
MouseHook.InstallHook();
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)
{
}
void MouseHook_MouseMove(MouseHook.POINT ptLocat)
{
}
void MouseHook_MouseEvent(MouseHook.MouseEvents mEvent)
{
}
To detect if the wheel was scrolled up or down within the MouseHook_WheelEvent
method, we use the MouseHook.MouseWheelEvents
enum:
string scrollDirection;
if (wEvent == MouseHook.MouseWheelEvents.ScrollDown)
scrollDirection = "scrolled down";
else scrollDirection = "scrolled up";
To detect the position (X and Y) of the mouse every time it moves, we use the ptLocat
argument within the MouseHook_MouseMove
method:
textBox1.Text = "The mouse cursor moved to: " + ptLocat.x + ", " + ptLocat.y;
To detect which button changed its state, we use the the mEvent
argument within the MouseHook_MouseEvent
method:
textBox1.Text = "Mouse button changed state to: " + mEvent.ToString();
You can use the switch
statement to handle each mouse button/state change differently:
switch (mEvent)
{
case MouseHook.MouseEvents.LeftDown:
break;
case MouseHook.MouseEvents.LeftUp:
break;
}
Sending Mouse and Keyboard Messages (With DirectX Support)
To send keyboard messages (key strokes), we use the Keyboard
class in the InputManager library.
To send key down/key up messages, we use the Keyboard.KeyDown
or Keyboard.KeyUp
methods. An example of writing "hello" in a textbox:
ExampleText.Focus();
Keyboard.KeyDown(Keys.H);
Keyboard.KeyUp(Keys.H);
Keyboard.KeyDown(Keys.E);
Keyboard.KeyUp(Keys.E);
Keyboard.KeyDown(Keys.L);
Keyboard.KeyUp(Keys.L);
Keyboard.KeyDown(Keys.L);
Keyboard.KeyUp(Keys.L);
Keyboard.KeyDown(Keys.O);
Keyboard.KeyUp(Keys.O);
To send shortcut keys, we use the Keyboard.ShortcutKeys
method, with an array of Keys
:
ExampleText.Focus();
Keys[] keys = new Keys[] { Keys.RShiftKey, Keys.RControlKey, Keys.Left };
Keyboard.ShortcutKeys(keys);
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);
To perform a mouse click message, we use the Mouse.PressButton
method:
Mouse.PressButton(Mouse.MouseKeys.Left);
To send mouse button down or up messages, we use the Mouse.ButtonDown
/Mouse.ButtonUp
methods:
Mouse.ButtonDown(Mouse.MouseKeys.Left);
Mouse.ButtonUp(Mouse.MouseKeys.Left);
To scroll up or down, we use the Mouse.Scroll
method:
Mouse.Scroll(Mouse.ScrollDirection.Down);
Mouse.Scroll(Mouse.ScrollDirection.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).