radioguy Posted May 12, 2020 Share Posted May 12, 2020 Hello, I'm relatively new to AutoIT having made a handful of scripts over the past couple of years. I was introduced to AutoIT by one of my co-workers. I'm working on a script that triggers countdown timers on an external system (using UDP sockets--works great!) and triggers a local countdown timer (h/t to user Wakillon for the base of the countdowntimer script, which I've modified for my purposes). The local timer part works fine from a countdown perspective. It counts down, reverts to the entry window, then counts down again when re-triggered. In the case that someone enters the wrong time I have scripted the countdown timer to be "close-able" via a GUI_EVENT_CLOSE command, which then clears the timer (and the external system when fully functional), then returns to the entry interface. This works great the first time... The problem is that if I loop through this again, the attempt to close the countdown timer again--the second time it doesn't close the countdown window--instead, it waits for the countdown to finish then closes the entry window. I've attached the code (instead of exiting I have message box popups to confirm which part of the script the GUI_EVENT_CLOSE is accessing). So far I'm stumped. I've tried "GUISwitch", removing the old GUI, hiding/removing the countdown GUI, and everything else in between. I'm guessing this has something to do with interrupting the "While 1" loop in the "ComputercountDown()" function, but I haven't figured out a way to do that. I've left my comments in line but removed the parts that "work". the script does function (and, by extension fail) as has been copied here. Hopefully this is clear. I'm sure the fix is probably something obvious. Any advice would be appreciated. Thanks! EDIT FOR INTERNET.au3 Link to comment Share on other sites More sharing options...
radioguy Posted May 12, 2020 Author Share Posted May 12, 2020 1 minute ago, radioguy said: Hello, I'm relatively new to AutoIT having made a handful of scripts over the past couple of years. I was introduced to AutoIT by one of my co-workers. I'm working on a script that triggers countdown timers on an external system (using UDP sockets--works great!) and triggers a local countdown timer (h/t to user Wakillon for the base of the countdowntimer script, which I've modified for my purposes). The local timer part works fine from a countdown perspective. It counts down, reverts to the entry window, then counts down again when re-triggered. In the case that someone enters the wrong time I have scripted the countdown timer to be "close-able" via a GUI_EVENT_CLOSE command, which then clears the timer (and the external system when fully functional), then returns to the entry interface. This works great the first time... The problem is that if I loop through this again, the attempt to close the countdown timer again--the second time it doesn't close the countdown window--instead, it waits for the countdown to finish then closes the entry window. I've attached the code (instead of exiting I have message box popups to confirm which part of the script the GUI_EVENT_CLOSE is accessing). So far I'm stumped. I've tried "GUISwitch", removing the old GUI, hiding/removing the countdown GUI, and everything else in between. I'm guessing this has something to do with interrupting the "While 1" loop in the "ComputercountDown()" function, but I haven't figured out a way to do that. I've left my comments in line but removed the parts that "work". the script does function (and, by extension fail) as has been copied here. Hopefully this is clear. I'm sure the fix is probably something obvious. Any advice would be appreciated. Thanks! EDIT FOR INTERNET.au3 4.3 kB · 0 downloads Sorry, I though the attachment would display the code. expandcollapse popup;;Includes #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <WinAPIFiles.au3> #include <WindowsConstants.au3> Global $SS_CENTER Global $_CountdownTime Global $_Minutes Global $_Seconds Global $TimeTicks Global $TimeLabel Global $_GuiCountDown Global $EnterMinutes Global $EnterSeconds Global $StartButton Global $Minutes Global $Seconds Global $_GuiEnterTime Dim $aPanelCSV[0] ;Main function to trigger everything Main() Func Main() EnterTimeGUI() EnterTime() EndFunc Func PanelCount() ;stuff that works in the real script EndFunc ;Primary function for entering in the countdown duration Func EnterTimeGUI() ;;Create a GUI $_GuiEnterTime = GUICreate ( "Enter Start Time", 300, 150) Opt("GUIOnEventMode", 0) GUISetBkColor ( 0xFFFFFF ) GUISetFont(10,0,0) $EnterLabel = GUICtrlCreateLabel ( "Minutes", 100,15,100,35) $EnterLabel = GUICtrlCreateLabel ( "Seconds", 160,15,100,35) GUISetFont(13.5,0,0) $EnterMinutes = GUICtrlCreateInput ("",105,35,45,35,$ES_NUMBER) $EnterSeconds = GUICtrlCreateInput ("",155,35,45,35,$ES_NUMBER) GUISetFont(12,0,0) $StartButton = GUICtrlCreateButton ("Start",110,80,80,50) GUISetState (@SW_SHOW,$_GuiEnterTime) EndFunc Func EnterTime() GUISetState (@SW_SHOW,$_GuiEnterTime) Opt("GUIOnEventMode", 0) While 1 $MSG = GUIGetMsg() Select Case $MSG = $GUI_EVENT_CLOSE ;Exit MsgBox(4000,"DEBUG: Enter Time","enter time close button pressed") ;;Start button for countdown Case $MSG = $StartButton $Minutes = GUICtrlRead($EnterMinutes) $Seconds = GUICtrlRead($EnterSeconds) ;Math for the WallTime and local countdown functions $Paneltime = (((60 * $Minutes) + $Seconds)) $_CountdownTime =(((60000 * $Minutes) + (1000 * $Seconds))+1000) Sleep(100) GUISetState (@SW_HIDE,$_GuiEnterTime) ;;Function starts the countdown timer on the WallTime panels PanelCountDown() ;;starts the function for local countdown CountDownGUI() ComputerCountDown() EndSelect WEnd EndFunc #cs Local countdown--this was mostly taken from Wakillon's post in April of 2011, then modified for my use case. Full credit to Wakillon for this part. https://www.autoitscript.com/forum/topic/127667-how-to-create-a-countdown-timer-in-autoit/ #ce Func CountDownGUI() ;;Countdown GUI $_GuiCountDown = GUICreate ( "CountDown...", 500, 200, @DesktopWidth/2 -250, @DesktopHeight/2 -100) GUISwitch ($_GuiCountDown) Opt("GUIOnEventMode", 1) GUISetOnEvent($GUI_EVENT_CLOSE, "StopCountdown") GUISetBkColor ( 0xFFFFFF ) $TimeLabel = GUICtrlCreateLabel ( "", 35, -10, 480, 180, $SS_CENTER ) GUICtrlSetFont ( -1, 125, 800 ) GUISetState (@SW_SHOW,$_GuiCountDown) ;WinSetOnTop ( $_GuiCountDown, "", 1 ) $TimeTicks = TimerInit ( ) EndFunc Func ComputerCountDown() While 1 ;;calls the function to begin the countdown Check ( ) Sleep (200) WEnd EndFunc Func Check ( ) $_CountdownTime -= TimerDiff ( $TimeTicks ) $TimeTicks = TimerInit ( ) Local $_MinCalc = Int ( $_CountdownTime / ( 60 * 1000 ) ), $_SecCalc = $_CountdownTime - ( $_MinCalc * 60 * 1000 ) $_SecCalc = Int ( $_SecCalc / 1000 ) If $_MinCalc <= 0 And $_SecCalc <= 0 Then ;;steps through one second at a time Sleep ( 250 ) ;;when it's done it removes the GUI and goes back to the entry interface GUIDelete ($_GuiCountDown) EnterTime() Else ;;changes colors of the GUI for the last 10 seconds If $_MinCalc <> $_Minutes Or $_SecCalc <> $_Seconds Then $_Minutes = $_MinCalc $_Seconds = $_SecCalc GUICtrlSetData ( $TimeLabel, StringFormat ( "%02u" & ":" & "%02u", $_Minutes, $_Seconds ) ) If $_Minutes = 0 And $_Seconds <= 10 Then GUISetBkColor ( 0xA093FF, $_GuiCountDown ) EndIf EndIf EndIf EndFunc Func PanelCountdown() ;;this part works fine, part of an external system I'm triggering via UDP sends EndFunc Func StopCountdown() MSGBox(4000,"DEBUG: Countdown Close","Countdown close button pressed") ;more UDP stuff that works fine GUIDelete($_GuiCountDown) ;;Back to the input interface EnterTime() EndFunc Link to comment Share on other sites More sharing options...
Aelc Posted May 13, 2020 Share Posted May 13, 2020 It's some problem with swapping between OnEventmode On/Off I guess. With swapping i couldn't make it work But like this it does expandcollapse popup;;Includes #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GuiImageList.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <WinAPIFiles.au3> #include <WindowsConstants.au3> Global $SS_CENTER Global $_CountdownTime Global $_Minutes Global $_Seconds Global $TimeTicks Global $TimeLabel Global $_GuiCountDown Global $EnterMinutes Global $EnterSeconds Global $StartButton Global $Minutes Global $Seconds Global $_GuiEnterTime Dim $aPanelCSV[0] ;Main function to trigger everything Main() Func Main() EnterTimeGUI() EnterTime() EndFunc Func PanelCount() ;stuff that works in the real script EndFunc ;Primary function for entering in the countdown duration Func EnterTimeGUI() ;;Create a GUI $_GuiEnterTime = GUICreate ( "Enter Start Time", 300, 150) ;~ Opt("GUIOnEventMode", 0) GUISetBkColor ( 0xFFFFFF ) GUISetFont(10,0,0) $EnterLabel = GUICtrlCreateLabel ( "Minutes", 100,15,100,35) $EnterLabel = GUICtrlCreateLabel ( "Seconds", 160,15,100,35) GUISetFont(13.5,0,0) $EnterMinutes = GUICtrlCreateInput ("",105,35,45,35,$ES_NUMBER) $EnterSeconds = GUICtrlCreateInput ("",155,35,45,35,$ES_NUMBER) GUISetFont(12,0,0) $StartButton = GUICtrlCreateButton ("Start",110,80,80,50) GUISetState (@SW_SHOW,$_GuiEnterTime) EndFunc Func EnterTime() GUISetState (@SW_SHOW,$_GuiEnterTime) ;~ Opt("GUIOnEventMode", 0) While 1 ;~ MsgBox ( 64,"","" ) $MSG = GUIGetMsg() Select Case $MSG = $GUI_EVENT_CLOSE ;Exit MsgBox(4000,"DEBUG: Enter Time","enter time close button pressed") ;;Start button for countdown Case $MSG = $StartButton $Minutes = GUICtrlRead($EnterMinutes) $Seconds = GUICtrlRead($EnterSeconds) ;Math for the WallTime and local countdown functions $Paneltime = (((60 * $Minutes) + $Seconds)) $_CountdownTime =(((60000 * $Minutes) + (1000 * $Seconds))+1000) Sleep(100) GUISetState (@SW_HIDE,$_GuiEnterTime) ;;Function starts the countdown timer on the WallTime panels PanelCountDown() ;;starts the function for local countdown CountDownGUI() ComputerCountDown() EndSelect WEnd EndFunc #cs Local countdown--this was mostly taken from Wakillon's post in April of 2011, then modified for my use case. Full credit to Wakillon for this part. https://www.autoitscript.com/forum/topic/127667-how-to-create-a-countdown-timer-in-autoit/ #ce Func CountDownGUI() ;;Countdown GUI $_GuiCountDown = GUICreate ( "CountDown...", 500, 200, @DesktopWidth/2 -250, @DesktopHeight/2 -100) GUISwitch ($_GuiCountDown) ;~ Opt("GUIOnEventMode", 1) ;~ GUISetOnEvent($GUI_EVENT_CLOSE, "StopCountdown") GUISetBkColor ( 0xFFFFFF ) $TimeLabel = GUICtrlCreateLabel ( "", 35, -10, 480, 180, $SS_CENTER ) GUICtrlSetFont ( -1, 125, 800 ) GUISetState (@SW_SHOW,$_GuiCountDown) ;WinSetOnTop ( $_GuiCountDown, "", 1 ) $TimeTicks = TimerInit ( ) EndFunc Func ComputerCountDown() Do ;;calls the function to begin the countdown $check = Check ( ) If GUIGetMsg () = -3 Then StopCountdown() Until $check <> True EnterTime() EndFunc Func Check ( ) $_CountdownTime -= TimerDiff ( $TimeTicks ) $TimeTicks = TimerInit ( ) Local $_MinCalc = Int ( $_CountdownTime / ( 60 * 1000 ) ), $_SecCalc = $_CountdownTime - ( $_MinCalc * 60 * 1000 ) $_SecCalc = Int ( $_SecCalc / 1000 ) If $_MinCalc <= 0 And $_SecCalc <= 0 Then ;;steps through one second at a time Sleep ( 250 ) ;;when it's done it removes the GUI and goes back to the entry interface GUIDelete ($_GuiCountDown) Return False Else ;;changes colors of the GUI for the last 10 seconds If $_MinCalc <> $_Minutes Or $_SecCalc <> $_Seconds Then $_Minutes = $_MinCalc $_Seconds = $_SecCalc GUICtrlSetData ( $TimeLabel, StringFormat ( "%02u" & ":" & "%02u", $_Minutes, $_Seconds ) ) If $_Minutes = 0 And $_Seconds <= 10 Then GUISetBkColor ( 0xA093FF, $_GuiCountDown ) EndIf EndIf EndIf Return True EndFunc Func PanelCountdown() ;;this part works fine, part of an external system I'm triggering via UDP sends EndFunc Func StopCountdown() MSGBox(4000,"DEBUG: Countdown Close","Countdown close button pressed") ;more UDP stuff that works fine ;~ ExitLoop GUIDelete($_GuiCountDown) ;;Back to the input interface EnterTime() EndFunc why do i get garbage when i buy garbage bags? Link to comment Share on other sites More sharing options...
water Posted May 13, 2020 Share Posted May 13, 2020 Did you have a look at the wiki? There you'll find a tutorial how to handle multiple GUIs: https://www.autoitscript.com/wiki/Managing_Multiple_GUIs My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
Aelc Posted May 13, 2020 Share Posted May 13, 2020 Well actually true.. your code @radioguy is really confusing why do i get garbage when i buy garbage bags? Link to comment Share on other sites More sharing options...
radioguy Posted May 13, 2020 Author Share Posted May 13, 2020 Hi all, @Aelc 's solution works perfectly. @water--I was originally referencing the Wiki, which is how I landed on using the GUIOnEventMode switch--or, really hybrid mode, as I needed to use the case statements for the original button push then define the control (close) the second GUI with the GUISetOnEvent call. With the original "While" loop I was unable to figure out a way to add a "case" for exiting the second GUI. Lots of Googling/reading examples did NOT lead to the "Do...Until" statement that was suggested (and with which, until now, I was unfamiliar). That said, I understand the changes you made/suggested (determine the control ID, use a Do...Until statement in place of the While, use the Control ID to determine which GUI is being closed), and am already re-thinking a few previous scripts where I may go back and make some modifications for similar issues where I found less...elegant solutions. Sorry the code is confusing. I'm green enough that I'm probably not as organized (or pre-planned) as I should/could be for much of my coding. "On the fly" planning (and troubleshooting) can definitely lead to things being a bit sloppy. That said, THANK YOU again--learning new things every day! Link to comment Share on other sites More sharing options...
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