GUI eingefroren

  • Hallo,

    tut mir Leid dass ich schon wieder was fragen muss, allerdings komm ich nicht weiter.

    Ich rufe über eine externe Funktion per Knopfdruck einen neuen GUI auf. So weit klappt alles,
    doch sobald ich den neuen GUI wieder schließen will, ist der erste (der mit dem Aufruf-Button)
    gefrohren und reagiert nicht mehr. Alles andere funktioniert einwandfrei.

    Ich poste hier mal die Funktion, die ich genommen habe (habe ich gefunden und leicht ausgedünnt, aber nicht selbst geschrieben)

    Meine Frage dazu: Liegt es an der Funktion, dass meine erste GUI einfriert, oder nicht?

    Spoiler anzeigen
    [autoit]

    Func _ArrayDisplay2(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|", $sHeader = "")
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)
    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    ; Separator handling
    If $sSeparator = "" Then $sSeparator = Chr(124)

    [/autoit] [autoit][/autoit] [autoit]

    ; Check the separator to make sure it's not used literally in the array
    If _ArraySearch($avArray, $sSeparator, 0, 0, 0, 1) <> -1 Then
    For $x = 1 To 255
    If $x >= 32 And $x <= 127 Then ContinueLoop
    Local $sFind = _ArraySearch($avArray, Chr($x), 0, 0, 0, 1)
    If $sFind = -1 Then
    $sSeparator = Chr($x)
    ExitLoop
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Declare variables
    Local $vTmp, $iBuffer = 4094 ; AutoIt max item size
    Local $iColLimit = 250
    Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)

    [/autoit] [autoit][/autoit] [autoit]

    ; Swap dimensions if transposing
    If $iSubMax < 0 Then $iSubMax = 0
    If $iTranspose Then
    $vTmp = $iUBound
    $iUBound = $iSubMax
    $iSubMax = $vTmp
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Set limits for dimensions
    If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
    If $iItemLimit < 1 Then $iItemLimit = $iUBound
    If $iUBound > $iItemLimit Then $iUBound = $iItemLimit

    [/autoit] [autoit][/autoit] [autoit]

    ; Set header up
    If $sHeader = "" Then
    $sHeader = "Row " ; blanks added to adjust column size for big number of rows
    For $i = 0 To $iSubMax
    $sHeader &= $sSeparator & "Col " & $i
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Convert array into text for listview
    Local $avArrayText[$iUBound + 1]
    For $i = 0 To $iUBound
    $avArrayText[$i] = "[" & $i & "]"
    For $j = 0 To $iSubMax
    ; Get current item
    If $iDimension = 1 Then
    If $iTranspose Then
    $vTmp = $avArray[$j]
    Else
    $vTmp = $avArray[$i]
    EndIf
    Else
    If $iTranspose Then
    $vTmp = $avArray[$j][$i]
    Else
    $vTmp = $avArray[$i][$j]
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Add to text array
    $vTmp = StringReplace($vTmp, $sSeparator, $sReplace, 0, 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Set max buffer size
    If StringLen($vTmp) > $iBuffer Then $vTmp = StringLeft($vTmp, $iBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    $avArrayText[$i] &= $sSeparator & $vTmp
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; GUI Constants
    Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66
    Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40
    Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200
    Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2
    Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4
    Local Const $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH = (0x1000 + 29)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
    Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
    Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
    Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
    Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
    Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
    Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
    Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
    Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000

    [/autoit] [autoit][/autoit] [autoit]

    ; Set interface up
    Local $iWidth = 640, $iHeight = 480
    Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
    Local $aiGUISize = WinGetClientSize($hGUI)
    Local $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
    Local $hSaveSelected = GUICtrlCreateButton("Save Selected", (($aiGUISize[0])/3) + 6, $aiGUISize[1] - 23, $aiGUISize[0]/3 - 9, 20)
    GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
    GUICtrlSetResizing($hSaveSelected, $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)

    [/autoit] [autoit][/autoit] [autoit]

    ; Fill listview
    For $i = 0 To $iUBound
    GUICtrlCreateListViewItem($avArrayText[$i], $hListView)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; adjust window width
    $iWidth = 0
    For $i = 0 To $iSubMax + 1
    $iWidth += GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH, $i, 0)
    Next
    If $iWidth < 250 Then $iWidth = 230
    $iWidth += 20

    [/autoit] [autoit][/autoit] [autoit]

    If $iWidth > @DesktopWidth Then $iWidth = @DesktopWidth - 100

    [/autoit] [autoit][/autoit] [autoit]

    WinMove($hGUI, "", (@DesktopWidth - $iWidth) / 2, Default, $iWidth)

    [/autoit] [autoit][/autoit] [autoit]

    ; Show dialog
    GUISetState(@SW_SHOW, $hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Local $guiMsg = GUIGetMsg()
    Switch $guiMsg

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_CLOSE
    GUIDelete ($hGUI)

    Case $hSaveSelected
    Global $sClip = ""
    ;
    Local $aiCurItems[1] = [0]
    For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then
    $aiCurItems[0] += 1
    ReDim $aiCurItems[$aiCurItems[0] + 1]
    $aiCurItems[$aiCurItems[0]] = $i
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Generate clipboard text
    If Not $aiCurItems[0] Then
    For $sItem In $avArrayText
    $sClip &= $sItem & @CRLF
    Next
    Else
    For $i = 1 To UBound($aiCurItems) - 1
    $sClip &= $avArrayText[$aiCurItems[$i]] & @CRLF
    Next
    EndIf
    If @error Then
    MsgBox(4096, "", "Save cancelled.")
    Else
    Return $sClip
    EndIf
    EndSwitch
    WEnd
    ; GUIDelete($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", $iOnEventMode)
    Opt("GUIDataSeparatorChar", $sDataSeparatorChar)

    [/autoit] [autoit][/autoit] [autoit]

    Return 1
    EndFunc

    [/autoit]

    ein Danke im Vorraus

    2 Mal editiert, zuletzt von tztztz (4. April 2014 um 10:27)

  • das hatte ich probiert, gab keinen Unterschied.

    Was ich vergessen hatte zu erwähnen: wenn ich den Speicherknopf drücke in dem 2ten GUI, dann werden beim Drücken des Schließen Knopfes beide Fenster geschlossen, falls ich nur den 2ten GUI schließe, ohne vorher zu speichern schließt sich nur der 2te GUI und der erste ist wie beschrieben eingefroren

  • Hatte mich zwar nicht weitergebracht, mittlerweile ist das Problem allerdings erledigt (umgangen).
    Hab im Button einfach einen Befehl zum Script neu laden eingebaut, dadurch den Effekt den ich wollte.

  • Hallo tztztz,

    das Problem ist, dass Dein Programm aus der Hauptendlosschleife, die das erste GUI auf Events abfragt, heraus die Funktion aufruft, sodass diese Schleife nicht mehr aus bzw. in der Funktion verlassen werden kann. Folglich befindest sich das Programm im Anschluss daran (d. h. nach Eintreten in die zweite und somit innere Endlosschleife, die für das zweite GUI zuständig ist,) lediglich und permanent in dieser Schleife, sodass auf Events aus dem ersten GUI nicht mehr reagiert werden kann.

    Deshalb hier zwei mögliche Lösungen:

    • Verlassen der inneren Schleife.
    • Verwenden des GUIOnEventModes ([autoit]Opt()[/autoit]).