如何检测进程是否移动了鼠标光标而不是用户?

问题描述 投票:1回答:1

可以移动调用mouse_event function或使用System.Windows.Forms.Cursor.Position属性的鼠标。我想知道的是,是否有可能知道使用我的软件的用户是否正在使用这些方法之一。

我知道可以检查用户的鼠标移动,例如,查看它是否发生得太快。但是我想知道是否还有其他更准确的方法,例如检查是否正在调用某个WinApi函数。

当鼠标物理移动时,是否会触发mouse_event函数?

或者对mouse_event函数的调用是否会再次进行系统调用,并调用“物理鼠标移动”所使用的实际函数?

c# winforms winapi mouseevent
1个回答
0
投票

我不认为如果另一个进程通过代码更改了光标位置,并且不是由用户来移动,除非某些WinAPI通过代码移动它具有可以注册的事件,否则我不会发出警告。

我测试了如果代码更改了光标位置,则不会在WinForm上或使用全局钩子引发MouseMove。

因此,使用GetLastInputInfo无效,并且似乎无法检测到进程是否更改了移动位置。

也就是说,您可以将计时器与此MouseMove全局挂钩一起使用。

https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

  • 在应用程序启动时,您将鼠标位置保存为先前的位置。

  • 例如,您启动一​​个间隔为100毫秒的计时器。

  • 在MouseMove上,您将更新此先前位置并将条件变量设置为true。

  • 在计时器刻度上,您将获得当前位置并将其与上一个和条件变量进行比较:如果不一致,则不是移动的用户。

很重,但是可以用。

如果用户在一个过程中同时移动鼠标,则只会得到移动的用户。

使用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;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.