可以移动鼠标调用mouse_event function或使用 System.Windows.Forms.Cursor.Position属性(property)。我想知道的是,是否有可能知道使用我的软件的用户是否正在使用这些方法之一。
我知道可以检查用户的鼠标移动,例如,查看它是否发生得太快。但是我想知道是否还有其他更准确的方法,比如检查是否正在调用某个 WinApi 函数。
当物理移动鼠标时,是否触发了 mouse_event 函数?
或者对 mouse_event 函数的调用是否进行另一个系统调用并调用“物理鼠标移动”使用的实际函数?
最佳答案
我不认为如果另一个进程通过代码更改了光标位置并且不是用户移动它是可能的,除非某些通过代码移动它的 WinAPI 具有可以注册的事件。
我测试过,如果代码更改光标位置,则不会在 WinForm 上或通过使用全局 Hook 引发 MouseMove。
因此使用 GetLastInputInfo 不起作用,并且您似乎无法检测进程是否更改了移动位置。
也就是说,您可以将计时器与此 MouseMove 全局 Hook 一起使用。
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;
}
}
https://stackoverflow.com/questions/58776794/