Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
Available now!
Buy at Amazon US or
Buy at Amazon UK


» Windows API reference
» Webcam streaming in VB.NET
» Remoting with firewalls
» RSA from first principles
» Key & MouseLogger in .NET
» Networking Resource Kit for .NET
» Migrating VB6 Winsock to VB.NET
» Migrating C++ sockets to C#
» RFC Reference guide
» COM Reference guide
» WMI Reference guide
» SQL stored procedures
» TCP & UDP port reference
» NET Framework reference
» Ethernet Type codes
» MAC address assignments
» DLL entry point reference
» Boost SQL performance
» Free SMS UK
» Free SMS Ireland
» Free SMS South Africa
» Internet Explorer

Contact us

Mouse & Keyboard Recorder for .NET

This application is designed to record user mouse activity, and keyboard presses from anywhere on the desktop, even when other applications have the focus.

This type of application can be used in many different scenarios, such as –

  • A remote pointer application
  • A go-anywhere colour picker feature
  • Macro generation software
  • Key logging utilities

One key feature of this application is that it uses events to model user actions. This means that the calling application need not constantly poll sets of properties for changes. As you will see in the code, the program is divided into two loosely coupled files, namely Form1.cs (the user interface) and another called InputListener.cs (the nuts & bolts of the software).

Although .NET allows you to track mouse activity using the Control.MouseButtons and Control.MousePosition classes, there is no native means of capturing global key-presses. To achieve this functionality, a Win32 API function is used, namely GetAsyncKeyState. This function takes a numeric keyboard scan-code as a parameter and returns –32767 (referred to as int16.MinValue+1 in code) if the key is pressed.

Keyboard scan-codes for standard alphanumeric keys are quite straightforward. Keys A-Z are mapped to their uppercase ASCII equivalent. Keys 0-9 (excluding the numeric keypad) are directly mapped to their ASCII equivalent. Extended keys such as delete or enter are mapped to unprintable ASCII codes, and appear as strange symbols in the display, as can be seen from the screenshot above. A bit of experimentation with the application will help you discover the codes for the rest of the keyboard.

Without further delay, lets start coding the application. Start off by creating a new C# Windows Forms project named “Recorder” in Visual Studio .NET. Right click on Solution Explorer and add a new class named InputListener.

Enter the following code as the body of the InputListener class. It is used simply to set up a new thread that runs an infinite loop, which will act as the underlying polling mechanism. This underlying polling mechanism will be completely transparent to the calling application.

public class InputListener
      public void Run()
      Thread thdMain = new Thread(new ThreadStart(RunThread));
      private void RunThread()



It is a unwritten coding convention that all events should contain two parameters, an object referring to the source of the event, and a second object, derived from EventArgs and containing any further information the ‘subscribing’ application may need. The first event we will deal with is the Mouse Move Event, this uses the MouseMoveEventArgs class, which is defined thus (and included in the body of the Recorder Namespace in InputListener.cs):

public class MouseMoveEventArgs : EventArgs
      public MouseMoveEventArgs(int X,int Y)
            this.X = X;
            this.Y = Y;
      public readonly int X;
      public readonly int Y;


In the input listener class, we must define the Event, and the delegate for this event, using the following code

private int lastX = 0;
private int lastY = 0; 
public delegate void MouseMoveHandler
      (object inputListener,
                  MouseMoveEventArgs mouseMoveInfo);

public event MouseMoveHandler OnMouseMove;

This event is generated by monitoring the Control.MousePosition class for changes. The best place to do this is within the loop in the RunThread method, that we created earlier. Therefore, add the following code directly after the Thread.Sleep(10); in RunThread().
Page 2  Page 3  Page 4 


Copyright 2019 Infinite Loop Ltd.