ListView - SubItem einzeln färben/formatieren, Finale Version! (v1.3)

  • BugFix besten Dank! Dann bau ich das mal diese Woche alles um. Auch habe ich noch nen DoubleClick-Handler von Dir entdeckt, den werde ich auch versuchen mit einzubauen.

    Besten Dank nochmal und weiterhin happy computing!
    R@iner

    • Offizieller Beitrag

    Neue Version:

    - keine Begrenzung der Spaltenzahl mehr!
    - Auch bei mehreren Listview werden alle Formatierungsdaten in einem Array verwaltet
    - die Prüfung, ob ein (Sub)Item formatiert ist, läuft wesentlich schneller
    - Management zur Verwaltung der Formatinfos zu den Items ist integriert (UDF-Funktionen angepaßt)
    - Listview kann sortiert, Einträge können eingefügt, gelöscht werden etc.

    Details s. Bsp. 5_LV_Format.au3 in Post 1

  • Ja ich weis Forenleichenschänder ;), aber muss einfach sein.

    Ich habe folgendes Testscript erstellt:

    Spoiler anzeigen
    [autoit]

    #include <LV_Format_include.au3>
    #include <ListViewConstants.au3>
    #region ### START Koda GUI section ### Form=
    $hauptform = GUICreate("Form1", 1018, 740, -1, 20)
    $wert1 = GUICtrlCreateButton("Wert 1", 8, 8, 75, 25)
    $wert2 = GUICtrlCreateButton("Wert 2", 8, 40, 75, 25)

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

    $planeten = GUICtrlCreateListView(" ", 8, 168, 1002, 565, $LVS_NOSORTHEADER)
    _GUICtrlListView_Formatting_Startup($hauptform, $planeten)

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

    _GUICtrlListView_AddOrIns_Item($planeten, ' Wert1')
    _GUICtrlListView_FormattingCell($planeten, 0, 0, -1, 0xff0000, 15, -1, 'Arial')
    _GUICtrlListView_AddOrIns_Item($planeten, ' Wert2')
    _GUICtrlListView_FormattingCell($planeten, 1, 0, -1, 0xff0000, 15, -1, 'Arial')

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

    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $wert1
    _GUICtrlListView_FormattingCell($planeten, 0, 0, -1, 0x006633, 15, -1, 'Arial')
    Case $wert2
    _GUICtrlListView_FormattingCell($planeten, 1, 0, -1, 0x006633, 15, -1, 'Arial')
    EndSwitch
    WEnd

    [/autoit]

    Problem ist nun, dass wenn man einen Button drückt sich die Farbe des entsprechenden Listview eintrages erst dann ändert, wenn man im Anschluss nochmal den Eintrag im Listview anklickt. Gibt es eine Möglichkeit das diese zusätzliche klicken auf den Eintrag nichtmehr nötig ist?

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    • Offizieller Beitrag

    dass wenn man einen Button drückt sich die Farbe des entsprechenden Listview eintrages erst dann ändert, wenn man im Anschluss nochmal den Eintrag im Listview anklickt.


    Du bist wahrscheinlich der erste, der keine Änderung der Hintergrundfarbe vornimmt. :D Hatte ich niemals bewußt allein geprüft, da das Färben des Hintergrundes im Vordergrund der UDF stand.
    Stimmt, die Überprüfung, ob das Subitem neu gezeichnet werden muß berücksichtigte nicht, dass evtl. nur die Vordergrundfarbe geändert wird. Hab das jetzt angepaßt.
    Tausche mal in der LV_Format_include.au3 die folgende Funktion aus, dann paßt es:

    _GUICtrlListView_FormattingCell
    [autoit]

    Func _GUICtrlListView_FormattingCell($hWnd, $iItem, $iSubItem, $iBkCol=-1, $iCol=-1, $iSize=-1, $iWeight=-1, $sFont=-1)
    Local $sumParam = 0
    Local $iParam = _GUICtrlListView_GetItemParam($hWnd, $iItem)
    Local $index = $oParamSearch.Item($iParam)
    If $iBkCol = -1 Then
    $iBkCol = $defBkColLV
    $sumParam += 1
    EndIf
    If $iCol = -1 Then
    $iCol = $defColLV
    $sumParam += 1
    EndIf
    If $iSize = -1 Then
    $iSize = $defSize
    $sumParam += 1
    EndIf
    If $iWeight = -1 Then
    $iWeight = $defWeight
    $sumParam += 1
    EndIf
    If $sFont = -1 Then
    $sFont = $defFont
    $sumParam += 1
    EndIf
    $aIParam[$index][$iSubItem+1][0] = $iBkCol
    $aIParam[$index][$iSubItem+1][1] = $iCol
    $aIParam[$index][$iSubItem+1][2] = $iSize
    $aIParam[$index][$iSubItem+1][3] = $iWeight
    $aIParam[$index][$iSubItem+1][4] = $sFont
    ; if SubItem not registered in IParam OR all values by -1 (delete Sub from IParam) ==> switch Sub value in IParam
    Local $mark = DllStructGetData($aIParam[$index][0][0], 2, $iSubItem+1)
    If Not $mark Or $sumParam = 5 Then
    DllStructSetData($aIParam[$index][0][0], 2, BitXOR($mark, 1), $iSubItem+1)
    EndIf
    ;~ If DllStructGetData($aIParam[$index][0][0], 2, $iSubItem+1) <> $mark Then
    If DllStructGetData($aIParam[$index][0][0], 2, $iSubItem+1) <> $mark Or $sumParam <> 5 Then
    _GUICtrlListView_RedrawItems($hWnd, $iItem, $iItem)
    EndIf
    EndFunc ;==>_GUICtrlListView_FormattingCell

    [/autoit]
  • Jetzt habe ich doch noch ein Problem. Wenn ich ein Subitem, welches mit _GUICtrlListView_AddSubItem hinzugefügt wurde, umfärben will kommt immer der Fehler:

    Zitat

    C:\Program Files (x86)\AutoIt3\Include\LV_Format_include.au3 (209) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    $aIParam[$index][$iSubItem+1][0] = $iBkCol
    ^ ERROR


    Hier das entsprechendes Testscript:

    Spoiler anzeigen
    [autoit]

    #include <LV_Format_include.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <GUIConstantsEx.au3>

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

    #region ### START Koda GUI section ### Form=
    $hauptform = GUICreate("Form1", 1018, 740, -1, 20)
    $planeten = GUICtrlCreateListView(" ", 8, 168, 1002, 565, $LVS_NOSORTHEADER)
    _GUICtrlListView_Formatting_Startup($hauptform, $planeten)

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

    _GUICtrlListView_AddOrIns_Item($planeten, 'Statisch')
    _GUICtrlListView_FormattingCell($planeten, 0, 0, -1, -1, 15, -1, 'Arial Black')
    _GUICtrlListView_AddOrIns_Item($planeten, ' eins')
    _GUICtrlListView_FormattingCell($planeten, 1, 0, -1, -1, 15, -1, 'Arial Black')
    _GUICtrlListView_AddOrIns_Item($planeten, ' zwei')
    _GUICtrlListView_FormattingCell($planeten, 2, 0, -1, -1, 15, -1, 'Arial Black')

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

    _GUICtrlListView_AddColumn($planeten, "colum", 80)

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

    _GUICtrlListView_AddSubItem($planeten, 1, "test", 1)
    _GUICtrlListView_AddSubItem($planeten, 2, "test", 1)
    _GUICtrlListView_FormattingCell($planeten, 1, 1, 0xFFFFFF, 0xFFFFFF, 15, -1, 'Arial')

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

    _GUICtrlListView_AddColumn($planeten, "Gesamt", 80)

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

    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()

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

    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    EndSwitch
    WEnd

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

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    • Offizieller Beitrag

    Jetzt habe ich doch noch ein Problem. Wenn ich ein Subitem, welches mit _GUICtrlListView_AddSubItem hinzugefügt wurde, umfärben will kommt immer der Fehler:


    Das ist auch völlig korrekt. Beim StartUp ( _GUICtrlListView_Formatting_Startup($hGUI, $hListView) ) wird die Spaltenzahl des/der verwendeten Listview ausgelesen und anhand dieser Werte das Array $aIParam erstellt. Wenn du später eine Spalte hinzufügst, ist dafür im Array kein Platz reserviert und der Fehler tritt auf.
    Ich möchte auch ungern diesen Schritt variabel gestalten, da eine ständige zusätzliche Überprüfung auf neue Spalten in allen betroffenen Funktionen auch einen erheblichen (zeitlichen) Mehraufwand im Programmablauf darstellt.
    Ich denke mal, es ist auch keine allzu große Hürde beim Programmieren, die Spaltenzahl zuerst festzulegen. ;)

  • Mh ok dann muss ich schauen ob ich da selbst reinbauen kann, weil die Spalzenanzahl zumindestens bei mir nicht fest ist :).

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    • Offizieller Beitrag

    Mh ok dann muss ich schauen ob ich da selbst reinbauen kann, weil die Spalzenanzahl zumindestens bei mir nicht fest ist :).


    In der Funktion _GUICtrlListView_Formatting_Startup wird die Größe von $aIParam unter anderem anhand der größten verwendeten Spaltenzahl (bei mehreren Listview) definiert.

    [autoit]

    Global $aIParam[1][$maxColumn+1][5] ; [n][0][0]=ItemStruct, [n][1..Count][0..4]=SubItemValue

    [/autoit]

    Hier kannst du aber durchaus auch vorab z.B. das mögliche Maximum festlegen (also z.B. 32 ). Dann sollte dein Problem gelöst sein. Aber beachten: Immer 1 größer als die max. Anzahl an Spalten!

  • Du kannst sicher auch eine Funktion definieren, die die Spaltenzahl aktualisiert. Wozu gibt es ReDim?


  • In der Funktion _GUICtrlListView_Formatting_Startup wird die Größe von $aIParam unter anderem anhand der größten verwendeten Spaltenzahl (bei mehreren Listview) definiert.

    [autoit]

    Global $aIParam[1][$maxColumn+1][5] ; [n][0][0]=ItemStruct, [n][1..Count][0..4]=SubItemValue

    [/autoit]

    Hier kannst du aber durchaus auch vorab z.B. das mögliche Maximum festlegen (also z.B. 32 ). Dann sollte dein Problem gelöst sein. Aber beachten: Immer 1 größer als die max. Anzahl an Spalten!

    Hatte ich sogar auch schon probier gehabt. Allerdings hats bei mir keinerleih unterschied gemacht gehabt was ich statt $maxColumn eingetragen hatte. Hatte es dann, wie progandy ja auch noch gepostet hat, mit einer Funktion über Redim erweitert.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    • Offizieller Beitrag

    Hatte ich sogar auch schon probier gehabt. Allerdings hats bei mir keinerleih unterschied gemacht gehabt was ich statt $maxColumn eingetragen hatte. Hatte es dann, wie progandy ja auch noch gepostet hat, mit einer Funktion über Redim erweitert.


    Ich hab mir das nochmal angeschaut:
    Ist wesentlich umfangreicher als nur ein ReDim.
    - Hat das Listview jetzt eine größere Anzahl Spalten als in $maxColumn gespeichert, ist dieser Wert zu erhöhen und das Verwaltungsarray mit den Formatinformationen muß vergrößert werden.
    - Wird die Spalte am Ende zugefügt kann das Array so bleiben, wird eingefügt, sind alle existierenden Einträge ab Einfüge-Index um 1 Platz nach hinten zu verschieben, aber nur, wenn in diesem Arrayelement die Info zu dem vergrößerten Listview steht.
    - Wurde $maxColumn vergrößert muß das Bytearray in der Struktur ebenfalls vergrößert werden und in jeder Arraye"zeile" neu eingetragen werden.

    Ich werd mal sehen, ob ich dazu noch eine neue Funktion erstelle.

    • Offizieller Beitrag

    - _GUICtrlListView_AddOrIns_Item - es kann jetzt auch ein Array übergeben werden.
    - Die Performance jetzt etwas flüssiger, Abfragen zum Neuzeichnungen eingefügt
    - neue Funktion _GUICtrlListView_DefaultsGet(), Auslesen der Standardformatierungswerte [$iBkCol, $iCol, $iSize, $iWeight, $sFont]

    s. Post #1

    • Offizieller Beitrag

    Änderung in AutoIt-Version 3.3.8.0 macht folgendes erforderlich:

    [autoit]

    ; statt:
    $FORMATLV_oPARAM_SEARCH.Add( ..., ...)
    $FORMATLV_oPARAM_SEARCH.Item( ..., ...)
    $FORMATLV_oPARAM_SEARCH.Remove( ..., ...)

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

    ; den ersten Parameter als String übergeben:

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

    $FORMATLV_oPARAM_SEARCH.Add( String(...), ...)
    $FORMATLV_oPARAM_SEARCH.Item( String(...), ...)
    $FORMATLV_oPARAM_SEARCH.Remove( String(...), ...)

    [/autoit]