Jump to content

Color a listview item ( UDF )


Terenz
 Share

Go to solution Solved by LarsJ,

Recommended Posts

Hello guys,

How i can color an item added with the _GUICtrlListView?

An example script:

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

$gui = GUICreate("lvtest")
$lv = GUICtrlCreateListView("column 1", 10, 10, 200, 200)
$hlv = GUICtrlGetHandle($lv)
ConsoleWrite("listview id: " & $lv & @CRLF)

GUICtrlCreateListViewItem("item2",$lv)
GUICtrlCreateListViewItem("item3",$lv)
_GUICtrlListView_InsertItem($lv, "item1", 0)

ConsoleWrite(@CRLF & "hlv: " & $hlv & @CRLF & "================" & @CRLF)
For $i = 0 To _GUICtrlListView_GetItemCount($hlv) - 1
    ConsoleWrite("item" & $i + 1 & " param: " & _GUICtrlListView_GetItemParam($hlv, $i) & @CRLF)
    GUICtrlSetBkColor(_GUICtrlListView_GetItemParam($hlv, $i), 0xFF0000)
Next

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

GUICtrlSetBkColor work only for the native GUICtrlCreateList and not for the UDF.

I'm miss something?

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Is a little complicated then i expect, i have try to use _GUICtrlListView_MapIndexToID but not work

Maybe i'll change the question, using native GUICtrlCreateListViewItem is possible to insert an item in a specific position?

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

This is the way posted in FireFox post, if someone know a easier method that not involving WM_NOTIFY ( i'm using GUICtrlRegisterListViewSort, both function are incompatible ) please post it:

#Include <GUIListView.au3>
#Include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $hGUI, $hListView

$hGUI = GUICreate('Test', 300, 200)
$iListView = GUICtrlCreateListView('Items|SubItems', 10, 10, 280, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE)
$hListView = GUICtrlGetHandle($iListView)

For $i = 0 To 9
    _GUICtrlListView_InsertItem($hListView, 'Item' & $i)
    _GUICtrlListView_SetItemText($hListView, $i, 'SubItem' & $i, 1)
    If Mod($i, 2) Then
        _GUICtrlListView_SetItemBkColor($hListView, $i, 0xFF0000, 0)
    Else
        _GUICtrlListView_SetItemBkColor($hListView, $i, 0x005676, 0)
    EndIf
Next
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _GUICtrlListView_SetItemBkColor($hWnd, $iItem, $iColor, $fRedraw = 0)
    If _WinAPI_InProcess($hWnd, $_lv_ghLastWnd) Then
        If _GUICtrlListView_SetItemParam($hWnd, $iItem, BitOR(BitAND($iColor, 0x00FF00), BitShift(BitAND($iColor, 0x0000FF), -16), BitShift(BitAND($iColor, 0xFF0000), 16))) Then
            If $fRedraw Then
                _GUICtrlListView_RedrawItems($hWnd, $iItem, $iItem)
            EndIf
            Return 1
        EndIf
    EndIf
    Return 0
EndFunc   ;==>_GUICtrlListView_SetItemBkColor

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
    Local $iCode = DllStructGetData($tNMHDR, 'Code')
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    Local $tNMLVCD = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage = DllStructGetData($tNMLVCD, 'dwDrawStage')
                    Switch $iDrawStage
                        Case $CDDS_PREPAINT
                            Return $CDRF_NOTIFYITEMDRAW
                        Case $CDDS_ITEMPREPAINT
                            Return $CDRF_NOTIFYSUBITEMDRAW
                        Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
                            DllStructSetData($tNMLVCD, 'clrTextBk', _GUICtrlListView_GetItemParam($hWndFrom, DllStructGetData($tNMLVCD, 'dwItemSpec')))
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

I have found a way to make WM_NOTIFY for bk color and RegistrerListViewSort convive:

#include <GUIListView.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $hGUI, $hListView
Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1

$hGUI = GUICreate('Test', 300, 200)
$iListView = GUICtrlCreateListView('Items|SubItems', 10, 10, 280, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE)
$hListView = GUICtrlGetHandle($iListView)
GUICtrlRegisterListViewSort(-1, "LVSort")

For $i = 0 To 9
    _GUICtrlListView_InsertItem($hListView, 'Item' & $i)
    _GUICtrlListView_SetItemText($hListView, $i, 'SubItem' & $i, 1)
Next
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $iListView
            $bSet = 0
            $nCurCol = $nCol
            GUICtrlSendMsg($iListView, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($iListView), 0)
            DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($iListView), "int", 0, "int", 1)
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
    Local $iCode = DllStructGetData($tNMHDR, 'Code')
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec")
                    $iColorBk = 0xFFFFFF ; reset default
                    If $iItem = 5 Then $iColorBk = 0xC0C0C0
                    DllStructSetData($tCustDraw, "clrTextBk", $iColorBk)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $nResult
    Return $nResult
EndFunc   ;==>LVSort

There is only a problem and i hope someone knows why, when i click on the column for the order the color disapper from that column ( i see a light gray on the colum, maybe created by GUICtrlRegisterListViewSort, probably is that the cause )

Is possible to resolve this?

OK:

2jbmaza.jpg

BAD:

25a2kuo.jpg

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

See if this helps:

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

Global $sub_item, $iItem_Color, $iColor1 = 0xFF0000, $iFlag = 0

_Main()

Func _Main()
        Local $hListView

        GUICreate("ListView Get Item", 400, 300)

        $hListView = GUICtrlCreateListView("", 2, 2, 394, 268)
        _GUICtrlListView_AddColumn($hListView, " Itens", 200)

        GUICtrlCreateListViewItem("Row 1", $hListView)
        $iItem_Color = GUICtrlCreateListViewItem("Changes the color of the line", $hListView)
        GUICtrlCreateListViewItem("Row 3", $hListView)

        GUISetState()

        AdlibRegister("_ItemColor", 500)
        Do

        Until GUIGetMsg() = $GUI_EVENT_CLOSE

        GUIDelete()
EndFunc   ;==>_Main

Func _ItemColor()
        Switch $iFlag
                Case 0
                        GUICtrlSetBkColor($iItem_Color, $iColor1)
                        GUICtrlSetColor($iItem_Color, 0xFFFFFF)
                        $iFlag = 1
                Case 1
                        GUICtrlSetBkColor($iItem_Color, 0xFFFFFF)
                        GUICtrlSetColor($iItem_Color, $iColor1)
                        $iFlag = 0
        EndSwitch
EndFunc
Link to comment
Share on other sites

Nope, i'm talking about the UDF _GUICtrlListView() not about the internal GUICtrlCreateListViewItem, only with the UDF i can insert an item in whatever position instead only in the last

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

  • Solution

This solves the issue in #5:

#include <GUIListView.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $hGUI, $hListView
Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1

Global $iColDef = 0xFFFFFF
Global $iColRow = 0xC0C0C0
Global $iColColumn  = 0xF5F5F5

$hGUI = GUICreate('Test', 300, 200)
$iListView = GUICtrlCreateListView('Items|SubItems', 10, 10, 280, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE)
$hListView = GUICtrlGetHandle($iListView)
GUICtrlRegisterListViewSort(-1, "LVSort")

For $i = 0 To 100
    _GUICtrlListView_InsertItem($hListView, 'Item' & $i)
    _GUICtrlListView_SetItemText($hListView, $i, 'SubItem' & $i, 1)
Next
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $iListView
            ;$bSet = 0
            $nCurCol = GUICtrlGetState($iListView)
            _GUICtrlListView_RedrawItems($hListView, 0, 100)
            ;GUICtrlSendMsg($iListView, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($iListView), 0)
            ;DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($iListView), "int", 0, "int", 1)
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
    Local $iCode = DllStructGetData($tNMHDR, 'Code')
    Switch $hWndFrom
        Case $hListView
            Switch $iCode

                Case $NM_CUSTOMDRAW
                  Local $tNMLVCUSTOMDRAW = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                  Local $dwDrawStage = DllStructGetData($tNMLVCUSTOMDRAW, "dwDrawStage")

                  Switch $dwDrawStage                ; Holds a value that specifies the drawing stage

                    Case $CDDS_PREPAINT
                      ; Before the paint cycle begins
                      Return $CDRF_NOTIFYITEMDRAW    ; Notify the parent window of any item-related drawing operations

                    Case $CDDS_ITEMPREPAINT
                      ; Before painting an item
                      Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations

                    Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM )
                      ; Before painting a subitem
                      Local $dwItemSpec = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec")
                      Local $iSubItem = DllStructGetData($tNMLVCUSTOMDRAW, "iSubItem")
                      Switch $iSubItem
                        Case $nCurCol
                          If $dwItemSpec = 5 Then
                            DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColRow)
                          Else
                            DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColColumn)
                          EndIf
                        Case Else
                          If $dwItemSpec = 5 Then
                            DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColRow)
                          Else
                            DllStructSetData($tNMLVCUSTOMDRAW, "clrTextBk", $iColDef)
                          EndIf
                      EndSwitch
                      Return $CDRF_NEWFONT

                  EndSwitch

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $nResult
    Return $nResult
EndFunc   ;==>LVSort
Link to comment
Share on other sites

LarsJ your version work fine with the GUICtrlRegisterListViewSort and i confirm resolve the issue at #5

I think i can say i'm satisfied of the result, i can't use a function like the #4 but is better then nothing

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

If you store the colors in an array (instead of ItemParam) with item as index, I think you can use the function in #4. I can add an example if you are interested. But you can't avoid WM_NOTIFY.

Edited by LarsJ
Link to comment
Share on other sites

This is a listview with some random colors. The colors are stored in an array. The listview row indices into the array is stored in the first column of the listview. This column is hidden (width = 0). ItemParam is not used and can be used for sorting. For the selected column the items are drawn with some slightly lighter colors.

 

#Include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#Include <GUIListView.au3>

Global $hGui, $iListView, $hListView, $nCurCol = 1

Global $aColors[6]      = [ 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000 ] ; Yellow, green, cyan, blue, magenta, red
Global $aColorsLight[6] = [ 0xFFFFBB, 0xBBFFBB, 0xBBFFFF, 0xBBBBFF, 0xFFBBFF, 0xFFBBBB ] ; Light colors: Yellow, green, cyan, blue, magenta, red
Global $aColorsTable[100][5] ; Change BB to make the colors lighter or darker

MainFunc()

Func MainFunc()

  $hGui = GUICreate( 'Colors', 400, 200 )

  ; Create ListView with 5 columns
  ; First column is used to store index in color table
  ; Then the indices are still valid if the ListView is sorted
  ; The indices are also valid if a row in the ListView is deleted
  ; When a row is added to the ListView also add a row to the color table and store index in hidden column
  $iListView = GUICtrlCreateListView( 'Indices|Items|SubItems1|SubItems2|SubItems3', 10, 10, 380, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE )
  $hListView = GUICtrlGetHandle( $iListView )
  GUICtrlRegisterListViewSort( -1, "LVSort" )

  ; Fill ListView
  For $i = 0 To 99 ; GUICtrlCreateListViewItem is the fastest way to fill a ListView with initial items
    GUICtrlCreateListViewItem( $i & "|" & "Item " & $i & "|SubItem1 " & $i & "|SubItem2 " & $i & "|SubItem3 " & $i, $iListView )
    ; Add random colors to color table
    $aColorsTable[$i][1] = Random( 0, 5, 1 )
    $aColorsTable[$i][2] = Random( 0, 5, 1 )
    $aColorsTable[$i][3] = Random( 0, 5, 1 )
    $aColorsTable[$i][4] = Random( 0, 5, 1 )
  Next

  ; Hide first column with indices
  _GUICtrlListView_HideColumn( $hListView, 0 )

  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )
  GUISetState()

  While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
      Case $GUI_EVENT_CLOSE
        Exit
      Case $iListView
        $nCurCol = GUICtrlGetState( $iListView )
        _GUICtrlListView_RedrawItems( $hListView, 0, 99 )
    EndSwitch
  WEnd

EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
    Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
    Local $hWndFrom = DllStructGetData( $tNMHDR, 'hWndFrom' )
    Local $iCode = DllStructGetData( $tNMHDR, 'Code' )
    Switch $hWndFrom
        Case $hListView
            Switch $iCode

                Case $NM_CUSTOMDRAW
                  Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
                  Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" )

                  Switch $dwDrawStage                ; Holds a value that specifies the drawing stage

                    Case $CDDS_PREPAINT
                      ; Before the paint cycle begins
                      Return $CDRF_NOTIFYITEMDRAW    ; Notify the parent window of any item-related drawing operations

                    Case $CDDS_ITEMPREPAINT
                      ; Before painting an item
                      Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations

                    Case BitOR(  $CDDS_ITEMPREPAINT, $CDDS_SUBITEM  )
                      ; Before painting a subitem
                      Local $dwItemSpec = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" )
                      Local $iSubItem = DllStructGetData( $tNMLVCUSTOMDRAW, "iSubItem" )
                      Local $iColorIdx = _GUICtrlListView_GetItemText( $hListView, $dwItemSpec, 0 )
                      Switch $iSubItem
                        Case $nCurCol
                          DllStructSetData( $tNMLVCUSTOMDRAW, "clrTextBk", $aColorsLight[$aColorsTable[$iColorIdx][$iSubItem]] )
                        Case Else
                          If $iSubItem Then _
                            DllStructSetData( $tNMLVCUSTOMDRAW, "clrTextBk", $aColors[$aColorsTable[$iColorIdx][$iSubItem]] )
                      EndSwitch
                      Return $CDRF_NEWFONT

                  EndSwitch

            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func LVSort( $hWnd, $nItem1, $nItem2, $nColumn )
  Local $nResult
  Return $nResult
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...