﻿id	summary	reporter	owner	description	type	status	milestone	component	version	severity	resolution	keywords	cc
513	Request: checked row highlight style for Listview controls	v3rt1g0		"I'd love to see the code below included as an easily usable extended style for listview controls.
In a listview with several subitems, keeping the entire row highlighted if the item is checked ($EX_LVS_CHECKBOXES) makes it very easy to quickly scan values in subitem columns.

The example below from user 'rasim' does not use the built-in listview extended style checkboxes, but I would prefer that it did.

Being able to add this functionality as an extended style, without having to delve into WinAPI/GDIPlus would be a huge time saver.
Also having the style work with WM_NOTIFY '$NM_CLICK' anywhere on the row (vs just the checkbox itself) would be perfect.

{{{
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>

Global Const $ODT_LISTVIEW = 102

Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4

Global Const $ODS_SELECTED = 0x0001

Global $aBitmap[10]

$hGUI = GUICreate(""Test GUI"", 300, 220)

$hListView = GUICtrlCreateListView(""Items|SubItems"", 10, 10, 280, 200, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED), $LVS_EX_CHECKBOXES)

For $i = 1 To 10
    GUICtrlCreateListViewItem(""Item "" & $i & ""|"" & ""SubItem "" & $i, $hListView)
Next

_GDIPlus_Startup()

$hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & ""\CheckOff.bmp"")

$hBitmap2 = _GDIPlus_BitmapCreateFromFile(@ScriptDir & ""\CheckOn.bmp"")

$hDC = _WinAPI_GetDC($hGUI)

$hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC)

_GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 10, 49)

_WinAPI_ReleaseDC($hGUI, $hDC)

For $i = 0 To UBound($aBitmap) - 1
    $aBitmap[$i] = $hBitmap
Next

GUIRegisterMsg($WM_DRAWITEM, ""WM_DRAWITEM"")
GUIRegisterMsg($WM_NOTIFY, ""WM_NOTIFY"")

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

;Release objects
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_ImageDispose($hBitmap2)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tagDRAWITEMSTRUCT, $iBrushColor = 0xFFFFFF, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected
    
    $tagDRAWITEMSTRUCT = DllStructCreate(""uint cType;uint cID;uint itmID;uint itmAction;uint itmState;"" & _
                                         ""hwnd hItm;hwnd hDC;int itmRect[4];dword itmData"", $lParam)
                                         
    If DllStructGetData($tagDRAWITEMSTRUCT, ""cType"") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    
    $cID = DllStructGetData($tagDRAWITEMSTRUCT, ""cID"")
    $itmID = DllStructGetData($tagDRAWITEMSTRUCT, ""itmID"")
    $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, ""itmAction"")
    $itmState = DllStructGetData($tagDRAWITEMSTRUCT, ""itmState"")
    $hItm = DllStructGetData($tagDRAWITEMSTRUCT, ""hItm"")
    $hDC = DllStructGetData($tagDRAWITEMSTRUCT, ""hDC"")
    
    $bSelected = BitAND($itmState, $ODS_SELECTED)
    
    Switch $itmAction
        Case $ODA_DRAWENTIRE
            ;If $itmState = $bSelected Then
                ;$iBrushColor = 0xFFFFFF
            ;Else
                If $aBitmap[$itmID] = $hBitmap2 Then
                    $iBrushColor = 0x0000FF
                Else
                    $iBrushColor = 0xFFFFFF
                EndIf
            ;EndIf
            
            Local $aBrush = DLLCall(""gdi32.dll"",""hwnd"",""CreateSolidBrush"", ""int"", $iBrushColor)
            
            Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush[0])
            
            Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, ""itmRect"", 1)
            DllStructSetData($tagDRAWITEMSTRUCT, ""itmRect"", $iLeft + 15, 1)
            
            _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, ""itmRect""), $aBrush[0])
            
            _WinAPI_SelectObject($hDC, $aBrushOld)
            
            _WinAPI_DeleteObject($aBrush[0])
            
            Local $itmText = _GUICtrlListView_GetItemText($hListView, $itmID)

            DllStructSetData($tagDRAWITEMSTRUCT, ""itmRect"", DllStructGetData($tagDRAWITEMSTRUCT, ""itmRect"", 1) + 2, 1)
            
            DllCall(""user32.dll"", ""int"", ""DrawText"", ""hwnd"", $hDC, ""str"", $itmText, ""int"", StringLen($itmText), _
                    ""ptr"", DllStructGetPtr($tagDRAWITEMSTRUCT, ""itmRect""), ""int"", $DT_LEFT)
                    
            Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, 1)
            Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, 1)
            
            Local $iSubItmRect = DllStructCreate(""int[4]"")
            
            DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + 10, 1)
            DllStructSetData($iSubItmRect, 1, $aSubItmRect[1], 2)
            DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3)
            DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4)
            
            DllCall(""user32.dll"", ""int"", ""DrawText"", ""hwnd"", $hDC, ""str"", $iSubItmText, ""int"", StringLen($iSubItmText), _
                    ""ptr"", DllStructGetPtr($iSubItmRect), ""int"", $DT_LEFT)
            
            $iImageLeft = DllStructGetData($tagDRAWITEMSTRUCT, ""itmRect"", 1)
            $iImageTop = DllStructGetData($tagDRAWITEMSTRUCT, ""itmRect"", 2)
            
            _GDIPlus_GraphicsDrawImage($hGraphic, $aBitmap[$itmID], $iImageLeft - 7, $iImageTop + 11)
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $iIDFrom, $iCode
    
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $iIDFrom = DllStructGetData($tNMHDR, ""IDFrom"")
    $iCode = DllStructGetData($tNMHDR, ""Code"")
    
    Switch $iIDFrom
        Case $hListView
            Switch $iCode
                Case $NM_CLICK
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    Local $iItem = DllStructGetData($tInfo, ""Item"")
                    
                    Local $tPoint = _WinAPI_GetMousePos(True, $hGUI)
                    Local $iX = DllStructGetData($tPoint, ""X"")
                    Local $iY = DllStructGetData($tPoint, ""Y"")
                    
                    If ($iItem <> -1) And ($iX < 22) Then
                        If $aBitmap[$iItem] = $hBitmap Then
                            $aBitmap[$iItem] = $hBitmap2
                            ConsoleWrite(""-> Item "" & $iItem + 1 & "" checked"" & @LF)
                        Else
                            $aBitmap[$iItem] = $hBitmap
                            ConsoleWrite(""-> Item "" & $iItem + 1 & "" unchecked"" & @LF)
                        EndIf
                        _WinAPI_RedrawWindow(GUICtrlGetHandle($hListView), 0, 0, $RDW_INVALIDATE)
                    EndIf
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc
}}}"	Feature Request	closed		AutoIt		None	Rejected	Listview, Checkboxes, Row highlight, GUI	
