我现在正在写一个自动点击器。我有一个非常困难的问题要解决,在我的知识水平。我有低水平的挂钩,以检测鼠标键下和键上。
private bool LeftButtonStatus;
private void AutoClicker_Load(object sender, EventArgs e)
{
core.mouseHook.LeftButtonDown += new MouseHook.MouseHookCallback(mouseHook_LeftKeyDown);
core.mouseHook.LeftButtonUp += new MouseHook.MouseHookCallback(mouseHook_LeftKeyUp);
}
private void mouseHook_LeftKeyDown(MouseHook.MSLLHOOKSTRUCT ma)
{
LeftButtonStatus = true;
StartClicking();
}
private void mouseHook_LeftKeyUp(KeyboardHook.VKeys key)
{
LeftButtonStatus = false;
StartClicking();
}
private void StartClicking()
{
if (LeftButtonStatus)
LeftButtonTimer.Start();
else
LeftButtonTimer.Stop();
}
private void LeftButtonTimer_Tick(object sender, EventArgs e)
{
Core.LeftClick();
}
Core
类中的click方法如下所示:
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
public static void LeftClick()
{
mouse_event(((int)KeyStates.LeftDown) | ((int)KeyStates.LeftDown), 0, 0, 0, 0);
}
问题是,当我调用Core.LeftClick();
时,我的钩子检测到它并停止计时器。
如何确保mouseHook_LeftKeyUp
和mouseHook_LeftKeyDown
方法忽略Core.LeftClick();
?
2条答案
按热度按时间zxlwwiss1#
你可以在你自己的代码中使用一个标志,在
LeftClick()
中设置ignore = true
,在钩子方法中检查if (ignore == true)
,但问题是你会面临一个竞争条件,在这个条件下,用户生成的点击可能会在设置为true
和钩子运行之间被处理,这将导致用户生成的点击被忽略。更好的方法是使用
mouse_event
的dwExtraInfo
参数。The documentation将其描述为:与鼠标事件关联的附加值。
这似乎是一个伟大的方式发送一些旗帜沿着在事件本身。
它本来是指向内存中某个位置的指针,用于存放一些数据,但是I found an example将其设置为某个任意的整数值(在他们的例子中为
111
),并且它可能会工作。它看起来像这样:
第一个
您的
mouseHook_LeftKeyUp
方法签名不同,但这是正确的吗?如果您也可以更改它以使用MSLLHOOKSTRUCT
,那么如果需要,您也可以在那里做同样的事情。在
DllImport
属性中,dwExtraInfo
的类型从技术上讲应该是IntPtr
,但在本例中这并不重要。aamkag612#
您的问题是如何区分实际的鼠标点击和虚拟的鼠标点击。我发现在您的代码中使用了鼠标挂钩,并且“关闭循环”的一种方法是根据Gabriel Luci的出色建议检查回调中的
dwExtraInfo
标志。但我开始做的是找到一种线程安全的方法,它不会“我不依赖钩子来检测自动点击,所以我最终放弃了鼠标钩子来进行测试。我尝试了几种方法,但我发现,根据我的经验,最可靠的方法是使用线程同步对象设置一个约100毫秒的监视计时器(如易于使用的SemaphoreSlim
)。该信号量可由最终使用点击的任何目标进行测试,以通过对信号量调用Wait(0)并查看bool
返回值来确定WDT是否已过期。在两个测试的第一个中,我检查了AutoClick按钮并让它运行。正如预期的那样,物理点击显示为黑色,自动点击显示为蓝色。指示灯都如预期的那样亮起来。
对于autoClick方法,我使用了
SendInput
,因为mouse_event
已经过时了(请参阅Hans Passant对此post的评论。Auto Click 5
复选框的处理程序定位并单击鼠标以点亮5个“indicator”复选框。作为一个更严格的测试,我重复了这一点,但当5X自动点击运行时,我做了几次手动点击,以确保它们穿插并以黑色打印。再次,它按预期工作。
如果你想浏览完整的代码或尝试它,full sample code在GitHub上。