I've pulled enough out of examples that I can alternate rows in two different colors. Now, when a row is clicked, that row gets some default blue color (I have theme support checked) and I want to change that blue to match my applications color theme instead and can't seem to find any examples laying around. Does somebody have a "quickie" they can share?
Local lpNmh As NMHDR Ptr
Local lpLvNm As NM_LISTVIEW Ptr
Local lpLvCd As NMLVCUSTOMDRAW Ptr
Select Case wMsg
Case %WM_NOTIFY
lpNmh = lParam
Select Case @lpNmh.idFrom
Case IDC_SECURITYGROUPLIST_GROUPLIST
lpLvNm = lParam
Select Case @LpLvNm.hdr.Code
Case %NM_CUSTOMDRAW
lpLvCd = lParam
Select Case @lplvcd.nmcd.dwDrawStage
Case %CDDS_PREPAINT, %CDDS_ITEMPREPAINT
Function = %CDRF_NOTIFYSUBITEMDRAW
Case %CDDS_ITEMPREPAINT Or %CDDS_SUBITEM
If (@lpLvCd.nmcd.dwItemSpec Mod 2) = 0 Then
@lpLvCd.clrTextBk = %RGB_WHITE
@lpLvCd.clrText = %Black
Else
@lpLvCd.clrTextBk = Rgb(251,225,218)
@lpLvCd.clrText = %Black
End If
Function = %CDRF_NEWFONT
Case Else
End Select
End Select
End Select
End Select
Rick Kelly
Richard,
Were you able to test or implement Borje's solution?
Sorry it took a bit of time for me to get back. Life is life at times.
I did manage to test Borje's code from the PB forum thread:
http://www.powerbasic.com/support/pbforums/showthread.php?t=54744
(http://www.powerbasic.com/support/pbforums/showthread.php?t=54744)
The only change I made was to not draw the focus rectangle, the focused row color to another shade of orange and focused text color to white.
Works right out of the box although I'm not sure of the shade of orange I'm using for the focused row although orange is one of 6 colors in the color theme of my app.
Rick
Well done Rick! I copied your screen shot and checked it in a paint program. It looks to be the same shade of orange. I used Corel Draw, both the selected line in the LV and the Status Bar had varying RGB values as if it is dithered. But the range of each value was the same. My eyes can't tell the difference anyway.
I was just wondering if there was "too much" orange. The status bar and the focus row color are exactly the same RGB value.
The even row lighter shade of range is just the normal orange about 4 shades lighter.
My resident color "expert" is my wife and she approved of the 6 colors I selected for this app as I have no sense of color balancing.
RGB's
124,125,111 (some murky slate color)
227,73,25 (shade of red)
235,107,70 (orange/apricot)
218,219,204 (form background)
151,171,180 (things like buttons, etc)
55,55,42 (wherever I might want a black with less contrast)
Rick
I think it looks nice. Not too much orange in my opinion.
Quote from: David Kenny on April 23, 2014, 05:18:29 AM
I think it looks nice. Not too much orange in my opinion.
Thank you.
Here is a more general purpose version of the code posted by Borje Hagstun I'm going to start using in my FF apps.
Sub DrawListviewRows (ByVal hwndListView As Dword, _
ByVal lParam As Long, _
ByVal nEvenColor As Long, _
ByVal nFocusColor As Long, _
ByVal nDrawFocusRectangle As Long)
' Ownerdraw ListView (Listview attribute set to LVS_OWNERDRAWFIXED)
' Derived from code provided by Borje Hagsten on the PowerBasic Forums April 2014.
' No support for images/icons
' Added to the CUSTOM handler for the form
' Select Case wMsg
' Case %WM_DRAWITEM
' DrawListviewRows (hwndListView,lParam,nEvenColor,nFocusColor,nFocusTextColor,nDrawFocusRectangle)
' hwndListView - Window handle to the listview control
' lParam - Passed from the FF CUSTOM handler for the FF form
' nEvenColor - color to use for even numbered rows
' nFocusColor - color to use for row with focus
' nFocusTextColor - color to use for the text on row with focus
' nDrawFocusRectangle - 1=Draw focus rectangle for focus row
Local nTotalColumns As Long
Local nColumn As Long
Local hBrush As Dword
Local lpdis As DRAWITEMSTRUCT Ptr
Local pt As PointApi
Local rc As Rect
Static szText As Asciiz * 100
lpdis = lParam
Select Case @lpdis.itemAction
Case %ODA_DRAWENTIRE, %ODA_SELECT
'Clear Background
If (@lpdis.itemState And %ODS_SELECTED) Then
hBrush = CreateSolidBrush (nFocusColor)
FillRect @lpdis.hDC, @lpdis.rcItem, hBrush
DeleteObject hBrush
SetBkColor @lpdis.hDC, nFocusColor
SetTextColor @lpdis.hDC, %White
Else
If @lpdis.itemID Mod 2 = 0 Then
FillRect @lpdis.hDC, @lpdis.rcItem, GetSysColorBrush(%COLOR_WINDOW)
SetBkColor @lpdis.hDC, GetSysColor(%COLOR_WINDOW)
SetTextColor @lpdis.hDC, GetSysColor(%COLOR_WINDOWTEXT)
Else
hBrush = CreateSolidBrush (nEvenColor)
FillRect @lpdis.hDC, @lpdis.rcItem, hBrush
DeleteObject hBrush
SetBkColor @lpdis.hDC, nEvenColor
SetTextColor @lpdis.hDC, GetSysColor(%COLOR_WINDOWTEXT)
End If
End If
' Get row coordinates
ListView_GetItemPosition(hwndListView, 0, pt)
' Get the total number of columns
nTotalColumns = FF_ListView_GetColumnCount (hwndListView)
Decr nTotalColumns
rc = @lpdis.rcItem
For nColumn = 0 To nTotalColumns
rc.nLeft = IIF(nColumn > 0, rc.nRight, pt.x)
rc.nRight = rc.nLeft + ListView_GetColumnWidth (hwndListView, nColumn)
ListView_GetItemText hwndListView, @lpdis.itemID, nColumn, szText, SizeOf(szText)
DrawText @lpdis.hDC, szText, Len(szText), rc, %DT_LEFT Or %DT_SINGLELINE Or %DT_VCENTER
Next
If nDrawFocusRectangle = 1 Then
If GetFocus() = hwndListView And (@lpdis.itemState And %ODS_SELECTED) Then
DrawFocusRect(@lpdis.hDC, @lpdis.rcItem)
End If
End If
End Select
End Sub
Of course now, I have to figure out how to support showing an icon from as associated imagelist. This will be really useful over and over again when it gets ironed out.
Rick
I occasionally have a listview where I want an icon in the first column of certain rows. Taking what I had just started using, I added a column on the left and when inserting the row, I determined if I wanted an icon shown and which one from an attached imagelist. Additionally, I also adjusted the background fill to skip over that newly added first column as I liked that appearance. So, although now the code is not perfectly an all around general purpose routine, it does just what I want with the app I'm working on.
Sub DrawListviewRows (ByVal hwndListView As Dword, _I occasionally have a listview where I want an icon in the first column of certain rows. Taking what I had just started using, I added a column on the left and when inserting the row, I determined if I wanted an icon shown and which one from an attached imagelist. Additionally, I also adjusted the background fill to skip over that newly added first column as I liked that appearance. So, although now the code is not perfectly an all around general purpose routine, it does just what I want with the app I'm working on.
ByVal lParam As Long, _
ByVal nEvenColor As Long, _
ByVal nFocusColor As Long, _
ByVal nDrawFocusRectangle As Long, _
Optional ByVal nDrawImage As Long)
' Ownerdraw ListView (Listview attribute set to LVS_OWNERDRAWFIXED)
' Derived from code provided by Borje Hagsten on the PowerBasic Forums April 2014.
' No support for images/icons
' Added to the CUSTOM handler for the form
' Select Case wMsg
' Case %WM_DRAWITEM
' DrawListviewRows (hwndListView,lParam,nEvenColor,nFocusColor,nFocusTextColor,nDrawFocusRectangle)
' hwndListView - Window handle to the listview control
' lParam - Passed from the FF CUSTOM handler for the FF form
' nEvenColor - color to use for even numbered rows
' nFocusColor - color to use for row with focus
' nFocusTextColor - color to use for the text on row with focus
' nDrawFocusRectangle - 1=Draw focus rectangle for focus row
' nDrawImage - 1=Use ImageList in first column
Local nTotalColumns As Long
Local nColumn As Long
Local nImageColumnSize As Long
Local nImageIndex As Long
Local hBrush As Dword
Local lpdis As DRAWITEMSTRUCT Ptr
Local pt As PointApi
Local rc As Rect
Static szText As Asciiz * 100
If nDrawImage = 1 Then
nImageColumnSize = FF_ListView_GetColumnWidth (hwndListView, 0)
Else
nImageColumnSize = 0
End If
lpdis = lParam
Select Case @lpdis.itemAction
Case %ODA_DRAWENTIRE, %ODA_SELECT
'Clear Background
rc = @lpdis.rcItem
rc.nLeft = rc.nLeft + nImageColumnSize
If (@lpdis.itemState And %ODS_SELECTED) Then
hBrush = CreateSolidBrush (nFocusColor)
FillRect @lpdis.hDC, rc, hBrush
DeleteObject hBrush
SetBkColor @lpdis.hDC, nFocusColor
SetTextColor @lpdis.hDC, %White
Else
If @lpdis.itemID Mod 2 = 0 Then
FillRect @lpdis.hDC, rc, GetSysColorBrush(%COLOR_WINDOW)
SetBkColor @lpdis.hDC, GetSysColor(%COLOR_WINDOW)
SetTextColor @lpdis.hDC, GetSysColor(%COLOR_WINDOWTEXT)
Else
hBrush = CreateSolidBrush (nEvenColor)
FillRect @lpdis.hDC, rc, hBrush
DeleteObject hBrush
SetBkColor @lpdis.hDC, nEvenColor
SetTextColor @lpdis.hDC, GetSysColor(%COLOR_WINDOWTEXT)
End If
End If
' Get row coordinates
ListView_GetItemPosition(hwndListView, 0, pt)
' Get the total number of columns
nTotalColumns = FF_ListView_GetColumnCount (hwndListView)
Decr nTotalColumns
rc = @lpdis.rcItem
For nColumn = 0 To nTotalColumns
rc.nLeft = IIF(nColumn > 0, rc.nRight, pt.x)
rc.nRight = rc.nLeft + ListView_GetColumnWidth (hwndListView, nColumn)
If nDrawImage = 1 Then
If nColumn = 0 Then
nImageIndex = FF_ListView_GetItemImage (hwndListView, @lpdis.itemID, 0)
If nImageIndex >= 0 Then
ImageList_Draw (FF_ListView_GetImageList (hwndListView, %LVSIL_SMALL), nImageIndex, @lpdis.hDC, rc.nLeft, rc.nTop, %ILD_TRANSPARENT)
End If
Else
ListView_GetItemText hwndListView, @lpdis.itemID, nColumn, szText, SizeOf(szText)
DrawText @lpdis.hDC, szText, Len(szText), rc, %DT_LEFT Or %DT_SINGLELINE Or %DT_VCENTER
End If
Else
ListView_GetItemText hwndListView, @lpdis.itemID, nColumn, szText, SizeOf(szText)
DrawText @lpdis.hDC, szText, Len(szText), rc, %DT_LEFT Or %DT_SINGLELINE Or %DT_VCENTER
End If
Next
If nDrawFocusRectangle = 1 Then
If GetFocus() = hwndListView And (@lpdis.itemState And %ODS_SELECTED) Then
DrawFocusRect(@lpdis.hDC, @lpdis.rcItem)
End If
End If
End Select
End Sub
Modify it for your FF projects and have some drawing fun!
Rick