Modify

Opened 12 years ago

Closed 12 years ago

#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 12 years ago.
Checkbox Pics

Download all attachments as: .zip

Change History (3)

Changed 12 years ago by v3rt1g0

Checkbox Pics

comment:1 Changed 12 years ago by TicketCleanup

  • Milestone Future Release deleted
  • Version Other deleted

Automatic ticket cleanup.

comment:2 Changed 12 years ago by Valik

  • Resolution set to Rejected
  • Status changed from new to closed

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.

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as closed The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.