以创建的相反顺序关闭窗口

时间:2015-02-13 13:59:02

标签: autoit

我有一个带有主窗口和多个其他窗口的程序,并希望使用autoit来关闭这些窗口。然而,如果程序的其他窗口打开并且创建警告消息,则主窗口拒绝关闭。

为了避免这种情况,我想先关闭其他窗口。

由于编写程序的方式,窗口不是父子关系,所以我不能在“user32.dll”中使用“EnumChildWindows”。

所以我的另一个选择是获取创建窗口的顺序或时间,并以相反的顺序关闭它们。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以尝试通过该过程获取它。根据我的知识,下面的函数将返回窗口的z顺序,而无需从您自己的代码中跟踪窗口本身的“创建时间”,您将无法获得可以做到这一点的解决方案。 / p>

#include <WinAPIProc.au3>
#include <WinAPISys.au3>

#region - Example
Global $gahWnd[3]
For $i = 0 To 2
    $gahWnd[$i] = GUICreate("Example " & $i)
    GUISetState(@SW_SHOW, $gahWnd[$i])
Next


Global $gaExample = _WinGetByProc(@AutoItPID)
If @error Then Exit 2
Sleep(3000) ; so you can at least see the windows were created

; windows are returned in the "last z-order"
;  so they'll be returned "Example 2, Example 1, Example 0"
;  This makes it easy to close all but the first one

; use -1 to keep the first window created
For $i = 1 To $gaExample[0] - 1
    ConsoleWrite("Closing: " & $gaExample[$i] & ":" & WinGetTitle($gaExample[$i]) & @CRLF)
    WinClose($gaExample[$i])
Next

Global $gaMsg
While 1
    $gaMsg = GUIGetMsg(1)
    Switch $gaMsg[1]
        Case $gahWnd[0]
            Switch $gaMsg[0]
                Case -3
                    Exit
            EndSwitch
        Case $gahWnd[1]
            Switch $gaMsg[0]
                Case -3
                    GUIDelete($gahWnd[1])
            EndSwitch
        Case $gahWnd[2]
            Switch $gaMsg[0]
                Case -3
                    GUIDelete($gahWnd[2])
            EndSwitch
    EndSwitch
WEnd
#EndRegion - Example

; pass the exe or the process id
Func _WinGetByProc($vExe)

    ; will return pid if exe name sent or validate if pid is sent
    Local $iPID = ProcessExists($vExe)
    If Not ProcessExists($iPID) Then
        Return SetError(1, 0, 0)
    EndIf

    ; enum desktop window only (top-level-windows)
    Local $ahWnds = _WinAPI_EnumDesktopWindows(_WinAPI_GetThreadDesktop( _
                _WinAPI_GetCurrentThreadId()))
    If @error Or Not IsArray($ahWnds) Then
        Return SetError(2, 0, 0)
    EndIf

    Local $aExeContainer[11], $iDim
    For $iwnd = 1 To $ahWnds[0][0]
        ; compare windows pid with our pid
        If (WinGetProcess(HWnd($ahWnds[$iwnd][0])) = $iPID) Then
            $iDim += 1
            ; sanity check, be sure the array has the right number of indexes
            If (Mod($iDim, 10) = 0) Then
                ReDim $aExeContainer[$iDim + 10]
            EndIf
            $aExeContainer[$iDim] = HWnd($ahWnds[$iwnd][0])
        EndIf
    Next

    ; if there were no matches return
    If Not $iDim Then
        Return SetError(3, 0, 0)
    EndIf

    ; trim array and set number found in the zero index
    ReDim $aExeContainer[$iDim + 1]
    $aExeContainer[0] = $iDim

    Return $aExeContainer
EndFunc