As mentioned in the first post, this system will continuously capture the mouse position and emit it as a series of events. At a later point, I plan to develop a web app, but for now, a simple console app will suffice.
After opening the solution in VSCode, we can see Producer.cs
- the template for console applications in .NET 7.
Console.WriteLine("Hello, World!");
Since .NET 6, this is a valid C# program. This article explains a few relatively new features that make it possible to have a one-line program in .NET.
Before changing anything, we can execute the current code.
cd Producer
dotnet run
The output is as expected, Hello World!
.
To get the mouse position, we can use the Windows API function called GetCursorPos
and invoke it using the P/Invoke
mechanism, which allows us to call platform-native functions from .NET code.
// MousePosition.cs
using System.Drawing;
using System.Runtime.InteropServices;
public class MousePosition
{
private Point _lastPoint;
private Point _currentPoint;
public string GetNewPosition()
{
GetCursorPos(ref _currentPoint);
if (_currentPoint != _lastPoint)
{
_lastPoint = _currentPoint;
return $"[{_currentPoint.X}, {_currentPoint.Y}]";
}
else return string.Empty;
}
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref Point lpPoint);
}
We can repeatedly call GetCurrent() to get a stream of mouse positions and display them only in case there was a change.
// Program.cs
var _mousePosition = new MousePosition();
while (true)
{
var newPosition = _mousePosition.GetNewPosition();
if (newPosition != string.Empty)
{
Console.WriteLine(newPosition);
}
await Task.Delay(100);
}
If we run the Producer again and move the mouse, we get a bunch of coordinates, up to 10 per second.
Now it's time to start thinking about the consumer.