Post 5
 
	Slightly more flexible code. Added highlight of selected item. Demonstrates listbox refresh.
 
	 
	How the code works? The $LBS_OWNERDRAWVARIABLE style means that the operating system sends WM_DRAWITEM messages when the listbox has to be updated. These messages are captured by AutoIt's internal message management system. For each message the management system executes the WM_DRAWITEM function.
 
	To delete and add rows, update texts and change row heights, use _GUICtrlListBox_ and array functions. Normally you'll not update the code directly in the WM_DRAWITEM function.
 
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListBox.au3>
Global Const $Gdi32dll = DllOpen( "gdi32.dll" )
Global Const $User32dll = DllOpen( "user32.dll" )
; DRAWITEMSTRUCT
Global Const $tagDRAWITEMSTRUCT ="uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;handle hDC;dword rcItem[4];ptr itemData"
; CtlType
Global Const $ODT_LISTBOX = 2
; itemAction
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
; itemState
Global Const $ODS_SELECTED = 0x1
Global $iRowHeight = 16, $iMargin = 4
Global $aRows = [ [ 2, "Row 0", "    Subrow 2"                                 ], _
                  [ 3, "Row 1", "    Subrow 2", "    Subrow 3"                 ], _
                  [ 2, "Row 2", "    Subrow 2"                                 ], _
                  [ 1, "Row 3"                                                 ], _
                  [ 4, "Row 4", "    Subrow 2", "    Subrow 3", "    Subrow 4" ], _
                  [ 2, "Row 5", "    Subrow 2"                                 ], _
                  [ 3, "Row 6", "    Subrow 2", "    Subrow 3"                 ], _
                  [ 2, "Row 7", "    Subrow 2"                                 ], _
                  [ 1, "Row 8"                                                 ], _
                  [ 3, "Row 9", "    Subrow 2", "    Subrow 3"                 ] ]
Example()
Func Example()
  GUICreate( "Ownerdrawn Listbox", 300, 340 )
  Local $idListBox = GUICtrlCreateList( "", 10, 10, 280, 280, $WS_VSCROLL+$LBS_OWNERDRAWVARIABLE ), $hListBox = GUICtrlGetHandle( $idListBox )
  Local $idButton = GUICtrlCreateButton( "Modify row 4", 10, 300, 280, 30 )
  ; Fill listbox rows and set row height
  ; This tells WM_DRAWITEM function how many rows to draw
  For $i = 0 To UBound( $aRows ) - 1
    _GUICtrlListBox_AddString( $idListBox, $aRows[$i][1] )
    _GUICtrlListBox_SetItemHeight( $idListBox, $aRows[$i][0] * $iRowHeight + $iMargin, $i )
  Next
  GUIRegisterMsg( $WM_DRAWITEM, "WM_DRAWITEM" )
  GUISetState( @SW_SHOW )
  Local $n = 0
  While 1
    Switch GUIGetMsg()
      Case $idButton
        $n += 1
        $aRows[4][1] = "Modified row 4 (" & $n & ")"
        _WinAPI_InvalidateRect( $hListBox ) ; Refresh
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd
  GUIDelete()
EndFunc
Func WM_DRAWITEM( $hWnd, $iMsg, $wParam, $lParam )
  Local $tDRAWITEMSTRUCT = DllStructCreate( $tagDRAWITEMSTRUCT, $lParam )
  Local $CtlType = DllStructGetData( $tDRAWITEMSTRUCT, "CtlType" )
  If $CtlType <> $ODT_LISTBOX Then Return $GUI_RUNDEFMSG
  Local $itemID = DllStructGetData( $tDRAWITEMSTRUCT, "itemID" )
  Local $itemAction = DllStructGetData( $tDRAWITEMSTRUCT, "itemAction" )
  Local $itemState = DllStructGetData( $tDRAWITEMSTRUCT, "itemState" )
  Local $hDC = DllStructGetData( $tDRAWITEMSTRUCT, "hDC" )
  Local $iBrushColor, $iTextColor, $DT_LEFT = 0
  Switch $itemAction
    Case $ODA_DRAWENTIRE, $ODA_SELECT
      ; Item state
      If $itemState = $ODS_SELECTED Then
        $iBrushColor = _WinAPI_GetSysColor( $COLOR_HIGHLIGHT )
        $iTextColor = 0xFFFFFF
      Else
        $iBrushColor = ColorConvert( 0xEAEE97 )
        $iTextColor = 0x000000
      EndIf
      ; Item rectangle
      Local $tRECT = DllStructCreate( $tagRECT, DllStructGetPtr( $tDRAWITEMSTRUCT, "rcItem" ) )
      ; Background color
      DLLCall( $Gdi32dll, "int", "SetBkMode", "hwnd", $hDC, "int", 1 ) ; 1 = $TRANSPARENT
      Local $aBrush = DLLCall( $Gdi32dll, "hwnd", "CreateSolidBrush", "int", $iBrushColor )
      DLLCall( $Gdi32dll, "hwnd", "SelectObject", "hwnd", $hDC, "hwnd", $aBrush[0] )
      DllStructSetData( $tRECT, "Bottom", DllStructGetData( $tRECT, "Bottom" ) - 1 )
      DLLCall( $User32dll, "int", "FillRect", "hwnd", $hDC, "struct*", $tRECT, "hwnd", $aBrush[0] )
      DLLCall( $Gdi32dll, "int", "DeleteObject", "hwnd", $aBrush[0] )
      ; Text color
      DllCall( $Gdi32dll, "int", "SetTextColor", "hwnd", $hDC, "int", $iTextColor )
      ; Left margin
      DllStructSetData( $tRECT, "Left",   DllStructGetData( $tRECT, "Left" ) + 4 )
      ; Item text 1
      Local $sItemText = $aRows[$itemID][1]
      DllStructSetData( $tRECT, "Top",    DllStructGetData( $tRECT, "Top"  ) + 2 )
      DllStructSetData( $tRECT, "Bottom", DllStructGetData( $tRECT, "Top"  ) + $iRowHeight )
      DllCall( $User32dll, "int", "DrawText", "hwnd", $hDC, "str", $sItemText, "int", StringLen( $sItemText ), "struct*", $tRECT, "int", $DT_LEFT )
      ; Item text 2 - last column
      For $i = 2 To UBound( $aRows, 2 ) - 1
        If $aRows[$itemID][$i] Then
          $sItemText = $aRows[$itemID][$i]
          DllStructSetData( $tRECT, "Top",    DllStructGetData( $tRECT, "Bottom" ) )
          DllStructSetData( $tRECT, "Bottom", DllStructGetData( $tRECT, "Top"    ) + $iRowHeight )
          DllCall( $User32dll, "int", "DrawText", "hwnd", $hDC, "str", $sItemText, "int", StringLen( $sItemText ), "struct*", $tRECT, "int", $DT_LEFT )
        EndIf
      Next
  EndSwitch
  Return $GUI_RUNDEFMSG
  #forceref $hWnd, $iMsg, $wParam
EndFunc
;RGB to BGR or BGR to RGB
Func ColorConvert($iColor)
  Return BitOR(BitAND($iColor, 0x00FF00), BitShift(BitAND($iColor, 0x0000FF), -16), BitShift(BitAND($iColor, 0xFF0000), 16))
EndFunc