'Windows: SetCursorPos over RDP sometimes results in wrong position
I am connected to a Windows VM via RDP. The host system is also Windows. On the VM, I run an application that uses SetCursorPos to change the position of the mouse cursor. I have observed that the call sometimes causes the mouse cursor to arrive at a completely different location.
If I run the application on the host system, it runs without errors. So it seems to be related to RDP.
Consider the following C# demo application. Basically, it calls SetCursorPos a thousand times with random positions and checks with GetCursorPos whether the mouse cursor has landed at the specified position.
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace CursorDemoApp
{
class Program
{
static void Main()
{
var random = new Random(1);
var displayWidth = GetDisplayWidth();
var displayHeight = GetDisplayHeight();
for (var run = 1; run <= 1000; run++)
{
SetAndCheckCursorPosition(0, 0);
var x = random.Next(displayWidth);
var y = random.Next(displayHeight);
SetAndCheckCursorPosition(x, y);
Thread.Sleep(10);
}
}
private static void SetAndCheckCursorPosition(int x, int y)
{
SetCursorPosition(x, y);
var currentPosition = GetCursorPosition();
if (currentPosition.X != x || currentPosition.Y != y)
{
Console.WriteLine("Failed! Expected: ({0},{1}) - Got: ({2},{3})", x, y, currentPosition.X, currentPosition.Y);
}
}
private static void SetCursorPosition(int x, int y)
{
Console.WriteLine("SetCursorPosition({0},{1})", x, y);
SetCursorPos(x, y);
}
[DllImport("user32.dll")]
private static extern bool SetCursorPos(int x, int y);
private static Point GetCursorPosition()
{
GetCursorPos(out var point);
Console.WriteLine("GetCursorPosition() == ({0},{1})", point.X, point.Y);
return point;
}
[DllImport("user32.dll")]
private static extern bool GetCursorPos(out Point point);
private static int GetDisplayWidth()
{
return GetSystemMetrics(16 /* SM_CXFULLSCREEN */);
}
private static int GetDisplayHeight()
{
return GetSystemMetrics(17 /* SM_CYFULLSCREEN */);
}
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int index);
[StructLayout(LayoutKind.Sequential)]
private struct Point
{
public int X;
public int Y;
}
}
}
When I run this in the VM, I get as output, for example:
...
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(1330,269)
GetCursorPosition() == (1330,269)
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(18,10)
GetCursorPosition() == (1330,269)
Failed! Expected: (18,10) - Got: (1330,269)
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(973,392)
GetCursorPosition() == (973,392)
...
Can anyone explain this behavior or provide a solution?
(Originally, I noticed this when using Eclipse SWT and Display.setCursorLocation(..). Since that also uses SetCursorPos under the hood, I wanted to leave this as a hint for search engines.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
