Modify

#513 closed Feature Request (Rejected)

Request: checked row highlight style for Listview controls

Reported by: v3rt1g0 Owned by:
Milestone: Component: AutoIt
Version: Severity: None
Keywords: Listview, Checkboxes, Row highlight, GUI Cc:

Description

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

Attachments (1)

img.zip (404 bytes ) - added by v3rt1g0 on Aug 11, 2008 at 8:13:34 PM.
Checkbox Pics

Download all attachments as: .zip

Change History (3)

by v3rt1g0, on Aug 11, 2008 at 8:13:34 PM

Attachment: img.zip added

Checkbox Pics

comment:1 by TicketCleanup, on Aug 11, 2008 at 10:00:20 PM

Milestone: Future Release
Version: Other

Automatic ticket cleanup.

comment:2 by Valik, on Aug 12, 2008 at 1:33:01 AM

Resolution: Rejected
Status: newclosed

There's already too much custom behavior as is. If we added all the useful custom behaviors we'd have everything bloated so big it'd be ridiculous.

Modify Ticket

Action
as closed The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.