Listview "flackern" und Farbenbug

  • Hi Leute^^
    Habe ein problem mit meinem Listview, dieses wird regelmäßig komplett aktualisiert, der Funktionscode ist folgender:

    [autoit]


    Func load()
    _GUICtrlListView_DeleteAllItems($ListView1)
    _FileReadToArray("temp.txt",$array)
    For $i=0 To $array[0] Step +1
    If StringRegExp($array[$i],"TCP") Then
    $strip=StringStripWS($array[$i],4)
    $split=StringSplit($strip," ")
    $protokoll=$split[2]
    $lokal=$split[3]
    $remote=$split[4]
    $status=$split[5]
    $view=GUICtrlCreateListViewItem($protokoll&"|"&$lokal&"|"&$remote&"|"&$status,$ListView1)
    If $status="HERGESTELLT" Then GUICtrlSetBkColor($view,0x00EE00)
    If $status="SCHLIESSEN_WARTEN" Or $status="WARTEND" Then GUICtrlSetBkColor($view,0xFFC125)
    Endif
    Next
    Endfunc

    [/autoit]

    Dieser erzeugt allerdings bei jeder ausführung ein Flackern und setzt die Scrollbar zurück, ausserdem wird die Farbe vom einem Listviewitem bis zur nächsten ausführung zur hälfte "gelöscht" das Listview habe ich so erstellt:

    [autoit]


    $ListView1 = GUICtrlCreateListView("Protokoll|Lokale Adresse|Remoteadresse|Status", 8, 8, 513, 225, -1, Bitor($LVS_EX_DOUBLEBUFFER,$LVS_EX_GRIDLINES))

    [/autoit]

    Hier noch ein Screen von der kaputten Farbe:
    [Blockierte Grafik: http://img812.imageshack.us/img812/9523/picd.jpg]

    Hoffe jemand kennt die Lösung :D

    MfG Sumsum

  • weißte was jetzt geil wäre?ein komplett laufendes script!das wär jetzt der traum meiner zauberkugel!sie würde sofort mit lösungen überquillen!

    achja, das flackern liegt am löschen aller einträge!

  • Also schonmal danke AutoBert für die Lösung^^,
    aber wie gesagt muss ich halt alle Listviewitems immer löschen, daher kommt denke ich das flackern.

    Ich poste hier mal das komplette Script:

    [autoit]

    #include <Process.au3>
    #include <File.au3>
    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <WindowsConstants.au3>
    #include <GUIListview.au3>
    #include <Coproc.au3>
    Global $array,$items[999],$c=0
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Netstat Formater", 530, 245, 192, 124)
    $ListView1 = GUICtrlCreateListView("Protokoll|Lokale Adresse|Remoteadresse|Status", 8, 8, 513, 225, -1, Bitor($LVS_EX_DOUBLEBUFFER,$LVS_EX_GRIDLINES))
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 60)
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 50)
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 50)
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 50)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    _RunDOS('netstat -p TCP > "'&@ScriptDir&'\temp.txt"')
    Do
    sleep(100)
    Until FileExists("temp.txt") And not ProcessExists("netstat.exe")
    _FileReadToArray("temp.txt",$array)
    For $i=0 To $array[0] Step +1
    If StringRegExp($array[$i],"TCP") Then
    $strip=StringStripWS($array[$i],4)
    $split=StringSplit($strip," ")
    $protokoll=$split[2]
    $lokal=$split[3]
    $remote=$split[4]
    $status=$split[5]
    $view=GUICtrlCreateListViewItem($protokoll&"|"&$lokal&"|"&$remote&"|"&$status,$ListView1)
    If $status="HERGESTELLT" Then GUICtrlSetBkColor($view,0x00EE00)
    If $status="SCHLIESSEN_WARTEN" Or $status="WARTEND" Then GUICtrlSetBkColor($view,0xFFC125)
    EndIf
    Next

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

    $pid=_Coproc("update")
    AdlibRegister("load",5000)
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    ProcessClose($pid)
    Exit

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

    EndSwitch
    WEnd

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

    Func update()
    _RunDOS('netstat -p TCP > "'&@ScriptDir&'\temp.txt"')
    Do
    sleep(100)
    Until FileExists("temp.txt") And not ProcessExists("netstat.exe")
    Endfunc

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

    Func load()
    _GUICtrlListView_DeleteAllItems($ListView1)
    _FileReadToArray("temp.txt",$array)
    For $i=0 To $array[0] Step +1
    If StringRegExp($array[$i],"TCP") Then
    $strip=StringStripWS($array[$i],4)
    $split=StringSplit($strip," ")
    $protokoll=$split[2]
    $lokal=$split[3]
    $remote=$split[4]
    $status=$split[5]
    $view=GUICtrlCreateListViewItem($protokoll&"|"&$lokal&"|"&$remote&"|"&$status,$ListView1)
    If $status="HERGESTELLT" Then GUICtrlSetBkColor($view,0x00EE00)
    If $status="SCHLIESSEN_WARTEN" Or $status="WARTEND" Then GUICtrlSetBkColor($view,0xFFC125)
    Endif
    Next
    Endfunc

    [/autoit]

    Auch weil ich die Funktion
    _GUICtrlListView_AddArray
    Nicht richtig verstehe, jedenfalls nicht in dem Zusammenhang.

    Einmal editiert, zuletzt von sumsum (5. Juli 2010 um 21:13)

  • Ich denke, dass gerade der Farbunterschied von z.B. Grün gegenüber Weiß durch Neuzeichnen zum Flackern führt, soviel zum Doublebuffering ;-).
    Wie wäre es, wenn du statt alle Elemente zu löschen, diese lediglich überschreiben würdest. Mit _GUICtrlListView_SetItemText(), _GUICtrlListView_GetItem() und _GUICtrlListView_SetBkColor() bzw. _GUICtrlListView_SetTextBkColor() lässt sich doch sicher alles machen.

    Damit die Liste nicht unnötige Einträge hat, kann man nach update den Rest löschen. Dann bleibt es auch weiß, somit gibt es kein Flackern.

    Einmal editiert, zuletzt von viktorkl (6. Juli 2010 um 01:34)

  • Auch weil ich die Funktion
    _GUICtrlListView_AddArray
    Nicht richtig verstehe, jedenfalls nicht in dem Zusammenhang.


    ich habe einmal ein Beispiel von mir umgeschrieben (Laden klicken)

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <File.au3>

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

    ;#include <array.au3>

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

    Local $tZeit, $s1, $s2

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

    $main = GUICreate("Test Drag & Drop from LV1 to LV2 DblClick in LV1 with ContextMenu in LV1 (copies to ClipBoard", 600, 400)
    $listview = GUICtrlCreateListView("Gruppe1| BlubText", 10, 10, 200, 100, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS), BitOR($LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE))
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE) ; legt fest, dass Hintergrundfarbe wechselt
    GUICtrlSetBkColor(-1, 0xE6E6FA) ; Hintergrundfarbe 1

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

    $listview2 = GUICtrlCreateListView("Gruppe2 | BlubText", 230, 10, 200, 100, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS), BitOR($LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE))
    GUICtrlSetState($listview2, $GUI_DROPACCEPTED)
    $hbtnInfo = GUICtrlCreateButton("Info", 10, 120, 100, 20)
    $hbtnSave = GUICtrlCreateButton("&Speichern", 230, 120, 100, 20)
    $hbtnLoad = GUICtrlCreateButton("&Laden", 230, 150, 100, 20)

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

    For $i = 1 To 9
    $listitem = GUICtrlCreateListViewItem("test" & $i & " |Blub " & Random(1, 9), $listview)
    If $i = 5 Then GUICtrlSetFont($listitem, 14, 800)
    GUICtrlSetBkColor(-1, 0xcccccc) ; Hintergrundfarbe 2
    Next
    $idContextmenu = GUICtrlCreateContextMenu($listview)
    $idClipmenu = GUICtrlCreateMenuItem("Selektierte ins ClipBoard", $idContextmenu)
    $idAllClipmenu = GUICtrlCreateMenuItem("Alle aus Splate 2 ins ClipBoard", $idContextmenu)
    $idDragmenu = GUICtrlCreateMenuItem("In LV 2", $idContextmenu)

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

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;<=========================================== Bemachrichtigung Doppelklick
    GUISetState()
    $first = True
    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_DROPPED, $idDragmenu
    $ar = _GUICtrlListView_GetSelectedIndices($listview, True)
    ;_ArrayDisplay($ar)
    For $i = 1 To $ar[0]
    $sItem = _GUICtrlListView_GetItemTextString($listview, $ar[$i])
    GUICtrlCreateListViewItem($sItem, $listview2)
    Next
    Case $hbtnInfo
    $Wert = _GUICtrlListView_GetItemTextArray($listview)
    If $Wert[2] <> "" Then
    MsgBox(0, "Eintrag für " & $Wert[1], "ist: " & $Wert[2])
    Else
    MsgBox(0, "", "Kein Eintrag ausgewählt")
    EndIf
    Case $hbtnSave
    SaveLV(@ScriptDir & "\LV2.TXT")
    Case $hbtnLoad
    LoadLV(@ScriptDir & "\LV2.TXT")
    Case $idClipmenu
    $aItems = _GUICtrlListView_GetSelectedIndices($listview, True)
    $sItemText = ""
    For $i = 1 To $aItems[0]
    ;Schleifenbeginn 1 da $aItem[0] die Anzahl enhält
    $sItemText &= _GUICtrlListView_GetItemTextString($listview, $aItems[$i]) & @CRLF
    ConsoleWrite($sItemText & @CRLF)
    Next ;= > weiter mit For
    ;ClipPut($sItemText & @CRLF)
    Case $idAllClipmenu
    $sToClip = ""
    For $i = 0 To _GUICtrlListView_GetItemCount($listview)
    $aItem = _GUICtrlListView_GetItemTextArray($listview, $i)
    $sToClip &= $aItem[2] & @CRLF
    Next
    ClipPut($sToClip)
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

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

    Func SaveLV($sFile)
    Local $hFileOut, $aItem
    $hFileOut = FileOpen($sFile, 2)
    For $j = 0 To _GUICtrlListView_GetItemCount($listview2) - 1
    $aItem = _GUICtrlListView_GetItemTextString($listview2, $j)
    FileWriteLine($hFileOut, $aItem)
    Next
    FileClose($hFileOut)
    EndFunc ;==>SaveLV

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

    #cs
    Func LoadLV($sFile)
    Local $aItems
    If FileExists($sFile) Then
    _FileReadToArray($sFile, $aItems)
    If IsArray($aItems) Then
    _GUICtrlListView_DeleteAllItems($listview2)
    ;_ArrayDisplay($aItems)
    For $j = 1 To $aItems[0]
    GUICtrlCreateListViewItem($aItems[$j], $listview2)
    Next
    EndIf
    EndIf
    EndFunc ;==>LoadLV
    #ce

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

    Func LoadLV($sFile) ;zur Demo von _GUICtrlListView_AddArray
    Local $aItems, $aItem, $aItemsNew
    If FileExists($sFile) Then
    _FileReadToArray($sFile, $aItems)
    If IsArray($aItems) Then
    _ArrayDelete($aItems, 0)
    If IsArray($aItems) Then; könnte nach löschen von Eintrag 0 ja leer sein
    Dim $aItemsNew[UBound($aItems)][2]
    _GUICtrlListView_DeleteAllItems($listview2)
    ;_ArrayDisplay($aItems)
    For $i = 0 to UBound($aItems) -1 ;Array mit Daten füllen
    $aItem = StringSplit($aItems[$i],"|",2)
    ;ConsoleWrite($i & @CRLF)
    $aItemsNew[$i][0] = $aItem[0]
    $aItemsNew[$i][1] = $aItem[1]
    Next
    _ArrayDisplay($aItemsNew)
    _GUICtrlListView_AddArray($listview2, $aItemsNew) ;<===== Array ins LV einfügen
    EndIf
    EndIf
    EndIf
    EndFunc ;==>LoadLV

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

    Func WM_NOTIFY($hWnd, $MsgID, $wParam, $lParam)
    Local $tagNMHDR, $event, $hwndFrom, $code
    $tagNMHDR = DllStructCreate("int;int;int", $lParam)
    If @error Then Return 0
    $code = DllStructGetData($tagNMHDR, 3)
    If $wParam = $listview Then
    ConsoleWrite($code & @CRLF)
    Switch $code
    ;case -2 ;Klick
    Case -3 ;Doppelklick
    If _GUICtrlListView_GetSelectedCount($listview) > 0 Then
    For $i = 0 To _GUICtrlListView_GetItemCount($listview)
    If _GUICtrlListView_GetItemSelected($listview, $i) Then
    $aItem = _GUICtrlListView_GetItemTextArray($listview, $i)
    MsgBox(0, "Doppel-Klick auf ", $aItem[1] & @CRLF & @CRLF & $aItem[2])
    EndIf
    Next
    EndIf
    EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]

    Die dazu gehörige Textdatei: autoit.de/wcf/attachment/10588/

    mfg (Auto)Bert