ListView: Wieder ein Problem

    • Offizieller Beitrag

    Also wenn du mit _GUICtrlListView_Create() arbeitest, hast du keine Chance Items farbig zu markieren. Zumindest habe ich bisher keine Möglichkeit gefunden.
    Das Konzept dieser neuen (besch...) ListViewfunktionen basiert darauf, dass die Items keine einzelnen Controls mehr sind. Somit kannst du sie ausschließlich über den Index ansprechen.
    Ich vermeide es tunlichst die neuen ListViewfunktionen zu verwenden.

  • Carsten8
    das Script aus dem englischen Forum verstehe ich auch nicht.
    Vielleichts raffts ja ein anderer :)

  • Hi! Ich habs so einigermaßen gerafft.
    Hier kann man jetzt einzelne Zeilen färben :)
    // Edit: sry, irgendwas fehlt noch, hab wohl zu viel gelöscht :(
    //Edit: Jetzt gehts :)

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7
    Opt("MustDeclareVars", 1)
    #include <GuiConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiImageList.au3>
    #include <GuiStatusbar.au3>
    #include <Constants.au3>
    ;---------------------------
    ; Saves the ListViewItem Background Colors
    Global $_ListView_BKColors[1]
    ;---------------------------
    Global Const $tagNMLVCUSTOMDRAW = "hwnd hWndFrom;int IDFrom;int Code;dword dwDrawStage;hwnd hdc;int Left;int Top;int Right;int Bottom;" & _
    "dword dwItemSpec;uint uItemState;long lItemlParam;int clrText;int clrTextBk;int iSubItem;dword dwItemType;int clrFace;int iIconEffect;" & _
    "int iIconPhase;int iPartId;int iStateId;int TextLeft;int TextTop;int TextRight;int TextBottom;uint uAlign"
    Global Const $CDDS_PREPAINT = 0x00000001
    Global Const $CDDS_ITEMPREPAINT = 0x00010001
    Global Const $CDRF_NEWFONT = 0x00000002
    Global Const $CDRF_NOTIFYITEMDRAW = 0x00000020
    #region Globals *************************************************************************
    Global $hDragImageList, $h_ListView, $bDragging = False, $LV_Height, $StatusBar1
    Global $a_index[2] ; from and to
    Global Const $DebugIt = 1
    #endregion End Global variables
    Opt("WinTitleMatchMode", 2)
    _TestDragItemWithImages()
    Func _TestDragItemWithImages()
    Local Const $image_width = 20
    Local Const $image_height = 20
    Local $h_images, $main_GUI, $iIndex

    $main_GUI = GUICreate("GuiRegisterMsg Test", 225, 400)

    $h_ListView = _GUICtrlListView_Create($main_GUI, "Entry Name|Category", 5, 75, 220, 280, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE))
    $LV_Height = 280 - 75
    _GUICtrlListView_SetColumnWidth($h_ListView, 0, 100)
    _GUICtrlListView_SetColumnWidth($h_ListView, 1, 100)
    _GUICtrlListView_SetExtendedListViewStyle($h_ListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES))

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

    ;-----------------------------------------------------
    ;Register WM_NOTIFY events
    ;Here the ListView-Background-Colors will be painted.
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    ;------------------------------------------------------

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

    Local $y = 1
    For $x = 0 To 9
    $iIndex = _GUICtrlListView_AddItem($h_ListView, "Name " & $x + 1, $y) ; handle, string, image index
    _GUICtrlListView_AddSubItem($h_ListView, $iIndex, "Category " & $x + 1, 1, $y + 1) ; handle, index, string, subitem, image index
    $y += 2
    Next
    _ListView_SetItemColor($h_ListView,0x0000FF,2)
    _ListView_SetItemColor($h_ListView,0x00FF00,1) ; Sets the BG- Color
    GUISetState()
    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd
    EndFunc ;==>_TestDragItemWithImages

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

    ;
    ; WM_NOTIFY event handler
    Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tNMHDR, $code, $x, $y, $tNMLISTVIEW, $hwndFrom, $tDraw, $dwDrawStage, $dwItemSpec, $test
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam) ;NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $code = DllStructGetData($tNMHDR, "Code")
    $hwndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Switch $hwndFrom
    ;---------------------------------------------------------
    Case $h_ListView ;---------> Here goes the ListView Gui-Variable
    ;---------------------------------------------------------
    Switch $code
    Case $NM_CUSTOMDRAW
    ;~ If $DebugIt Then _DebugPrint("$NM_CUSTOMDRAW")
    $tDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
    $dwDrawStage = DllStructGetData($tDraw, "dwDrawStage")
    $dwItemSpec = DllStructGetData($tDraw, "dwItemSpec")
    Switch $dwDrawStage
    Case $CDDS_PREPAINT
    Return $CDRF_NOTIFYITEMDRAW
    Case $CDDS_ITEMPREPAINT
    If $dwItemSpec < UBound($_ListView_BKColors) Then
    If IsNumber($_ListView_BKColors[$dwItemSpec]) Then DllStructSetData($tDraw, "clrTextBk", $_ListView_BKColors[$dwItemSpec])
    EndIf
    Return $CDRF_NEWFONT
    EndSwitch
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY
    #endregion Event Function(s)

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

    Func _ListView_SetItemColor($ListView, $Color, $Index, $redraw = 1)
    ReDim $_ListView_BKColors[_GUICtrlListView_GetItemCount($ListView)+1]
    If Not ($Index < UBound($_ListView_BKColors)) Then Return Seterror(1,0,0)
    $_ListView_BKColors[$Index] = $Color

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

    If $Color = Default Then $_ListView_BKColors[$Index]=""
    If $redraw Then DLLCAll("user32.dll","int","RedrawWindow","hwnd", $ListView,"int",0,"int",0,"int",0x1)
    EndFunc ; <--| _ListView_SetItemColor

    [/autoit]

    Einmal editiert, zuletzt von progandy (27. Dezember 2007 um 17:56)

  • Aha, wäre denke ich sinnvoll, wenn du noch erklären würdest was davon genau warum gefärbt wird.

    Kann ich damit auch alle Einträge des ListView erstellen und dann anschließend die Felder je nach Wert (z. B. <50 rot, >=50 gelb) ändern?

  • Ok, ich versuchs mal zu erkären.
    1) Ich erstelle ein Array, das die gleiche Zahl an Einträgen hat, wie das ListView
    2) Dem Index, der gefärbt werden soll, wird im Array die Farbe in der Form BGR zugewiesen.
    3) Beim Event WM_NOTIFY :
    Ist es der ListView-Handle
    -> Ja
    ..-> Ist der Code $NM_CUSTOMDRAW?
    ..-> Ja
    ....->Ist der Item-Index im Array?
    ....-> Ja
    ......-> Wenn der Array-Index eine Zahl und damit leer ist, wird die Hintergrundfarbe auf den Wert aus dem Array gesetzt.
    Wenn irgendwo die Bedingung nicht stimmt, wird nichts gemacht.

    Und warum das so geht: Keine Ahnung. Das mit dem Array war meine Idee, der Rest war schon im Beispiel aus dem eng. Forum vorhanden
    Ja, die Farbe wird erst nach der Erstellung gesetzt. Du musst eben immer machen:
    For $item = 0 To ItemCount
    If TextofItem($Listview,$item) < 50 Then SetItemColor($Listview,$item, 0x0000FF ;Rot (BLAU-GRÜN-ROT)
    If TextofItem($Listview,$item) >= 50 Then SetItemColor($Listview,$item, 0x00FFFF ;Gelb (BLAU-GRÜN-ROT)
    EndIf

  • Nochmal was: Nach dem Farbe setzen muss man das GUI-Window neu zeichnen lassen.
    Einfach:
    GUISetState(@SW_HIDE)
    GUISetState()
    oder

    [autoit]

    DLLCAll("user32.dll","int","RedrawWindow","hwnd",$main_GUI,"int",0,"int",0,"int",0x1)

    [/autoit]

    //Edit: Ich habs jetzt in die Funktion mit eingebaut. Es kann durch den optionalen Paramnter $redraw abgeschaltet werden. Dazu wird er auf 0 gesetzt.

  • Juhuu es klappt ^^
    Hab folgende Teile aus dem Script übernommen (zwei Zeilen hab ich noch dazu und zwar die, die die Liste neuladen):

    [autoit]


    Global $_ListView_BKColors[1]
    Global Const $tagNMLVCUSTOMDRAW = "hwnd hWndFrom;int IDFrom;int Code;dword dwDrawStage;hwnd hdc;int Left;int Top;int Right;int Bottom;" & _
    "dword dwItemSpec;uint uItemState;long lItemlParam;int clrText;int clrTextBk;int iSubItem;dword dwItemType;int clrFace;int iIconEffect;" & _
    "int iIconPhase;int iPartId;int iStateId;int TextLeft;int TextTop;int TextRight;int TextBottom;uint uAlign"
    Global Const $CDDS_PREPAINT = 0x00000001
    Global Const $CDDS_ITEMPREPAINT = 0x00010001
    Global Const $CDRF_NEWFONT = 0x00000002
    Global Const $CDRF_NOTIFYITEMDRAW = 0x00000020
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    _ListView_SetItemColor($List,0x0000FF,2) ;Lege Item 1 und 2 für die markierung fest
    _ListView_SetItemColor($List,0x00FF00,1) ;s.o.
    $itemcount = _GUICtrlListView_GetItemCount($List) ;Lade Liste neu und markiere Items
    _GUICtrlListView_RedrawItems($List, 0, $itemcount) ;s.o.

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

    Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tNMHDR, $code, $x, $y, $tNMLISTVIEW, $hwndFrom, $tDraw, $dwDrawStage, $dwItemSpec, $test
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam) ;NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $code = DllStructGetData($tNMHDR, "Code")
    $hwndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Switch $hwndFrom
    ;---------------------------------------------------------
    Case $List ;---------> Here goes the ListView Gui-Variable
    ;---------------------------------------------------------
    Switch $code
    Case $NM_CUSTOMDRAW
    ;~ If $DebugIt Then _DebugPrint("$NM_CUSTOMDRAW")
    $tDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
    $dwDrawStage = DllStructGetData($tDraw, "dwDrawStage")
    $dwItemSpec = DllStructGetData($tDraw, "dwItemSpec")
    Switch $dwDrawStage
    Case $CDDS_PREPAINT
    Return $CDRF_NOTIFYITEMDRAW
    Case $CDDS_ITEMPREPAINT
    If $dwItemSpec < UBound($_ListView_BKColors) Then
    If IsNumber($_ListView_BKColors[$dwItemSpec]) Then DllStructSetData($tDraw, "clrTextBk", $_ListView_BKColors[$dwItemSpec])
    ;MsgBox(0,"", $hWndGUI & @CRLF & $MsgID & @CRLF & $wParam & @CRLF & $lParam)
    EndIf
    Return $CDRF_NEWFONT
    EndSwitch
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]

    DANKESCHÖN (das Forum hier gefällt mir immer besser ^^)

  • Man kann auch noch die Schriftfarbe ändern:

    [autoit]

    If $dwItemSpec < UBound($_ListView_BKColors) Then
    If IsNumber($_ListView_BKColors[$dwItemSpec]) Then DllStructSetData($tDraw, "clrTextBk", $_ListView_BKColors[$dwItemSpec])
    ;MsgBox(0,"", $hWndGUI & @CRLF & $MsgID & @CRLF & $wParam & @CRLF & $lParam)
    EndIf

    [/autoit]


    zu

    [autoit]

    If $dwItemSpec < UBound($_ListView_BKColors) Then
    If IsNumber($_ListView_BKColors[$dwItemSpec]) Then DllStructSetData($tDraw, "clrTextBk", $_ListView_BKColors[$dwItemSpec])
    ;MsgBox(0,"", $hWndGUI & @CRLF & $MsgID & @CRLF & $wParam & @CRLF & $lParam)
    EndIf
    If $dwItemSpec < UBound($_ListView_ForeColors) Then
    If IsNumber($_ListView_ForeColors[$dwItemSpec]) Then DllStructSetData($tDraw, "clrText", $_ListView_ForeColors[$dwItemSpec])
    ;MsgBox(0,"", $hWndGUI & @CRLF & $MsgID & @CRLF & $wParam & @CRLF & $lParam)
    EndIf

    [/autoit]


    und zusätzlich die Funktion:

    [autoit]

    Func _ListView_SetItemFontColor($ListView, $Color, $Index, $redraw = 1)
    ReDim $_ListView_ForeColors[_GUICtrlListView_GetItemCount($ListView)+1]
    If Not ($Index < UBound($_ListView_ForeColors)) Then Return Seterror(1,0,0)
    $_ListView_ForeColors[$Index] = $Color

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

    If $Color = Default Then $_ListView_ForeColors[$Index]=""
    If $redraw Then DLLCAll("user32.dll","int","RedrawWindow","hwnd", $ListView,"int",0,"int",0,"int",0x1)
    EndFunc ; <--| _ListView_SetItemColor

    [/autoit]


    Und am Anfang des Skripts

    [autoit]

    Global $_ListView_ForeColors[1]

    [/autoit]