找回密码
 加入
搜索
查看: 1126|回复: 8

[网络通信] [已解决]捕捉鼠标按下时如果按键速度过快则无法捕捉到

[复制链接]
发表于 2022-4-6 16:56:28 | 显示全部楼层 |阅读模式
本帖最后由 smooth 于 2022-4-7 13:12 编辑

我用_WinAPI_GetAsyncKeyState、_WinAPI_GetKeyState、_IsPressed试图捕捉鼠标左键在某个X坐标上被按下,但是发现一个问题,就是只要鼠标按键的速度稍快一点,就完全捕捉不到按键动作。
如果单独测试还好一些,放到脚本里,由于主循环里面有其他代码,可能会造成一定的影响,就经常捕捉不到了,按左键的时候,需要人为的延长松开的时间,才能被捕捉到。不知道有没有什么办法解决它。

我测试过,从while循环开始到结束,时间差也就是几十毫秒,搞不清楚为什么不响应_IsPressed("01"),不知道能否提高_IsPressed("01")的级别,只要按下鼠标,就跳转到这个函数上,类似按下热键。

<p>#PRE_UseX64=n
#NoTrayIcon
#RequireAdmin
Global $idTitle <a href="mailto:=@OSVersion">=@OSVersion</a> & "  " & @AutoItVersion
Global $hGui = GUICreate($idTitle, 420, 416)
GUISetState()
GUIRegisterMsg(0x0112, "WM_SYSCOMMAND")</p><p>While 1
 Sleep(1)
 If (MouseGetPos(0) > 792 And MouseGetPos(0) < 986 And _IsPressed("01")) Or (MouseGetPos(0) > 662 And MouseGetPos(0) < 790 And _IsPressed("01")) Then
  Local $iWinWait = WinWait("U-KEY签名确认", "", 3)
  If WinExists("U-KEY签名确认") Then
   Local $iWinWaitClose = WinWaitClose("U-KEY签名确认")
   If WinExists("浦发银行网银客户端") Then
    Local $iBlockInput = BlockInput(1)
    Local $EndTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC) + 10 * 1000
    Do
     Local $iWinActivate = WinActivate("浦发银行网银客户端")
     Sleep(500)
     MouseMove(620, 164, 0)
     Sleep(300)
     Local $NowTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC)
    Until MouseGetCursor() = 0 Or $NowTimeTicks >= $EndTimeTicks
    If MouseGetCursor() = 0 Then
     Local $iMouseClick = MouseClick("left", 620, 164, 1, 0)
     Local $iWinWait = WinWait("浦发网银弹窗", "", 5)
     Sleep(300)
     Local $iBlockInput = BlockInput(0)
     Local $ac = WinActivate("浦发网银弹窗")
     If StringLen($sPath) = 3 Then
      _ScreenCapture_CaptureWnd($sPath & 'spdb' & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & ".jpg", $ac)
     Else
      Local $iScrCaptur = _ScreenCapture_CaptureWnd($sPath & "" & 'spdb' & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & ".jpg", $ac)
     EndIf
     Sleep(300)
     Local $iWinClose = WinClose("浦发网银弹窗")
     Local $iBlockInput = BlockInput(1)
     Local $EndTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC) + 5 * 1000
     Do
      WinActivate("浦发银行网银客户端")
      MouseMove(1020, 430, 0)
      Local $NowTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC)
     Until MouseGetCursor() = 0 Or $NowTimeTicks >= $EndTimeTicks
     MouseClick("left", 1020, 430, 1, 0)
     Sleep(300)
     Local $iBlockInput = BlockInput(0)
    Else
     Local $EndTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC) + 5 * 1000
     Do
      MouseMove(1130, 574, 0)
      Local $NowTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC)
     Until MouseGetCursor() = 0 Or $NowTimeTicks >= $EndTimeTicks
     MouseClick("left", 1130, 574, 1, 0)
     Sleep(1500)
     Local $EndTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC) + 5 * 1000
     Do
      MouseMove(1086, 240, 0)
      Local $NowTimeTicks = _TimeToTicks(@HOUR, @MIN, @SEC)
     Until MouseGetCursor() = 0 Or $NowTimeTicks >= $EndTimeTicks
     MouseClick("left", 1086, 240, 1, 0)
     Sleep(100)
     Local $iBlockInput = BlockInput(0)
    EndIf
   EndIf
  EndIf
 EndIf
WEnd</p><p>Func _TimeToTicks($iHours = @HOUR, $iMins = @MIN, $iSecs = @SEC)
 If StringIsInt($iHours) And StringIsInt($iMins) And StringIsInt($iSecs) Then
  Local $iTicks = 1000 * ((3600 * $iHours) + (60 * $iMins) + $iSecs)
  Return $iTicks
 Else
  Return SetError(1, 0, 0)
 EndIf
EndFunc   ;==>_TimeToTicks</p><p>Func _IsPressed($sHexKey, $vDLL = "user32.dll")
 Local $aCall = DllCall($vDLL, "short", "GetAsyncKeyState", "int", "0x" & $sHexKey)
 If @error Then Return SetError(@error, @extended, False)
 Return BitAND($aCall[0], 0x8000) <> 0
EndFunc   ;==>_IsPressed</p><p>Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam) 
 Local $iID = BitAND($wParam, 0xFFFF) 
 If ($iID = 0xF060) Then 
  Exit
 EndIf
EndFunc   ;==>WM_SYSCOMMAND

</p>

 楼主| 发表于 2022-4-7 11:04:44 | 显示全部楼层
本帖最后由 smooth 于 2022-4-7 11:54 编辑

找到根源了,是这句代码惹的祸。我本来的想法是,鼠标按下之后,怕窗口还没出现,代码就继续往下执行了,所以加了这句。

但是很奇怪,为什么下面的 WinWaitClose,同样是等待窗口出现,为什么这句就不影响呢?

还有,不是需要If的条件满足之后,才会执行到WinWait("U-KEY签名确认", "", 3)这句代码吗?为什么这句代码,能影响到上一句代码?

  Local $iWinWait = WinWait("U-KEY签名确认", "", 3)
发表于 2022-4-7 11:55:49 | 显示全部楼层
我今天是来喷楼主的


发贴时代码不知道好好排排版么,别人复制下来一堆排版错误,你这是发bug呢,还是发bug呢,还是发bug呢?
发贴求助,也要考虑一下那些愿意帮助你的人看代码的感受。



想起前段时间你跟我说过的话,说啥以后再也不用au3了,本来我连喷的欲望都没有了。
但有些话不吐不快,其实au3并没有你想象的那么弱,自己写不好代码,别怪语言,和au3关系真的不大。
自己拉不出屎来,就怪地球没引力么?


也提醒一下其他总是挑au3毛病的人,au3能xxxx吗?au3可不可以xxxx?au3用户量不大,很小众,xxxx。。。。
怼一下,我想问问一个语言你用不用,是要看用户量才去使用的么,如果是,请直接去使用其他语言,纠结au3干什么?
在不同的场景下,能合理的使用你熟悉的语言,就已经很不错了。
另外提问问题时,别动不动就带上au3能XXXX吗?提问之前先考虑这个问题和语言有关系么。
如果你用其他语言写同样的代码可以正常运行,au3写出来不行话,再考虑是au3的问题。
如果根本思路都不通,就别这样提问,感觉是来找茬的。

拿楼主的代码举例,就按照楼主的写法,用其他语言会出现同样的问题。
最后说说楼主的问题:
不是_IsPressed响应不到你的鼠标左键。你在主循环放那么多Sleep,而且放在了一个可能要持续10秒钟的循环里,能实时响应到你的鼠标动作才是不正常。

这么长的代码是最简化?你把里面的Sleep和do Until 都去掉再测试。
发表于 2022-4-7 12:14:49 | 显示全部楼层
haijie1223 发表于 2022-4-7 11:55
我今天是来喷楼主的

严重支持下阿杰
 楼主| 发表于 2022-4-7 12:34:32 | 显示全部楼层
本帖最后由 smooth 于 2022-4-7 13:12 编辑
haijie1223 发表于 2022-4-7 11:55
我今天是来喷楼主的

1、我这里能运行,没有报错信息出来,看下面的截图。
2、导致不能响应_ispressed函数的问题,我已经测出来了,和sleep,do until没关系。
3、关于排版,我不明白你说的是什么意思,我脚本里是排好的,复制到论坛就变成这样了,可能是我对论坛的编辑了解太少了。
4、关于我说不用AU3,我说是因为我要准备考试,没时间玩了。现在是因为有问题没有解决,我没有说过因为AU3弱不玩了,见下图。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2022-4-7 16:25:48 | 显示全部楼层
smooth 发表于 2022-4-7 12:34
1、我这里能运行,没有报错信息出来,看下面的截图。
2、导致不能响应_ispressed函数的问题,我已经测出 ...

好吧,我再次败下阵来
发表于 2022-4-7 16:28:22 | 显示全部楼层
afan 发表于 2022-4-7 12:14
严重支持下阿杰

失态失态~见笑了
发表于 2022-4-8 12:55:53 | 显示全部楼层
注册WM_KEYUP试试
 楼主| 发表于 2022-4-8 13:25:40 | 显示全部楼层
tubaba 发表于 2022-4-8 12:55
注册WM_KEYUP试试

谢谢大佬,这个问题我解决了。另外一个帖子https://www.autoitx.com/thread-72926-1-1.html,就注册了你说的WM_KEYUP,到了后面不知道怎么处理$WM_COPY消息,方便的话帮忙看一下,谢谢!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-4 04:25 , Processed in 0.080699 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表