How to Winwait for two windows simultaneously in AutoIt?
Asked Answered
I

6

8

I would like to know if its possible to WinWaitActive for WindowWithThisTitle and WindowWithThatTitle at the same time. I'm executing a command and there could be a window telling me that the connection failed or a user/pass dialog coming up.

Is there another way doing it as this?

WinWaitActive("Title1", "", 5)
If(WinExists("Title1")) Then
 MsgBox(0, "", "Do something")
Else
 If(WinExists("Title2")) Then
  MsgBox(0, "", "Do something else")
 EndIf
EndIf

Because I don't want to have the timeout which could be more than 15 seconds.

Initiation answered 14/8, 2010 at 0:9 Comment(1)
You can see this Autohotkey board for an answer that you might be able to transfer.Obidiah
P
8

A simpler solution might be to use a REGEX title in your WinWaitActive as defined here

You would then have something like this:

$hWnd = WinWaitActive("[REGEXPTITLE:(WindowWithThisTitle|WindowWithThatTitle)]")

If WinGetTitle($hWnd) = "WindowWithThisTitle" then
    DoSomething()
Else
    DoSomethingElse()
EndIf
Paiz answered 25/3, 2014 at 18:3 Comment(1)
The synax should be: $hWnd = WinWaitActive("[REGEXPTITLE:.*WindowWithThisTitle.*|.*WindowWithThatTitle.*]")Phytology
T
5

How about something like this.

$stillLooking = True
While $stillLooking
    $activeWindowTitle = WinGetTitle(WinActive(""))
    If $activeWindowTitle == "Title1" Then
        MsgBox(0, "", "Do something")
        $stillLooking = False
    ElseIf $activeWindowTitle == "Title2" Then
        MsgBox(0, "", "Do something else")
        $stillLooking = False
    EndIf
    sleep(5)
WEnd

Because I don't want to have the timeout which could be more than 15 seconds.

WinWaitActive() doesn't have a timeout unless you specify one. You gave it a five second timeout but you could leave that off and it would wait forever.

Tuchun answered 14/8, 2010 at 0:49 Comment(7)
But this WhileLoop causes one cpu thread/core to run at 100%. I was thinking about a solution with WinWaitActive(regex) but I dont know how to create a regex that has an OR operator. Any Idea? What do you mean with "Don't forget to vote!" btw?Initiation
The sleep(5) - or more - will fix the cpu problem, it was hard looping. WinWaitActive() wont do multiple targets and its return is a simple success bool so you can't really regex it. You have voted once since you started using stack overflow. The StackOverflow system really only works if people vote. If a question or answer is helpful to you you can vote it up with the up arrow picture or down with the down arrow. Good luck, hope this helped if it did you could show that by voting.Tuchun
I didn't yet mark your answer as "THE" answer because maybe someone knows a method without looping. I'll just wait some time and then set it as answer if no one can provide a better way. Thanks for your help!Initiation
WinWaitActive() also loops in the code of that function. I have a hard time imagining any way to do anything like this without looping in a procedural (vs. event driven) context. I'm sure a better way to do this exists but that way is also likely to have a loop in it.Tuchun
I agree, being a procedural environment, this would be nearly impossible to accomplish without looping. I typically have my long running AutoIt loops sleep for an 1/8th of a second: Sleep(125) This polls often enough for most needs, and doesn't hog the CPU cycles.Baribaric
I agree John, I usually do 200 or more in real world applications. A window typically will not come into focus and then leave focus in a time shorter then that. I just wanted to show that any sleep even a short one will solve it. Thanks for the +1!Tuchun
According to official AutoIt documentation for WinWaitActive, "The window is polled every 250 milliseconds or so.".Ascender
M
2

You can use this Functions for two windows ..

; #FUNCTION# ====================================================================================================================
; Name...........: _2WinWait
; Description ...: Wait For Tow Windows .
; Syntax.........: _2WinWait ($FirstTitle,$SecondTitle,[$FirstText = "" ,[$SecondText = ""]] )
; Parameters ....: $FirstTitle  - Title Of First  Wondow 
;                  $SecondTitle - Title Of Second Wondow 
;                  $FirstText   - Text  Of First  Wondow 
;                  $SecondText  - Text  Of Second Wondow 
; Return values .: Success - None
;                  Failure - Returns a 0 => If Your Titles Is Wrong
; Author ........: Ashalshaikh : Ahmad Alshaikh
; Remarks .......: 
; Related .......:
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _2WinWait ($FirstTitle,$SecondTitle,$FirstText = "" ,$SecondText = "" )
    If $FirstTitle = "" Or $SecondTitle = "" Then
        Return 0 
    Else
        Do 
        Until WinExists ($FirstTitle,$FirstText) Or WinExists ($SecondTitle,$SecondText)
    EndIf
EndFunc


; #FUNCTION# ====================================================================================================================
; Name...........: _2WinWait_Any 
; Description ...: Wait For Tow Windows And Return Any Window Id Exists .
; Syntax.........: _2WinWait_Any ($FirstTitle,$SecondTitle,[$FirstText = "" ,[$SecondText = ""]] )
; Parameters ....: $FirstTitle  - Title Of First  Wondow 
;                  $SecondTitle - Title Of Second Wondow 
;                  $FirstText   - Text  Of First  Wondow 
;                  $SecondText  - Text  Of Second Wondow 
; Return values .: Success - Number Of Window ==> 1= First Window , 2= Second Window
;                  Failure - Returns a 0 => If Your Titles Is Wrong
; Author ........: Ashalshaikh : Ahmad Alshaikh
; Remarks .......: 
; Related .......:
; Link ..........;
; Example .......; No
; ===============================================================================================================================
Func _2WinWait_Any ($FirstTitle,$SecondTitle,$FirstText = "" ,$SecondText = "" )
    If $FirstTitle = "" Or $SecondTitle = "" Then
        Return 0 
    Else
        Do 
        Until WinExists ($FirstTitle,$FirstText) Or WinExists ($SecondTitle,$SecondText)
        If WinExists ($FirstTitle,$FirstTexit) Then 
            Return 1 
        Else
            Return 2 
        EndIf
    EndIf
EndFunc

for more with examples

Mameluke answered 3/10, 2010 at 18:55 Comment(0)
R
1

I'm fairly new to autoit and the programming world in general and I had this same dilemma. Luckily I figured out a straight fwd way to do it:

Do
$var1 = 0
If  WinGetState("Document Reference","")    Then
    $var1 = 1
ElseIf  WinGetState("Customer Search","")   Then
    $var1 = 1
EndIf
Until $var1 = 1

So it'll stay in the loop until it finds the window and sets $var1 to 1. There's probably easier ways (I'm sure developers are gasping at this) but this is straight fwd enough for me.

Roundworm answered 27/2, 2012 at 18:16 Comment(0)
H
0

You can create an infinite while loop with if statements in there:

#include <MsgBoxConstants.au3>

Example()

Func Example()
    While 1
        ; Test if the window exists and display the results.
        If WinExists("Windows Security") Then
            Local $hWnd = WinWaitActive("Windows Security", "", 2000)
            ControlSetText($hWnd, "", "[CLASS:Edit; INSTANCE:1]", "hel233")
            ControlClick("Windows Security","","[CLASS:Button; INSTANCE:2]")
            Sleep(5000)
        EndIf

        ; Test if the window exists and display the results.
        If WinExists("Spread the Word") Then
            'The line below will wait until the window is active, but we don't need that
            'Local $hWnd = WinWaitActive("Spread the Word", "", 2000)
            WinClose("Spread the Word")
            Sleep(5000)
        EndIf



    wend
EndFunc
Houselights answered 14/12, 2015 at 18:0 Comment(0)
O
0

The RegExp solution is nice, but it has the following downsides:

  • RegExps are quite slow and should be avoided unless absolutely necessary;
  • It's not very handy and clean if more windows are needed;
  • It doesn't allow to use different properties to identify windows.

The following function allows you to wait for any number of windows using different identifiers:

Func WinWaitActiveMultiple(Const ByRef $avTitles, Const $asTexts = 0)
    Local Const $ciNumWindows = UBound($avTitles)
    Local Const $ciWaitDelay = Opt("WinWaitDelay")

    While True
        For $i = 0 To $ciNumWindows - 1
            Local $sText = ($asTexts = 0)? "": $asTexts[$i]
            Local $hWnd = WinActive($avTitles[$i], $sText)
            If $hWnd Then
                Return $hWnd
            EndIf
        Next
        Sleep($ciWaitDelay)
    WEnd
EndFunc

It works very similar to WinWaitActive(), but accepts arrays. It can be used as follows:

Local Const $casWinTitles = [ _
    "Title 1", "Title 2", "[CLASS:WClass1]" _
]
Local Const $casWinTexts = ["Text 1", "", ""]

Local $hWnd = WinWaitActiveMultiple($casWinTitles, $casWinTexts)
Local $sTitle = WinGetTitle($hWnd)

If $sTitle == "Title 1" Then
    ; Handle window 1

ElseIf $sTitle == "Title 2" Then
    ; Handle window 2

Else
    ; Handle window 3

EndIf
Ormandy answered 21/3, 2023 at 17:8 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.