I am one of those 'some people' who would recommend the use of the Flexgrid controls over a listview. I found (and because I am a slow learner) that the flexgrids are much more easy to understand, and SEEM to have better options for displaying information on the screen. I am sure some would disagree as they are very familiar with the use of the listview control, but, that is MY recommendation...use flexgrids.
How's COVID in India?...sux here in the US. People refuse to comply with simple requests.
Keep in mind the hazards of hot dog stand polychromatic user interfaces.
Many of them fall apart miserably when a user turns on low-vision themes, color filters, etc. and can put your software in violation of disability legislation in many countries.
We now also have things like Dark Mode to avoid running afoul of:
Here's a simplified version of an example on this I did a while back. It's set up to highlight a single row, but you'll see where you can easily change it to specify any condition you want to determine the rows, and the subitem if you don't want the entire row changed.
Last edited by fafalone; Nov 23rd, 2020 at 04:52 PM.
Having trouble posting things, don't want to mess up the attachment of the project in the last post, so here's the code and SS.
All you have to do is subclass then apply a simple NM_CUSTOMDRAW routine:
Code:
Public Function F1LVWndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long) As Long
Select Case uMsg
Case WM_NOTIFY
Dim tNMH As NMHDR
CopyMemory tNMH, ByVal lParam, Len(tNMH)
Select Case tNMH.Code
Case NM_CUSTOMDRAW
Dim nmcdr As NMLVCUSTOMDRAW
CopyMemory nmcdr, ByVal lParam, LenB(nmcdr)
Select Case nmcdr.nmcd.dwDrawStage
Case CDDS_PREPAINT
F1LVWndProc = CDRF_NOTIFYITEMDRAW
Exit Function
Case CDDS_ITEMPREPAINT
F1LVWndProc = CDRF_NOTIFYSUBITEMDRAW Or CDRF_NEWFONT
Exit Function
Case (CDDS_ITEMPREPAINT Or CDDS_SUBITEM)
Debug.Print "item=" & nmcdr.nmcd.dwItemSpec & ",target=" & gHighlight
If (nmcdr.nmcd.dwItemSpec = gHighlight) Then ' And (nmcdr.iSubitem = gHighlightSub) Then 'If you only want to set a subitem
If gSetBk Then nmcdr.clrTextBk = vbYellow
If gSetTxt Then nmcdr.clrText = vbRed
Else
If gSetBk Then nmcdr.clrTextBk = vbWhite
If gSetTxt Then nmcdr.clrText = vbBlack
End If
CopyMemory ByVal lParam, nmcdr, LenB(nmcdr)
F1LVWndProc = CDRF_NEWFONT
Exit Function
End Select
End Select
Case WM_DESTROY
Call UnSubclass(hWnd, PtrLVWndProc)
End Select
F1LVWndProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
End Function
Having trouble posting things, don't want to mess up the attachment of the project in the last post, so here's the code and SS.
All you have to do is subclass then apply a simple NM_CUSTOMDRAW routine:
Code:
Public Function F1LVWndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long) As Long
Select Case uMsg
Case WM_NOTIFY
Dim tNMH As NMHDR
CopyMemory tNMH, ByVal lParam, Len(tNMH)
Select Case tNMH.Code
Case NM_CUSTOMDRAW
Dim nmcdr As NMLVCUSTOMDRAW
CopyMemory nmcdr, ByVal lParam, LenB(nmcdr)
Select Case nmcdr.nmcd.dwDrawStage
Case CDDS_PREPAINT
F1LVWndProc = CDRF_NOTIFYITEMDRAW
Exit Function
Case CDDS_ITEMPREPAINT
F1LVWndProc = CDRF_NOTIFYSUBITEMDRAW Or CDRF_NEWFONT
Exit Function
Case (CDDS_ITEMPREPAINT Or CDDS_SUBITEM)
Debug.Print "item=" & nmcdr.nmcd.dwItemSpec & ",target=" & gHighlight
If (nmcdr.nmcd.dwItemSpec = gHighlight) Then ' And (nmcdr.iSubitem = gHighlightSub) Then 'If you only want to set a subitem
If gSetBk Then nmcdr.clrTextBk = vbYellow
If gSetTxt Then nmcdr.clrText = vbRed
Else
If gSetBk Then nmcdr.clrTextBk = vbWhite
If gSetTxt Then nmcdr.clrText = vbBlack
End If
CopyMemory ByVal lParam, nmcdr, LenB(nmcdr)
F1LVWndProc = CDRF_NEWFONT
Exit Function
End Select
End Select
Case WM_DESTROY
Call UnSubclass(hWnd, PtrLVWndProc)
End Select
F1LVWndProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
End Function
The code snippet is just to highlight the critical part of the code, it's not the complete source (which is in the zip in the post above that).
Here, the lParam contains the NMLVCUSTOMDRAW structure. The first part of that is the NMHDR structure, which is copied to determine the code, some codes inform us there's additional data that can be read from the address the lParam is pointing to.
Code:
Private Type NMHDR
hWndFrom As Long ' Window handle of control sending message
IDFrom As Long ' Identifier of control sending message
Code As Long ' Specifies the notification code
End Type
Private Type NMCUSTOMDRAW
hdr As NMHDR
dwDrawStage As Long
hDC As Long
rc As RECT
dwItemSpec As Long
uItemState As Long
lItemlParam As Long
End Type
Private Type NMLVCUSTOMDRAW
nmcd As NMCUSTOMDRAW
clrText As Long
clrTextBk As Long
iSubitem As Long
End Type
So when you copy the first 12 bytes (each Long is 4 bytes), you get just the NMHDR structure. Then the code tells you it's a NM_CUSTOMDRAW message, and since we're working with a ListView, we use the ListView extension, and can copy the full NMLVCUSTOMDRAW structure.
Last edited by fafalone; Nov 23rd, 2020 at 07:43 PM.