Jump to content
Sign in to follow this  

ListView extended style: $LVS_EX_BORDERSELECT

Recommended Posts



That extended style seems to lay the whammy on any ListView I apply it to.

Is broken? Or am I missing something?

Edit: I searched on the full variable name, instead of just "borderselect" and got some archived hits. I guess this only works with large icons? I have a listview where the rows have different background colors depending upon the type of record, and I wanted to retain those colors even when the row was selected. I'm not sure if there is a way for force a border color change on an entire selected row, keeping the original background color? Any CustomDraw magic that will do it?

(Grr... this post would been better in the GUI forum)

Edited by Spiff59

Share this post

Link to post
Share on other sites

After a few tests it seems the only difference is that if $LVS_EX_BORDERSELECT is not specified then the image gets highlighted as well whereas specifying this extended style won't highlight the image:

#Include <GuiImageList.au3>
#include <GUIListView.au3>

Global $hGUI = GUICreate('', 200, 200)
Global $ListView = GUICtrlCreateListView('1|2|3', 0, 0, 200, 200, $LVS_DEFAULT)
Global $hListView = GUICtrlGetHandle($ListView)
Global $hImage = _GUIImageList_Create(16, 16, 5)

_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT))

_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
_GUICtrlListView_SetImageList($hListView, $hImage, 1)

For $i = 0 To 9
    $Item = GUICtrlCreateListViewItem('A|B|C', $ListView)
    GUICtrlSetBkColor($Item, Random(13369344, 13434879, 1))
    _GUICtrlListView_SetItemImage($hListView, $i, 0)
For $i = 0 To 2
    _GUICtrlListView_SetColumnWidth($hListView, $i, 150)

Until GUIGetMsg() = -3

Share this post

Link to post
Share on other sites

I'd prefer some sort of outlining of the selected row, but if that's not possible, I thought maybe highlighting the entire row in the current background color of the "key" cell might be an option. I've been tinkering with some code, but can only get it to outline the area of the rectangle occupied by text, rather than the entire rectangle. So, instead of a solid color bar across the selected row, I get the color broken into pieces. Anyone have an idea how to color all parts of the selected row?

#Include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiListView.au3>

Global $Row_Changed
$hGUI = GUICreate("Listview Custom Draw", 400, 300)

$cListView = GUICtrlCreateListView("", 2, 2, 394, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
$hListView = GUICtrlGetHandle($cListView)
$label = GUICtrlCreateLabel("", 50, 275, 100, 15)

_GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 90)
_GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 140)
_GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

; Add items
For $i = 1 To 30
    _GUICtrlListView_AddItem($hListView, "Row" & $i & ": Col 1", $i-1)
    For $j = 1 To 2
        _GUICtrlListView_AddSubItem ($hListView, $i-1, "Row" & $i & ": Col " & $j+1, $j)

    If $Row_Changed Then
        $Row_Changed = 0
        GUICtrlSetData($label, "Row selected: " & _GUICtrlListView_GetSelectionMark($hListView))

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $iColor, $iBkColor

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CLICK, -155 ; up/down
                    $Row_Changed = 1
                Case $NM_CUSTOMDRAW
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage")
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW
                    Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec")
                    Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem")
                    If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then
                        Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem)
                        Switch Mod($iItem, 3)
                            Case 0
                                $iBkColor = RGB2BGR(0xFF0000)
                                $iColor = RGB2BGR(0xFFFFFF)
                            Case 1
                                $iBkColor = RGB2BGR(0x00FF00)
                                $iColor = RGB2BGR(0x000000)
                            Case 2
                                $iBkColor = RGB2BGR(0x0000FF)
                                $iColor = RGB2BGR(0xFFFFFF)
                        $tRect = DllStructCreate('long;long;long;long')
                        DllStructSetData($tRect, 2, $iSubitem)
                        DllCall('user32.dll','int','SendMessage', 'hwnd',$hWndFrom, 'uint',$LVM_GETSUBITEMRECT, 'wparam',$iItem, 'lparam',DllStructGetPtr($tRect))
                        $hDC = DllStructGetData($tCustDraw, 'hdc');_WinAPI_GetDC($hWndFrom)
;                        $rc = DllStructGetData($tCustDraw, 'rc')
                        DLLCall("gdi32.dll","int","SetTextColor", "ptr", $hDC, "int", $iColor)
                        DLLCall("gdi32.dll","int","SetBkColor", "ptr", $hDC, "int", $iBkColor)
                        DLLCall("gdi32.dll","int","SetBkMode", "ptr", $hDC, "int", 2)
                        DllStructSetData($tRect, 1, DllStructGetData($tRect, 1) + 6)
                        _WinAPI_DrawText($hDC, $sText, $tRect, 0x8000) ;; $DT_END_ELLIPSIS
                        Return $CDRF_SKIPDEFAULT
                    Switch Mod($iItem, 3) ; alternate bg/text colors
                        Case 0
                            $iColor = RGB2BGR(0xFF0000)
                            $iBkColor = RGB2BGR(0xFFFFFF)
                        Case 1
                            $iColor = RGB2BGR(0x00FF00)
                        Case 2
                            $iColor = RGB2BGR(0x0000FF)
                            $iBkColor = RGB2BGR(0xFFFFFF)
                    If $iSubitem = 1 Then ; only paint column 2
                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor)
                        DllStructSetData($tCustDraw, 'clrText', $iBkColor)
                        DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF)
                        DllStructSetData($tCustDraw, 'clrText', 0)
                    Return $CDRF_NEWFONT
EndFunc   ;==>WM_NOTIFY

Func RGB2BGR($iColor)
    Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)

Share this post

Link to post
Share on other sites

You can easily fill the items and subitems using a brush and the _WinAPI_FillRect() function. To outline the brush you need to use a pen and the Rectangle function. It's a straightforward way and may not be to your likes but it's applicable. ;]

Share this post

Link to post
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
Sign in to follow this