找回密码
 加入
搜索
查看: 1812|回复: 2

[网络通信] Settimer中持续按住鼠标按键实现[已解决]

[复制链接]
发表于 2019-2-26 10:40:23 | 显示全部楼层 |阅读模式
本帖最后由 overrainy 于 2019-3-4 13:22 编辑

一个自动按键的小脚本,使用settimer定时触发器,按键都可以没有什么问题,但是想要实现鼠标左右键持续按住,不管使用mousedown+sleep+mouseup还是使用Opt("MouseClickDownDelay",xx)都不能实现持续按键。请教一下大神。示例代码如下。
#Region ACN预处理程序参数(常用参数)
#PRE_Icon=                                                                                 ;图标,支持EXE,DLL,ICO
#PRE_OutFile=                                                                        ;输出文件名
#PRE_OutFile_Type=exe                                                        ;文件类型
#PRE_Compression=4                                                                ;压缩等级
#PRE_UseUpx=y                                                                         ;使用压缩
#PRE_Res_Comment=                                                                 ;程序注释
#PRE_Res_Description=                                                        ;详细信息
#PRE_Res_Fileversion=1.0.0.4
#PRE_Res_FileVersion_AutoIncrement=p                        ;自动更新版本
#PRE_Res_LegalCopyright=                                                 ;版权
#PRE_Change2CUI=N                                           ;修改输出的程序为CUI(控制台程序)
;#PRE_Res_Field=AutoIt Version|%AutoItVer%                ;自定义资源段
;#PRE_Run_Tidy=                                                   ;脚本整理
;#PRE_Run_Obfuscator=                                                      ;代码迷惑
;#PRE_Run_AU3Check=                                                         ;语法检查
;#PRE_Run_Before=                                                                 ;运行前
;#PRE_Run_After=                                                                ;运行后
;#PRE_UseX64=n                                                                        ;使用64位解释器
;#PRE_Compile_Both                                                                ;进行双平台编译
#EndRegion ACN预处理程序参数设置完成
#cs ____________________________________

 Au3 版本:
 脚本作者:
 电子邮件:
        QQ/TM:
 脚本版本:
 脚本功能:

#ce _______________脚本开始_________________

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
;Global $Paused
HotKeySet("{PAUSE}", "Terminate")
Global $flag = 0
Global $Pid = 0
Global $paused = 0
Global $hWnd_1

Example()

Func Example()
    ; Create a GUI with various controls.
    Global $hGUI = GUICreate("Game", 400, 400)

    ; Create a checkbox control.
        Global $iCheckbox_4 = GUICtrlCreateCheckbox("Mouse Left", 10, 160, 100, 25)
        Global $iCheckbox_5 = GUICtrlCreateCheckbox("Mouse Right", 10, 190, 100, 25)

        Global $Column_2 = GUICtrlCreateLabel("Key", 120, 10, 90, 25)
        Global $Input_Key_4 = GUICtrlCreateLabel("Mouse Left", 120, 170, 90, 25)
        Global $Input_Key_5 = GUICtrlCreateLabel("Mouse Right", 120, 200, 90, 25)

        Global $Column_3 = GUICtrlCreateLabel("Delay (ms)", 240, 10, 90, 25)
        Global $Input_Delay_4 = GUICtrlCreateInput("1000", 240, 160, 90, 25)
        Global $Input_Delay_5 = GUICtrlCreateInput("1000", 240, 190, 90, 25)

        Global $Process_Label = GUICtrlCreateLabel("Process", 10, 220, 200, 25)
        Global $Process_Input = GUICtrlCreateInput("*****.exe", 10, 250, 200, 25)

        Global $Tip = GUICtrlCreateLabel("Start开始脚本,Break Pause暂停继续脚本.", 10, 280, 390, 25)
        Global $Tip_1 = GUICtrlCreateLabel("", 10, 310, 390, 25)

    Global $iClose = GUICtrlCreateButton("Close", 310, 370, 85, 25)
        Global $Start = GUICtrlCreateButton("Start", 310, 340, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    While 1
        Switch GUIGetMsg()
                        Case $GUI_EVENT_CLOSE, $iClose
                                IniWrite("DefineKeyboard.ini", "Key", "mouse left", GUICtrlRead($Input_Delay_4))
                                IniWrite("DefineKeyboard.ini", "Key", "mouse right", GUICtrlRead($Input_Delay_5))
                ExitLoop
                        Case $Start
                                $flag = 0
                                _IsCheckedProcessExists(GUICtrlRead($Process_Input))
                                GUICtrlSetState($Start, $GUI_DISABLE)
                                GUICtrlSetState($iClose, $GUI_DISABLE)
                                $hWnd_1 = _ProcessGetHWnd($Pid)
                                If $hwnd_1 = 0 Then
                                        MsgBox(0,"Info", "未找到窗口")
                                Else
                                        _Start()
                                EndIf
        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _Start()
        GUICtrlSetData($Tip_1, "脚本运行中...")
        ;MsgBox(4096, "Info", "脚本开始!", 1)
        $paused = Not $paused
        ConsoleWrite('Start pause: '&$paused&@CRLF)
        Global $pTimerProc5 = DLLCallbackRegister("_TimerProc","int","hwnd;uint;uint;dword")
        Global $uiTimer5 =  DllCall("user32.dll",  "uint",  "SetTimer",  "hwnd",  0,  "uint",  0,  "int",  GUICtrlRead($Input_Delay_4),  "ptr",  DllCallbackGetPtr ($pTimerProc5))
        Global $pTimerProc6 = DLLCallbackRegister("_TimerProc","int","hwnd;uint;uint;dword")
        Global $uiTimer6 =  DllCall("user32.dll",  "uint",  "SetTimer",  "hwnd",  0,  "uint",  0,  "int",  GUICtrlRead($Input_Delay_5),  "ptr",  DllCallbackGetPtr ($pTimerProc6))

        While 1
                If $flag <> 0 Then
                DllCall("user32.dll",  "int",  "KillTimer",  "hwnd",  0,  "uint",  $uiTimer5[0])
                DllCallbackFree  ($pTimerProc5)
                DllCall("user32.dll",  "int",  "KillTimer",  "hwnd",  0,  "uint",  $uiTimer6[0])
                DllCallbackFree  ($pTimerProc6)
                ExitLoop
                EndIf
        WEnd
        ;MsgBox(0, "提示", "脚本已结束,要重新开始请按Start.", 1)
        $paused = Not $paused
        GUICtrlSetData($Tip_1, "脚本已停止")
EndFunc

Func _TimerProc($hWnd,  $uiMsg,  $idEvent,  $dwTime)
     ;$idEvent能分辨是哪个Timer控件调用了这个函数
     ;$dwTime表示已开机的时间
     Switch  $idEvent
                 Case $uiTimer5[0]
                        If _IsChecked($iCheckbox_4) Then
                                ;;!!!!!!!!!!!!!!!使用mouseclikcdowndelay 无法实现鼠标左键持续按键
                                Opt("MouseClickDownDelay", GUICtrlRead($Input_Key_4))
                                MouseClick($MOUSE_CLICK_LEFT)
                                Opt("MouseClickDownDelay", 10)
                                ;ControlSend($hWnd_1, "", "", GUICtrlRead($Input_Key_3))
                        EndIf
                 Case $uiTimer6[0]
                        If _IsChecked($iCheckbox_5) Then
                                ;;!!!!!!!!!!!!!!!使sleep也无法实现鼠标右键持续按键
                                MouseDown($MOUSE_CLICK_RIGHT)
                                Sleep(GUICtrlRead($Input_Key_5))
                                MouseUp($MOUSE_CLICK_RIGHT)
                                ;ControlSend($hWnd_1, "", "", GUICtrlRead($Input_Key_3))
                        EndIf
     EndSwitch
EndFunc

Func _IsChecked($iControlID)
    Return BitAND(GUICtrlRead($iControlID), $GUI_CHECKED) = $GUI_CHECKED
EndFunc   ;==>_IsChecked

Func _IsCheckedProcessExists($Process)
        If (ProcessExists($Process) = 0) Then
                MsgBox(0, "Error", "进程不存在!")
                Exit
        Else
                $pid = ProcessExists($Process)
        EndIf
EndFunc


Func Terminate()
        ConsoleWrite('Pause: '&$paused&'        Flag: '&$flag&@CRLF)
        If $paused = 1 Then
                GUICtrlSetState($Start, $GUI_ENABLE)
                GUICtrlSetState($iClose, $GUI_ENABLE)
                $flag = 1
        Else
                GUICtrlSetState($Start, $GUI_DISABLE)
                GUICtrlSetState($iClose, $GUI_DISABLE)
                $flag = 0
                _IsCheckedProcessExists(GUICtrlRead($Process_Input))
                $hWnd_1 = _ProcessGetHWnd($Pid)
                If $hwnd_1 = 0 Then
                        MsgBox(0,"Info", "未找到窗口")
                Else
                        _Start()
                EndIf
        EndIf
EndFunc

Func _ProcessGetHWnd($iPid, $iOption = 1, $sTitle = "", $iTimeout = 2000)
        Local $aReturn[1][1] = [[0]], $aWin, $hTimer = TimerInit()

        While 1

                ; Get list of windows
                $aWin = WinList()
                ;_ArrayDisplay($aWin)
                ; Searches thru all windows
                For $i = 1 To $aWin[0][0]

                        ; Found a window owned by the given PID
                        If $iPid = WinGetProcess($aWin[$i][1]) Then

                                ; Option 0 or 1 used
                                If $iOption = 1 OR ($iOption = 0 And $aWin[$i][0] <> "") Then
                                        Return $aWin[$i][1]

                                ; Option 2 is used
                                ElseIf $iOption = 2 Then
                                        ReDim $aReturn[UBound($aReturn) + 1][2]
                                        $aReturn[0][0] += 1
                                        $aReturn[$aReturn[0][0]][0] = $aWin[$i][0]
                                        $aReturn[$aReturn[0][0]][1] = $aWin[$i][1]
                                EndIf
                        EndIf
                Next

                ; If option 2 is used and there was matches then the list is returned
                If $iOption = 2 And $aReturn[0][0] > 0 Then Return $aReturn

                ; If timed out then give up
                If TimerDiff($hTimer) > $iTimeout Then ExitLoop

                ; Waits before new attempt
                Sleep(Opt("WinWaitDelay"))
        WEnd


        ; No matches
        SetError(1)
        Return 0
EndFunc
关键代码部分如下:
在settimer中无法使用sleep类似的方法实现鼠标持续按键。
Switch  $idEvent
                 Case $uiTimer5[0]
                        If _IsChecked($iCheckbox_4) Then
                                ;;!!!!!!!!!!!!!!!使用mouseclikcdowndelay 无法实现鼠标左键持续按键
                                Opt("MouseClickDownDelay", GUICtrlRead($Input_Key_4))
                                MouseClick($MOUSE_CLICK_LEFT)
                                Opt("MouseClickDownDelay", 10)
                                ;ControlSend($hWnd_1, "", "", GUICtrlRead($Input_Key_3))
                        EndIf
                 Case $uiTimer6[0]
                        If _IsChecked($iCheckbox_5) Then
                                ;;!!!!!!!!!!!!!!!使sleep也无法实现鼠标右键持续按键
                                MouseDown($MOUSE_CLICK_RIGHT)
                                Sleep(GUICtrlRead($Input_Key_5))
                                MouseUp($MOUSE_CLICK_RIGHT)
                                ;ControlSend($hWnd_1, "", "", GUICtrlRead($Input_Key_3))
                        EndIf
     EndSwitch
求大神提示一下,应该怎么在定时器中实现鼠标的持续按键。感谢~
发表于 2019-3-4 01:51:15 | 显示全部楼层
鼠标的按下和释放函数是OK的,你代码无法正确工作的原因是你读错了控件。
延迟1000毫秒的控件名是:
$Input_Delay_4 = GUICtrlCreateInput("1000", 240, 160, 90, 25)
你代码去读的控件是:$Input_Key_4
$Input_Key_4读取到的值应该是:Mouse Left
结果就变成了
Sleep("Mouse Left")
因为字符串的值等于零。
执行结果就是
Sleep(0)
自然鼠标无法持续按下。
 楼主| 发表于 2019-3-4 13:22:09 | 显示全部楼层
测试了一下是可以的,前提是延迟的时间要小于定时时间。关问题喽
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-11-16 12:39 , Processed in 0.068134 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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