Jump to content
Sign in to follow this  
AndyScull

Constant check for WinActive or similar

Recommended Posts

AndyScull

What I have -

1. Long and complex script written a long time ago

2. Sometimes the target window loses focus or just some unpredictable things happen.

3. Currently I am just restarting the script manually with hotkey as soon as I notice it went wrong.

What I want is to have some background function in script that checks some condition (for example, WinActive) and if false - pauses or stops the whole script.

I had several thoughts -

1. AdlibRegister a function which checks for condition and restarts the whole script? This way all running functions are definitely stopped and script just loads it's settings from .ini. But it will also have to redraw it's GUI - which is a bit annoying.

2 the same as (1) but with 'WinWaitActive' instead of IF at regular intervals.

Like

Func CheckWindow()
  WinWaitActive("xxx")
EndFunc

And AdlibRegister it to run every 50-100 milliseconds. But will it pause execution of other functions while WinWait'ing?

3. Insert a "if $flag=1 then return" on each 2nd line of all functions? They're pretty long so I can't place the check only at beginning of function.

The problem I am thinking about - which is the best and most effective way to do it?

Also, related question - is there some command that would pause execution for everything except current code block (=function)?

Something like

Func CheckAndWait()
  While $flag=1
     _PauseOtherFunctions()
     sleep(100)
     If (SomeCondition) Then
        $flag=0
        _UnpauseOtherFunctions()
      EndIf
  Wend
EndFunc

Share this post


Link to post
Share on other sites
Melba23

AndyScull,

Welcome to the AutoIt forum. :graduated:

I quite like your second idea - using Adlib and WinWaitActive. As you can see from this little test script it does seem to stop everything else (as I expected): :)

#include <GUIConstantsEx.au3>

$hGUI = GUICreate("Test", 500, 500)

GUISetState()

AdlibRegister("_WinCheck", 1000)

$iBegin = TimerInit()

While 1

    If TimerDiff($iBegin) > 5000 Then
        _Writer()
        $iBegin = TimerInit()
    EndIf

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

WEnd

Func _Writer()

    For $i = 1 To 3
        ConsoleWrite(@SEC & @CRLF)
        Sleep(1000)
    Next

EndFunc

Func _WinCheck()

    WinWaitActive("Test", "")

EndFunc

You might want embellish the Adlib function to add a loop including the WinWait with a suitably long timeout followed by a WinExists - in this way you could then exit the script if the window had entirely disappeared. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
AndyScull

Yeah, I did some tests too, it really seems to work.

Though with a one quirk I do not quite understand myself.

AdlibRegister("pause",10); this keeps running at all times till you exit.
Func pause()
  ConsoleWrite(@SEC & " pausecheck start" & @CR)    
  if not WinActive("Untitled - Notepad") then  WinWaitActive("Untitled - Notepad")   ; --  This is the strange thing I mentioned below
  ConsoleWrite(@SEC & " pausecheck end" & @CR)  
EndFunc
 
While True
    sleep(500)
    send("4"); this sends the number 4 key to the active program.
    sleep(500) ; sleep for .5 second before repeating
    send("5"); this sends the number 5 key to the active program.
    ConsoleWrite(@SEC & " Main loop end")
Wend
 
ConsoleWrite(@SEC & " Script end")

The 10 ms interval is set so the script would have lesser chance to 'leak' 4 or 5 keys to unrelated windows.

I took basic script from autoit's help. The strange thing is that simple WinWaitActive stops sending "454545" to notepad...

This 'debug' version of script correctly writes 'pausecheck start/end' and 'main loop' events to console.

As soon as I change if not WinActive("Untitled - Notepad") then WinWaitActive("Untitled - Notepad")

to simple WinWaitActive("Untitled - Notepad"), it stops all other execution completely. There's no 'Main loop end' and 'Script end' debugging events, no '45' output in notepad, only Adlib function keeps running again and again..

Whatever, It seems this code does what I want. Thanks for the answer!

p.s. Though I still hope someone knows how to force-break all running functions without restarting the script itself/

Edited by AndyScull

Share this post


Link to post
Share on other sites
Melba23

AndyScull,

Though I still hope someone knows how to force-break all running functions without restarting the script itself

You might find the Interrupting a running function tutorial in the Wiki of interest. It shows how you can do it within the (pretty severe) limits of AutoIt. :graduated:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Melba23

AndyScull,

i have solved the mystery of the simple WinWaitActive line pausing everything. On my machine it takes 250 msecs to check and so you are rerunning the Adlib function faster than it takes to finish. I would hazard a guess you will run into the recursion limit if you leave it long enough. ;)

AdlibRegister("pause", 10); this keeps running at all times till you exit.

HotKeySet("{ESC}", "On_Exit")

While True
    Sleep(500)
    Send("4"); this sends the number 4 key to the active program.
    Sleep(500) ; sleep for .5 second before repeating
    Send("5"); this sends the number 5 key to the active program.
    ConsoleWrite(@SEC & " Main loop end" & @CRLF)
WEnd

ConsoleWrite(@SEC & " Script end")

Func On_Exit()
    Exit
EndFunc

Func pause()
    $iBegin = TimerInit()

    WinWaitActive("Untitled - Notepad")

    ConsoleWrite(Int(TimerDiff($iBegin)) & "ms" & @CR)
EndFunc   ;==>pause

Simple really! :graduated:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
AndyScull

"have a function which checks internally whether it ought to allow an interruption. In all other cases you are are not going to be able to interrupt your function."

Disappointing but I'll have to live with it. There's no real alternatives to autoit.

I am thinking of a final solution - I'll write a tiny wrapper for each function, for example

Func MyMouseMove(x,y,spd=10)
    if WinActive($wintitle) then
       MouseMove(x,y,spd)
       return 0
    else
       return 1
    EndIf
EndFunc

and replace in main working script all MouseMove(x,y) with if MyMouseMove(x,y)<>0 then return 1

That way, if something goes wrong, any function of any depth would stop with return code 1 and drop out to main waiting loop.

Pity there's no inline functions/macros, the code would be less readable with all those ifs.

Damn, foolproofing programs is ten times harder that writing them.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×