Razi Posted February 19, 2023 Posted February 19, 2023 (edited) Can you help solve the problem in code? The problem is that in the following code, when I press backspace in any Input control or any other keyboard button, the value is returned back. For example: when I want to change the value 127 in the input control and I erase the number 7 with the backspace button, the number becomes 127 again. But I need the number to change when any keyboard button is pressed. expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Include <Timers.au3> #Include <WinAPIEx.au3> #include <Misc.au3> #Region ### START Koda GUI section ### Form= Local $Form1 = GUICreate("Form1", 658, 401, 192, 124) Local $aInput[135], $c = 0 Global $nMsg For $y = 0 To 8 For $a = 0 To 14 $aInput[$c] = GUICtrlCreateInput('Input' & $a+1 + $y*15, 26+$y*53, 31+$a*22 , 52, 21) $c += 1 Next Next Global $timedelay = _Timer_Init() ;Start delay timer GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Global $timersec = 2000 While 1 $nMsg = GUIGetMsg() local $inp = $nMsg - $aInput[0] Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $aInput[0] To $aInput[UBound($aInput) - 1] $timersec = 3600000 ConsoleWrite($timersec & @CRLF) ConsoleWrite($inp & @CRLF) $val = Number(GUICtrlRead($nMsg)) If $val <> 0 And _IsPressed("0D") Then $val = Number(GUICtrlRead($nMsg)) local $inp = $nMsg - $aInput[0] GUICtrlSetData($aInput[$inp], $inp) ConsoleWrite($val & @CRLF) $timersec = 2000 EndIf ;ConsoleWrite("Input " & $nMsg - $aInput[0] & " has been modified" & @CRLF) EndSwitch If _Timer_Diff($timedelay) > $timersec Then For $x = 0 To 134 GUICtrlSetData($aInput[$x], $x) Next $timedelay = _Timer_Init() ;Reset delay timer EndIf WEnd Func WM_COMMAND($hWinHandle, $iMsg, $wParam, $lParam) If _WinAPI_HiWord($wParam) = $EN_CHANGE Then Switch _WinAPI_LoWord($wParam) Case $aInput[0] To $aInput[UBound($aInput) - 1] local $inp = $nMsg - $aInput[0] ConsoleWrite($inp & @CRLF) EndSwitch EndIf EndFunc Without changing the following part of the code: If _Timer_Diff($timedelay) > $timersec Then For $x = 0 To 134 local $number = 132* Int($x / 15) + Mod($x,15) GUICtrlSetData($aInput[$x], $x) Next $timedelay = _Timer_Init() ;Reset delay timer EndIf In general, I want to pause the timer when any button on the keyboard was pressed in any Input GUI control, but the code manages to execute this part of the code: GUICtrlSetData($aInput[$x], $x) , although it should not execute it after pressing the keyboard button in any Input GUI control. Edited February 19, 2023 by Razi
ioa747 Posted February 19, 2023 Posted February 19, 2023 To tell the truth, I didn't really understand what exactly the script does, but I know that here you had to calculate an offset , Maybe other things need adjusting in the line Case $aInput[0] To $aInput[UBound($aInput) - 1] you have to calculate one offset, in this case + 3 , because the $aInput[0] = GUIGetMsg() = 3 expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Include <Timers.au3> #Include <WinAPIEx.au3> #include <Misc.au3> #include <Debug.au3> #Region ### START Koda GUI section ### Form= Local $Form1 = GUICreate("Form1", 658, 401, 192, 124) Local $aInput[135], $c = 0 Global $nMsg For $y = 0 To 8 For $a = 0 To 14 $aInput[$c] = GUICtrlCreateInput('Input' & $a+1 + $y*15, 26+$y*53, 31+$a*22 , 52, 21) $c += 1 Next Next ConsoleWrite("you have to calculate one offset, in this case +" & $aInput[0] & @CRLF) Global $timedelay = _Timer_Init() ;Start delay timer GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Global $timersec = 2000 While 1 $nMsg = GUIGetMsg() local $inp = $nMsg - $aInput[0] Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $aInput[0] + 3 To $aInput[0] + 3 + $aInput[UBound($aInput) - 1] ;if $nMsg = $aInput[0] + 3 $timersec = 3600000 ConsoleWrite($timersec & @CRLF) ConsoleWrite($inp & @CRLF) ConsoleWrite("$nMsg=" & $nMsg & @CRLF) $val = Number(GUICtrlRead($nMsg)) If $val <> 0 And _IsPressed("0D") Then $val = Number(GUICtrlRead($nMsg)) local $inp = $nMsg - $aInput[0] GUICtrlSetData($aInput[$inp], $inp) ;~ ConsoleWrite($val & @CRLF) $timersec = 2000 EndIf ;ConsoleWrite("Input " & $nMsg - $aInput[0] & " has been modified" & @CRLF) EndSwitch If _Timer_Diff($timedelay) > $timersec Then For $x = 0 To 134 GUICtrlSetData($aInput[$x], $x) Next $timedelay = _Timer_Init() ;Reset delay timer EndIf WEnd Func WM_COMMAND($hWinHandle, $iMsg, $wParam, $lParam) If _WinAPI_HiWord($wParam) = $EN_CHANGE Then Switch _WinAPI_LoWord($wParam) Case $aInput[0] To $aInput[UBound($aInput) - 1] local $inp = $nMsg - $aInput[0] ;~ ConsoleWrite($inp & @CRLF) EndSwitch EndIf EndFunc I know that I know nothing
mistersquirrle Posted February 19, 2023 Posted February 19, 2023 I also am a bit confused on what your goal is, but I think that the issue is you default to resetting all values every 2 seconds. Every time you press Backspace, you're saying that if your timer was started more than 2 seconds ago, do your GUICtrlSetData($aInput[$x], $x). Add some logging to your TimerDiff section and you can see when that happens. Also, why are you using <Timers.au3> instead of the normal TimerInit() and TimerDiff()? So, why are you setting $timersec = 3600000 and then if Backspace is pressed, back down to $timersec = 2000? You're enabling it so that if you press backspace in 2s or less (since the timer is already running, the timer is not reset, only its goal was changed) it'll reset all values. I think I have something closer to what you want. As long as you type something in a box every < 2s it will not replace all values to default. If you take longer than 2s, it'll replace everything back to default. expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Timers.au3> #include <WinAPIEx.au3> #include <Misc.au3> #include <Debug.au3> #Region ### START Koda GUI section ### Form= Local $Form1 = GUICreate("Form1", 658, 401, 192, 124) Local $aInput[135], $c = 0 Global $nMsg For $y = 0 To 8 For $a = 0 To 14 $aInput[$c] = GUICtrlCreateInput('Input' & $a + 1 + $y * 15, 26 + $y * 53, 31 + $a * 22, 52, 21) $c += 1 Next Next ConsoleWrite("you have to calculate one offset, in this case +" & $aInput[0] & @CRLF) Global $timedelay = _Timer_Init() ;Start delay timer GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Global $timersec = 2000 While 1 $nMsg = GUIGetMsg() Local $inp = $nMsg - $aInput[0] Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $aInput[0] + 3 To $aInput[0] + 3 + $aInput[UBound($aInput) - 1] ;if $nMsg = $aInput[0] + 3 ;~ $timersec = 3600000 ;~ ConsoleWrite($timersec & @CRLF) ; There's no point in logging this, you just set it to 3600000 ;~ ConsoleWrite($inp & @CRLF) ;~ ConsoleWrite("$nMsg=" & $nMsg & @CRLF) $val = Number(GUICtrlRead($nMsg)) ;~ ConsoleWrite('$val (GUICtrlRead($nMsg)): ' & $val & @CRLF) ;~ If $val <> 0 And _IsPressed("0D") Then ;~ $val = Number(GUICtrlRead($nMsg)) ;~ Local $inp = $nMsg - $aInput[0] ;~ GUICtrlSetData($aInput[$inp], $inp) ;~ ConsoleWrite($val & @CRLF) ;~ $timersec = 2000 ;~ EndIf ;ConsoleWrite("Input " & $nMsg - $aInput[0] & " has been modified" & @CRLF) EndSwitch If _Timer_Diff($timedelay) > $timersec Then ConsoleWrite('_Timer_Diff($timedelay): ' & Round(_Timer_Diff($timedelay), 2) & ', $timersec: ' & $timersec & @CRLF) For $x = 0 To 134 GUICtrlSetData($aInput[$x], $x) Next $timedelay = _Timer_Init() ;Reset delay timer EndIf WEnd Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local $nNotifyCode = _WinAPI_HiWord($wParam) Local $iId = _WinAPI_LoWord($wParam) Local $hCtrl = $lParam If $nNotifyCode = $EN_CHANGE Then ConsoleWrite('$nNotifyCode = $EN_CHANGE, $hCtrl: ' & $hCtrl & ', $iId: ' & $iId & @CRLF) Switch $iId Case $aInput[0] To $aInput[UBound($aInput) - 1] ;~ Local $inp = $nMsg - $aInput[0] + 3 If _IsPressed("0D") <> 1 Then $timedelay = _Timer_Init() ;Reset delay timer ;~ ConsoleWrite($inp & @CRLF) EndSwitch EndIf EndFunc ;==>WM_COMMAND We ought not to misbehave, but we should look as though we could.
Razi Posted February 19, 2023 Author Posted February 19, 2023 (edited) 4 hours ago, ioa747 said: I didn't really understand what exactly the script does I want the timer to stop when I press any keyboard button in the input field and not reset the value. 3 hours ago, mistersquirrle said: why are you setting $timersec = 3600000 This gives the effect of a timer pause and the values in the input fields are not reset (not updated). Here, I want to stop updating the values. 3 hours ago, mistersquirrle said: then if Backspace is pressed, back down to $timersec = 2000? If _IsPressed("0D") Then : When the "Enter" button is pressed, then update the values every 2 seconds again. I wanted to achieve an effect when I press any button in the input field, then do not update the values. And when I press the "Enter" button, then update the values again. But for some reason this condition is executed (If _Timer_Diff($timedelay) > $timersec Then) , although it should not be executed, after pressing any button. I don't know if this function is needed at all: Func WM_COMMAND($hWinHandle, $iMsg, $wParam, $lParam) Edited February 19, 2023 by Razi
mistersquirrle Posted February 19, 2023 Posted February 19, 2023 1 minute ago, Razi said: If _IsPressed("0D") Then : When the "Enter" button is pressed, then update the values every 2 seconds again. My mistake, I knew it was Enter but I got it confused with your comments about backspace so mixed them up. 2 minutes ago, Razi said: I want the timer to stop when I press any keyboard button in the input field and not reset the value. Did you try the code that I posted? That's exactly what it does in mine 2 minutes ago, Razi said: This gives the effect of a timer pause and the values in the input fields are not reset (not updated). Here, I want to stop updating the values. Setting $timersec = 3600000 (aka 1 hour) does NOT pause the timer, it only extends the time until the timer reaches it goal. If you want to actually 'pause' the timer, you need to just set $timedelay = 0 (destroys the timer), and when you want to 'unpause' the timer, set it to $timedelay = _Timer_Init(). This way you can keep your $timersec to the value you want and have a better 'pause' on the timer. For a more accurate pause, you'd want to do something like this: expandcollapse popup#include-once #include <Timers.au3> Global $ghTimer Global $giPauseTime, $giCount = 0 Global $giTimerTimeoutMs = 2 * 1000 Global $giTimerUnpausedTime = $giTimerTimeoutMs Global $ghTotalTimer = TimerInit() ; Used to track the total time _StartTimer($ghTimer) Sleep(100) ConsoleWrite('$ghTimer after 100 ms: ' & Round(_Timer_Diff($ghTimer), 2) & ' ms' & @CRLF) Sleep(1000) ConsoleWrite('$ghTimer after additional 1000 ms: ' & Round(_Timer_Diff($ghTimer), 2) & ' ms' & @CRLF) _PauseTimer($ghTimer) Sleep(1000) _ResumeTimer($ghTimer) ConsoleWrite('$ghTimer after paused for 1000 ms: ' & Round(_Timer_Diff($ghTimer), 2) & ' ms, time remaining after pause: ' & $giTimerUnpausedTime & @CRLF) Do Sleep(10) $giCount += 1 If Mod($giCount, 10) = 0 Then ConsoleWrite('$ghTimer waiting until ' & Ceiling($giTimerUnpausedTime) & ': ' & Round(_Timer_Diff($ghTimer), 2) & ' ms' & @CRLF) Until _Timer_Diff($ghTimer) >= $giTimerUnpausedTime ConsoleWrite('Total time to run: ' & Round(TimerDiff($ghTotalTimer), 2) & ' ms' & @CRLF) Func _PauseTimer(ByRef $hTimer) Local $iTimerMs = _Timer_Diff($hTimer) $giTimerUnpausedTime = $giTimerUnpausedTime - $iTimerMs ConsoleWrite('Timer paused at: ' & Round($iTimerMs, 2) & ' ms, time remaining: ' & $giTimerUnpausedTime & @CRLF) $hTimer = 0 ; Destory/stop the timer Return $giTimerUnpausedTime EndFunc ;==>_PauseTimer Func _ResumeTimer(ByRef $hTimer) $hTimer = _Timer_Init() Return 1 EndFunc ;==>_ResumeTimer Func _StartTimer(ByRef $hTimer) $hTimer = _Timer_Init() $giTimerUnpausedTime = $giTimerTimeoutMs EndFunc ;==>_StartTimer But I don't think that you want to actually 'pause' the timer, it would make more sense to reset the timer on interaction, in my opinion. That's what my code in the previous post was doing. We ought not to misbehave, but we should look as though we could.
Razi Posted February 20, 2023 Author Posted February 20, 2023 (edited) 19 hours ago, mistersquirrle said: Did you try the code that I posted? Yes, I tried, but the code just resets $timedelay to zero. I need when at least 1 button was pressed in Input field, then stop/pause timer. I just want to change value in Input field, for that I need to stop updating the values. And start to update values after "Enter" button was pressed in Input field. 19 hours ago, mistersquirrle said: you need to just set $timedelay = 0 (destroys the timer) Unfortunately, it didn't help. Or I don't know where to paste it. Why the developers of Autoit didn't included the stop/pause timer function? It's so inconvenient to use a timer. On 2/19/2023 at 7:33 PM, ioa747 said: you have to calculate one offset, in this case + 3 , because the $aInput[0] = GUIGetMsg() = 3 Thanks, that's a helpful note. Edited February 20, 2023 by Razi
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now