Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

change color of row when click in listview item

change color of row when click in listview item

RE: change color of row when click in listview item

No, sadly not easy.

The VB6 version of the Lisview (i.e the one in the common controls library) does not support a different highlight colour (the vb.net version does, but we can't use that). The is no Windows message, API call or API macro that gives us a way to do this.

So to achieve what you are asking, you need to resort - once more - to OwnerDraw (it's only about another 3 or 4 lines of code). The core example for ownerdraw on a listview was provided to you a while back. Here is a link: thread222-1803482: border on entire row in listview

RE: change color of row when click in listview item

ok tks, but...

For strongm...

Hi strongm, based this post : https://www.tek-tips.com/viewthread.cfm?qid=180348...

how to use the code with 2 or more listview?

Possible to create a public sub function an pass th new paremeter LV as Listview

RE: change color of row when click in listview item

Heres a minor modification of my original example (mostly removing and/or commenting out unneccessary code). It demonstartews more than one Listview, and also the highlight colour (which can be anything we like)

End result looks a bit like: https://res.cloudinary.com/engineering-com/video/upload/v1648474575/tips/Untitled_jtqfoa.mp4

You'll need a form with two listviews, a command button and a CommonDialog control

In the form paste the following code:

CODE -->

Option Explicit

Private Declare Function LockWindowUpdate Lib "user32.dll" (ByVal hwndLock As Long) As Long
Private Const LVIF_IMAGE = &H2
Private OnceExecuted As Boolean

'Private Sub chkNoFocus_Click()
'    ListView1.Refresh
'    ListView1.SetFocus
'End Sub

'Private Sub chkBorderOnly_Click()
'    ListView1.SetFocus
'    ListView1.Refresh
'End Sub

Private Sub Command1_Click()
End Sub

Private Sub Form_Activate()
    If Not OnceExecuted Then
    ' let's do 2 listviews
        PopulateListView ListView1
        PopulateListView ListView2
        SubClass Me.hWnd
        OnceExecuted = True
        LVHighlighColour = vbBlue
    End If
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Set Form1 = Nothing
End Sub

Private Sub SubClass(ByVal hWnd As Long)
    mWndProcNext = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
    If mWndProcNext Then mhWndSubClassed = hWnd
End Sub

Private Sub UnSubClass()
    If mWndProcNext Then
        SetWindowLong mhWndSubClassed, GWL_WNDPROC, mWndProcNext
        mWndProcNext = 0
    End If
End Sub

Private Sub PopulateListView(lv As ListView)
    Dim oldExStyle As Long
    Dim i As Integer
    Dim st As String
    Dim tmp As Single
    Dim lvItem As ListItem
    Dim j As Integer
    LockWindowUpdate lv.hWnd
    lv.ColumnHeaders(4).Width = 0
    ' Some of the stuff in here will not display in custom ownerdraw mode (e.g red color, bold), but cannot be bothered to modifiy for sake of this example
    For i = 1 To 30
        Set lvItem = lv.ListItems.Add(i, , "This item contains text " & i, 3, 3)
        With lvItem
            .Tag = ""
            st = Format$(DateSerial(2005, 1, 31 - i), "dd.mm.yyyy")
            .ListSubItems.Add 1, , st
            .ListSubItems(1).Tag = Format$(st, "yyyymmddHHMMSS")
            tmp = Rnd * 10000
            .ListSubItems.Add 2, , Format$(tmp, ".0000")
            .ListSubItems(2).Tag = Format$(tmp, "000000000000.0000000000")
            .ListSubItems.Add 3, , ""
            .ListSubItems(3).Tag = ""
            .SmallIcon = 3
            .Bold = (i Mod 3 = 0)
            .ListSubItems(1).Bold = (i Mod 3 = 0)
            .ListSubItems(2).Bold = (i Mod 3 = 0)
            If i Mod 4 = 0 Then
                .ForeColor = vbRed
                For j = 1 To .ListSubItems.Count
                    .ListSubItems(j).ForeColor = vbRed
            End If
        End With
    lv.SortOrder = lvwDescending
    lv.ListItems(1).Selected = True
    LockWindowUpdate 0&
End Sub 

And then in a Module:

CODE -->

Private Const LVM_FIRST As Long = &H1000
Private Const LVM_GETITEMRECT As Long = (LVM_FIRST + 14)
Private Const LVM_GETSUBITEMRECT As Long = (LVM_FIRST + 56)

Private Const LVIR_LABEL As Long = 2
Private Const LVIR_ICON As Long = 1
Private Const LVIR_BOUNDS As Long = 0

Public mhWndSubClassed As Long
Public mWndProcNext As Long

Public LVHighlighColour As Long

Public Sub SelectColour()
      ' Set Cancel to True
        With Form1.CommonDialog1
            .CancelError = True
            On Error GoTo ErrHandler
            'Set the Flags property
            .Flags = cdlCCRGBInit
            ' Display the Color Dialog box
            ' Set the form's background color to selected color
            LVHighlighColour = .Color
            Exit Sub
        End With

  ' User pressed the Cancel button
End Sub

Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, _
                           ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim tNMH As NMHDR
    If uMsg = WM_NOTIFY Then
        CopyMemory tNMH, ByVal lParam, Len(tNMH)
        ' Hardcoded cheap way of working with individual LVs - handling LV1 and LV2 here
        ' Essentially, we ned to call plCustomDraw p0assing the correct lParam for each LV we are handling
        If tNMH.hwndFrom = Form1.ListView1.hWnd And tNMH.code = NM_CUSTOMDRAW Then
            WindowProc = plCustomDraw(lParam)
            Exit Function
        End If
        If tNMH.hwndFrom = Form1.ListView2.hWnd And tNMH.code = NM_CUSTOMDRAW Then
            WindowProc = plCustomDraw(lParam)
            Exit Function
        End If
    End If
    WindowProc = CallWindowProc(mWndProcNext, hWnd, uMsg, wParam, ByVal lParam)
End Function

Private Function plCustomDraw(ByVal lParam As Long) As Long
    Dim lLen As Long
    Dim hFont As Long
    Dim lvRowIndex As Long
    Dim rct As RECT
    Dim hBr As Long, bgColor As Long, bdrColor As Long, tmp As Long
    Dim LVI As lvItem
    ' Get the CustomDraw data.
    lLen = Len(NMLVCD)
    CopyMemory NMLVCD, ByVal lParam, lLen
    lvRowIndex = NMLVCD.nmcd.dwItemSpec
    Select Case NMLVCD.nmcd.dwDrawStage
        Case CDDS_PREPAINT
            ' Tell it we want to be told when an item is drawn.
            plCustomDraw = CDRF_NOTIFYITEMDRAW
            If Not (NMLVCD.nmcd.lItemlParam = 0) Then
'                If Form1.chkNoFocus.Value = 1 Then
'                    ' removing focus rect:
'                    NMLVCD.nmcd.uItemState = NMLVCD.nmcd.uItemState And (Not CDIS_FOCUS)
'                End If
'                If Form1.chkBorderOnly.Value = 1 Then
'                    ' removing standard selection:
'                    NMLVCD.nmcd.uItemState = NMLVCD.nmcd.uItemState And (Not CDIS_SELECTED)
'                End If
                If NMLVCD.nmcd.uItemState And CDIS_SELECTED Then
                    NMLVCD.clrTextBk = LVHighlighColour
                    NMLVCD.nmcd.uItemState = NMLVCD.nmcd.uItemState And (Not CDIS_SELECTED)
                End If
                CopyMemory ByVal lParam, NMLVCD, lLen
            End If
            plCustomDraw = CDRF_NOTIFYPOSTPAINT
            ' ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'            If Form1.chkBorderOnly.Value = 1 Then
'                ' replacing color filling with border:
'                If lvRowIndex + 1 = Form1.ListView1.SelectedItem.Index Then
'                    rct.Left = LVIR_BOUNDS 'LVIR_LABEL 'LVIR_ICON
'                    SendMessage Form1.ListView1.hWnd, LVM_GETITEMRECT, lvRowIndex, rct
''                    tmp = rct.Left
''                    rct.Top = Form1.ListView1.ColumnHeaders.Count - 2 '
''                    rct.Left = LVIR_BOUNDS
''                    SendMessage Form1.ListView1.hWnd, LVM_GETSUBITEMRECT, lvRowIndex, rct
''                    rct.Left = tmp
''                   We can use hitTest to track which subitem is under cursor
'                    rct.Top = rct.Top + 1
'                    hBr = CreateSolidBrush(RGB(0, 127, 0)) 'GetSysColorBrush(bdrColor)
'                    FrameRect NMLVCD.nmcd.hdc, rct, hBr
'                    'FillRect NMLVCD.nmcd.hdc, rct, hBr
'                    DeleteObject hBr
'                End If
'            End If
            plCustomDraw = CDRF_NEWFONT
        Case Else
            plCustomDraw = CDRF_DODEFAULT
    End Select
End Function 

RE: change color of row when click in listview item


tKS for patience.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close