Jump to content

Recommended Posts

Posted (edited)

 

Hello,

 

I am trying to learn how this works. I want to be able to interrupt a running  function with winwait.. In this example I want to start notepad and than the script needs to  winwait for a specific window. 

But if that window does not appear then I want the user to be able to interrupt the function and start the next function (run nextprogram.exe")

I found some examples and mentioned winwait, but I still could not make it work.

I tried to adjust the tutorial https://www.autoitscript.com/wiki/Interrupting_a_running_function , but could not get this working either with a winwait 

I hope someone can put me in the right direction.

Code below is just one of my many attempts...

#include <GUIConstantsEx.au3>
 #include <WindowsConstants.au3>

 AutoItSetOption("TrayIconDebug", 1) ;0-off ;AutoIt3Wrapper_Run_Debug_Mode=Y

 ; Set a HotKey
 HotKeySet("x", "_Interrupt")

 ; Declare a flag
 $fInterrupt = 0

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

 $hButton_1 = GUICtrlCreateButton("Func One", 10, 10, 80, 30)
 $hButton_2 = GUICtrlCreateButton("Func Two", 10, 50, 80, 30)

 ; Create a dummy control for the Accelerator to action when pressed
 $hAccelInterupt = GUICtrlCreateDummy()
 ; Set an Accelerator key to action the dummy control
 Dim $AccelKeys[1][2]=[ ["z", $hAccelInterupt] ]
 GUISetAccelerators($AccelKeys)

 GUISetState()

 ; Intercept Windows command messages with out own handler
 GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

 While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
         Case $hButton_1
             _Func_1()
             _Func_3()
         Case $hButton_2
             _Func_2()
     EndSwitch
 WEnd

 ; Use a wrapper function in place of the blocking function
 Func _Func_1()
    ; Make sure the flag is cleared
    $fInterrupt = 0
    ;For $i = 1 To 20
run ("notepad")
        ConsoleWrite("-Func 1 Running" & @CRLF)
        ; Run a modified Sleep function which checks for the interrupt
        ;if _Interrupt_Sleep(1000) Then ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            if _Interrupt_Sleep(999999999999999999999999999999999) Then ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

            ; The flag was set
            Switch $fInterrupt
                Case 1
                    ConsoleWrite("!Func 1 interrrupted by Func 2" & @CRLF)
                Case 2
                    ConsoleWrite("!Func 1 interrrupted by HotKey" & @CRLF)
                Case 3
                    ConsoleWrite("!Func 1 interrrupted by Accelerator" & @CRLF)
            EndSwitch
            Return
        EndIf
        Sleep(100)
 ;  Next
    ConsoleWrite(">Func 1 Ended" & @CRLF)
 EndFunc   ;==>_Func_1

 ; And here is the wrapper function itself
 Func _Interrupt_Sleep($iDelay)
    ; Get a timestamp
    Local $iBegin = TimerInit()
    ; And run a tight loop
    Do
        ; Use a minimum Sleep (could also be a WinWaitActive with a short timeout)
        ;Sleep(10)
        winwait("sdfdf","sdfsdf") ;<<<<<<----- the winwait for a window I want to skip
        ; Look for the interrrupt
        If $fInterrupt Then
            ; And return True immediately if set
            Return True
        EndIf
    Until TimerDiff($iBegin) > $iDelay
    ; Return False if timed out and no interrupt was set
    Return False
 EndFunc   ;==>_Interrupt_Sleep

 Func _Func_2()
     ;For $i = 1 To 3
     processclose("notepad.exe")
         ConsoleWrite("+Func 2 Running" & @CRLF)
         Sleep(100)
     ;Next
     ConsoleWrite(">Notepad killed!" & @CRLF)
 EndFunc
 
 Func _Func_3()
 run("nextprogam.exe")
 Endfunc

 Func _Interrupt()
     ; The HotKey was pressed so set the flag
     $fInterrupt = 2
 EndFunc

 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
     ; The Func 2 button was pressed so set the flag
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1
     ; The dummy control was actioned by the Accelerator key so set the flag
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3
     Return $GUI_RUNDEFMSG
 EndFunc   ;==>_WM_COMMAND

 

Edited by MightyWeird

Share this post


Link to post
Share on other sites

MightyWeird,

Your functions are short and there is no need to interrupt them. This should do as you wish:

#include <GUIConstantsEx.au3>

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

$hButton_1 = GUICtrlCreateButton("Func One", 10, 10, 80, 30)
$hButton_2 = GUICtrlCreateButton("Func Two", 10, 50, 80, 30)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hButton_1
            _Func_1()
        Case $hButton_2
            _Func_2()
    EndSwitch
WEnd

Func _Func_1()
    ConsoleWrite("-Func 1 Running" & @CRLF)
    Run("notepad")
    ConsoleWrite(">Func 1 Ended" & @CRLF)
EndFunc   ;==>_Func_1

Func _Func_2()
    ConsoleWrite("+Func 2 Running" & @CRLF)
    Do
        ProcessClose("notepad.exe")
        Sleep(10)
    Until Not ProcessExists("notepad.exe")
    ConsoleWrite(">Notepad killed!" & @CRLF)
    ConsoleWrite("+Func 2 Ended" & @CRLF)
    _Func_3()
EndFunc   ;==>_Func_2

Func _Func_3()
    ConsoleWrite("Running 'nextprogram.exe'" & @CRLF)
    ;Run("nextprogam.exe")
EndFunc   ;==>_Func_3

The code you were trying to use is for functions which take an age to run - not short discrete ones like yorus.

M23


Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see 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
Posted (edited)

Or maybe this is what you want ?

Global $fInterrupt = False

HotKeySet("x", "_Interrupt")

Local $hWnd
Do
  $hWnd = WinWait ("none","none",1)
Until $hWnd or $fInterrupt

If $hWnd Then
  ConsoleWrite ("WinWait succeeded" & @CRLF)
Else
  ConsoleWrite ("WinWait was interrupted" & @CRLF)
EndIf

Func _Interrupt()
  ; The HotKey was pressed so set the flag
   $fInterrupt = True
EndFunc

 

Edited by Nine

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By FMS
      Hello,

      I'm having a problem whit winwait on firefoxscreens whit the same title and text.
      On mine quest on this forum and internet I've found some work around and solutions.
      unfortunaly This wasn't working for me.

      I've tried searching tru winlist or finding some unique text but wasn't finding any solution.
      Does anyone know how to get the wright handle?
      I just want to move the browser to the right place in the end whit WinMove.

      thnx in advanced.

       
      #include <Array.au3> Global $A_URL[4][2] = _ [["url1" , "same_title"] , _ ["url2", "same_title"] , _ ["url3" , "other_title" ] , _ ["url4" , "other_title" ]] ;~ _ArrayDisplay($A_URL) ;-----kill all firefox.exe ;~ Run("taskkill /IM firefox.exe /F", "", @SW_HIDE) ;Sleep(5000) For $i = 0 To 1 ConsoleWrite("running 1 : " & $i & @CRLF) Local $ID = ShellExecute("firefox.exe", "-new-window " & $A_URL[$i][0] ,"C:\Program Files\Mozilla Firefox" ) ConsoleWrite("$ID = " & $ID & @CRLF) Next sleep(200) ;~ Local $screen1HWND = WinWait($A_URL[0][1],"") ;~ If Not WinActive($screen1HWND) Then WinActivate($screen1HWND) ;~ ConsoleWrite("$screen1HWND = " & $screen1HWND & @CRLF) ;~ Local $screen2HWND = WinWait($A_URL[1][1],"") ;~ If Not WinActive($screen2HWND) Then WinActivate($screen2HWND) ;~ ConsoleWrite("$screen2HWND = " & $screen2HWND & @CRLF) $sWinTitle = $A_URL[0][1] $avWinList = WinList($sWinTitle) For $n = 1 to $avWinList[0][0] ConsoleWrite("Window " & $n & ": Text: " & WinGetText($avWinList[$n][1]) & @LF) Next For $i = 0 To 1 ;~ WinWait("title1", "", 10) ;~ WinActive("title1", "") ;~ WinMove ("title1", "", $i , $i ) Next  
    • By MFrancisca
      OK, after days looking at my code, the help file and forums I come (again) for help on message windows.
      I'm having trouble trying to close window messages that appear. This is the code I'm using
      #include <MsgBoxConstants.au3> Local $obs_handler = 0 Opt("WinTitleMatchMode",2) While 1 $obs_handler = WinWait("C:\Users\", "", 1) If IsHWnd($obs_handler) then MsgBox($MB_OK, "Message", "handler: "&$obs_handler, 1) ;Sleep(100) $obs_handler = HWND($obs_handler) WinKill($obs_handler, "") ;<<<<< PROBLEM!!!!! Else MsgBox($MB_OK, "Message", "No handler", 1) EndIf Send("{ESC}") Sleep(2000) $obs_handler = 0 WEnd The problem is on the Winkill command, it won't just close the window! 
      Winwait is capturing the handler, it checks as handler. Ii'm using the HWND() command just to be sure it is the correct variable type.  I've also checked the message box info with the autoit window info tool and the handle value matches the one captured by the code. 
      I've tried winkill, winclose, using wingethandle, moving the winkill command to Before the message box so it is not converted to a string, and now using the hwnd function to force the variable type of the handler. The use of the sleep command does not make any diference.
      As a side quest, I'd like to use classes to capture the windows instead of titles, just to keep things cleaner, but using the [CLASS:...] value for winwait is not working. I have the class name and number, am I missing something? 
       
      Thanks! 
    • By TAMIRI
      Hello,
      i was wondering how could i stop a loop with a button
      here is my code
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Global $Form1 = GUICreate("Form1", 623, 444, 192, 114) Global $StartButton = GUICtrlCreateButton("Button1", 88, 192, 171, 25) Global $EndButton = GUICtrlCreateButton("Button2", 320, 192, 203, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $var = 1 While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $StartButton Start() Case $EndButton Stop() EndSwitch WEnd Func Start() While $var = 1 ConsoleWrite("again" & @CRLF) WEnd EndFunc Func Stop() $var = 0 EndFunc i was reading https://www.autoitscript.com/wiki/Interrupting_a_running_function
      but still i could not figure it out
      help PLZ !
    • By ur
      if ControlClick("[CLASS:MsiDialogCloseClass]"," ","[CLASS:SysTreeView32; INSTANCE:1]") Then $htreeview=ControlGetHandle($hwnd,"","[CLASS:SysTreeView32; INSTANCE:1]") ControlTreeView($hwnd," ",$htreeview,"Select","#4") The above code worked well to enable the martupgrade feature on windows 7.
      As part of our Installation Testing Automation before delivering the installer to end user.To confirm whether all the screens are working good.

      But it is not working on windows 10.
       
      $h= ControlTreeView($hwnd," ",$htreeview,"Select","#4") The $h is getting value 1,which means error.
    • By ur
      I have automated an install process by using the below code.
       
      Func _WinWaitActivate($title,$text,$timeout=0) WinWait($title,$text,$timeout) If Not WinActive($title,$text) Then WinActivate($title,$text) WinWaitActive($title,$text,$timeout) EndFunc $win1 = "Text 1" $win2 = "Text 2" _WinWaitActivate($win1,"WARNING: This progra") Send("{ALTDOWN}n{ALTUP}");Send("{SPACE}") _WinWaitActivate($win1,"I DISAGREE and &do n") Send("{UP}n") _WinWaitActivate($win1,"Customer Information") Send("{ALTDOWN}n{ALTUP}");Send("{TAB}{TAB}n") _WinWaitActivate($win1,"Click Next to instal") Send("{ALTDOWN}n{ALTUP}");Send("n") _WinWaitActivate($win1,"This feature require") Send("{ALTDOWN}n{ALTUP}");Send("{TAB}n") _WinWaitActivate($win1,"Ready to Install the") Send("{ALTDOWN}i{ALTUP}");Send("i") _WinWaitActivate($win1,"The InstallShield Wi") Send("{ALTDOWN}f{ALTUP}");Send("f") _WinWaitActivate($win2,"You must restart you") Send("{ALTDOWN}n{ALTUP}");Send("n") Now if any new screen comes in the middle of installation, like some VC++ installation error or like that.
      The AutoIT is waiting in the background.
      Is there any way to skip the new screens with just "enter" and continue the installation??
×
×
  • Create New...