Jump to content
Sign in to follow this  

Wait until any new window appears

Recommended Posts


I'm trying to find a way to wait until any new window appears, no matter it's title and contents. Do you know what would be the best way of achieving such behavior?

I tried using


but that returns also the already open windows, so it isn't of any use.

I thought I could maybe get all the open windows and store them in a table, then in a loop do the same and compare if the tables contain the same data. If not, then some new window has appeared (or was destroyed, whatever :P) but that idea really seems suboptimal to me and I believe there should be a more practical way to do this.

Thank you in advance :)

Share this post

Link to post
Share on other sites

You're not going to be able to get out of a loop (even if calling a built in function, they'll need to loop through their list).

I thought I might have written something like this years and years ago for the forum, but I'll darned if I can find it.

See if this meets your needs (note the array passed is ByRef, the return is the length of the array).

#include <Array.au3>

Global $ga_newWin = 0
Global $gn_uBound = 0
$gn_uBound = _Win_GetNew($ga_newWin)

WinWait("Untitled - Notepad")

$gn_uBound = _Win_GetNew($ga_newWin)

; should only show new windows

For $i = 0 To $gn_uBound - 1
    ConsoleWrite("Window Handle: " & $ga_newWin[$i] & _
        " : Window Title: " & WinGetTitle($ga_newWin[$i]) & @CRLF)

Func _Win_GetNew(ByRef $a_oldwin, $v_process = 0, _
        $s_wintitle = Null, $s_wintext = Null, $b_visibleonly = 1)

    ; are we working with a processes windows only?
    If $v_process Then
        $v_process = ProcessExists($v_process)
        If Not $v_process Then Return SetError(1, 0, 0)

    ; provide options for each optional parameter of win/title-text
    Local $a_wlist = 0
    If $s_wintitle Then
        If $s_wintext Then
            $a_wlist = WinList($s_wintitle, $s_wintext)
            $a_wlist = WinList($s_wintitle)
    ElseIf $s_wintext Then
        $a_wlist = WinList("[REGEXPTITLE:.*?]", $s_wintext)
        $a_wlist = WinList()

    If Not IsArray($a_wlist) Then
        Return SetError(2, 0, 0)

    Local $h_wnd
    Local $n_next = 0
    Local $a_ret[UBound($a_wlist) - 1]

    For $iwin = 1 To UBound($a_wlist) - 1

        $h_wnd = $a_wlist[$iwin][1]

        If $v_process And Not WinGetProcess($h_wnd) = $v_process Then

        If $b_visibleonly And Not BitAND(WinGetState($h_wnd), 2) Then

        $a_ret[$n_next] = String($h_wnd)
        $n_next += 1

    ; was anything found
    If Not $n_next Then
        Return SetError(3, 0, 0)

    ReDim $a_ret[$n_next]; resize

    ; if the old array is not an array or is a 2D array then return
    ;  current data already received
    If Not IsArray($a_oldwin) Or UBound($a_oldwin, 2) Then
        $a_oldwin = $a_ret
        Return UBound($a_ret)

    ; scripting dictionary does not like the handles
    For $i = 0 To $n_next - 1
        $a_ret[$i] = String($a_ret[$i])

    ; mikell shared this option I've not seen before:
    ;  http://www.autoitscript.com/forum/topic/165667-delete-matches-on-2-file-lists/#entry1209704
    Local $o_sd1 = ObjCreate("Scripting.Dictionary")
    Local $o_sd2 = ObjCreate("Scripting.Dictionary")
    For $i In $a_oldwin
    For $i In $a_ret
    For $i In $o_sd2
        If $o_sd1.Exists($i) Then
    $a_ret = $o_sd2.Keys();

    Local $l_retsize = UBound($a_ret)

    If Not $l_retsize Then
        Return SetError(4, 0, 0)

    ; convert back to window handles
    For $i = 0 To $l_retsize - 1
        $a_ret[$i] = HWnd($a_ret[$i])

    $a_oldwin = $a_ret
    Return $l_retsize

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post

Link to post
Share on other sites

Hmm you're right, my code was not accurate enough, it should check visible windows only and not fire on a window close

This one should be better

#include <MsgBoxConstants.au3>

Global $n0 = _GetWnd()
; MsgBox($MB_TOPMOST,"", $n0)
    $n1 = _GetWnd()
Until $n1 > $n0
MsgBox($MB_TOPMOST,"", "boo")

Func _GetWnd()
  Local $list = WinList("[REGEXPTITLE:\S+]")
  Local $nb = $list[0][0]
  For $i = 1 To $list[0][0]
    If Not BitAND(WinGetState($list[$i][1]), 2) Then $nb -= 1
  If $nb < $n0 Then $n0 = $nb
  Return $nb

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...