Не думаю, что следует предупреждать, если другой процесс изменил позицию курсора по коду, и это не пользователь, который переместил его, возможно, если какой-то WinAPI для его перемещения по коду не имеет события, которое можно зарегистрировать.
Я проверил, что если код изменяет позицию курсора, MouseMove не вызывается в WinForm или с помощью глобальной ловушки.
Так что использование GetLastInputInfo не работает, и кажется, что вы не можете определить,процесс изменил позицию перемещения.
Тем не менее, вы можете использовать таймер с этим глобальным хуком MouseMove.
https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
ВклПри запуске приложения вы сохраните положение мыши, как и раньше.
Вы запускаете таймер, например, с интервалом 100 мс.
При MouseMove вы обновитеэтой предыдущей позиции и установите для условной переменной значение true.
На тике таймера вы получите текущую позицию и сравните ее с предыдущей и условной переменной: если это не same, это не пользователь, который двигается.
Это тяжело, но это работает.
Если пользователь перемещает мышь одновременно с процессом, вы получите толькочто пользователь перемещается.
Использование таймера WinForms
public partial class FormTest : Form
{
Point PreviousMousePosition;
bool UserMovedMouse;
public FormTest()
{
InitializeComponent();
PreviousMousePosition = Cursor.Position;
TimerCheckMouseMove.Start();
TimerMoveMouse.Start();
HookManager.MouseMove += HookManager_MouseMove;
}
private void HookManager_MouseMove(object sender, MouseEventArgs e)
{
PreviousMousePosition = Cursor.Position;
UserMovedMouse = true;
}
private void TimerCheckMouseMove_Tick(object sender, EventArgs e)
{
TimerCheckMouseMove.Enabled = false;
try
{
var pos = Cursor.Position;
if ( !UserMovedMouse && pos != PreviousMousePosition)
MessageBox.Show("Mouse moved by a process");
PreviousMousePosition = Cursor.Position;
UserMovedMouse = false;
}
finally
{
TimerCheckMouseMove.Enabled = true;
}
}
private void TimerMoveMouse_Tick(object sender, EventArgs e)
{
Cursor.Position = new Point(100, 100);
}
}
Использование резьбового таймера
System.Threading.Timer TimerCheckMouseMove;
TimerCheckMouseMove = new System.Threading.Timer(TimerCheckMouseMove_Tick, null, 0, 100);
private bool TimerCheckMouseMoveMutex;
private void TimerCheckMouseMove_Tick(object state)
{
if ( TimerCheckMouseMoveMutex ) return;
TimerCheckMouseMoveMutex = true;
try
{
var pos = Cursor.Position;
if ( !UserMovedMouse && pos != PreviousMousePosition)
MessageBox.Show("Mouse moved by a process");
PreviousMousePosition = Cursor.Position;
UserMovedMouse = false;
}
finally
{
TimerCheckMouseMoveMutex = false;
}
}