Liberty BASIC Community Forum
Liberty BASIC Programming Discussions >> API/DLL >> ListView color cells
http://libertybasic.conforums.com/index.cgi?board=api&action=display&num=1497613379

ListView color cells
Post by metro on Jun 16th, 2017, 06:42am

Has anybody had success filling the background color of a ListView cell based upon a condition, for example if Profit < 0 then BkGrnd="red"
I have been playing with this code with no success.

thanks in advance

Code:
global holdBgColor

    Struct LVCOLUMN, _
           mask As ulong, _
            fmt As long, _
             cx As long, _
       pszText$ As ptr, _
     cchTextMax As long, _
       iSubItem As long, _
         iImage As long, _
         iOrder As long

    Struct LVITEM, _
           mask As ulong, _
          iItem As long, _
       iSubItem As long, _
          state As ulong, _
      stateMask As ulong, _
       pszText$ As ptr, _
     cchTextMax As long, _
         iImage As long, _
         lParam As long, _
        iIndent As long


'listview constants
    LVS.NOSORTHEADER =   32768 : LVS.REPORT =             1 : LVS.SINGLESEL =          4 : LVS.SHOWSELALWAYS =      8
    LVS.SORTASCENDING =     16 : LVS.SORTDESCENDING =    32 : LVS.NOLABELWRAP =      128 : LVS.AUTOARRANGE =      256
    LVS.NOSCROLL =        8192 : LVS.ALIGNTOP =           0 : LVS.ALIGNLEFT =       2048 : LVS.NOCOLUMNHEADER = 16384
    LVIF.TEXT =              1 : LVIF.STATE =             8 : LVIS.UNSELECTED =        0 : LVIS.FOCUSED =           1
    LVIS.SELECTED =          2 : LVM.FIRST =           4096 : LVM.SETITEM =         4102 : LVM.INSERTITEM =      4103
    LVM.INSERTCOLUMN =    4123 : LVM.GETITEMCOUNT =    4100 : LVM.GETITEMA =        4101 : LVM.GETITEMTEXTA =    4141
    LVM.GETITEMSTATE =    4138 : LVM.SETITEMSTATE =    4139 : LVM.DELETEITEM =      4104 : LVM.DELETEALLITEMS =  4105
    LVM.SETTEXTCOLOR =    4132 : LVM.SETBKCOLOR=       4097 : LVM.SETTEXTBKCOLOR =  4134 : LVM.DELETEALLITEMS =  4105
    LVM.UPDATE =          4138 : LVIF.IMAGE         =     2 : LVCF.WIDTH =             2 : LVCF.TEXT =              4
    LVS.EX.GRIDLINES=        1 : LVCFMT.CENTER  =         2 : LVCFMT.RIGHT =           1 : LVCF.FMT =               1
    LVS.LIST=                3 : LVS.SMALLICON=           2 : LVSCW.AUTOSIZE=         -1

    LVS.EX.FULLROWSELECT = hexdec("20")
    LVM.SETEXTENDEDLISTVIEWSTYLE = LVM.FIRST + 54

    holdTxtColor=0
    '    holdBgColor=13825525
  ' holdBgColor=139119107
 holdBgColor=4134
    nomainwin
    WindowWidth = 390
    WindowHeight = 232
    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    open "untitled" for dialog as #1
    print #1, "font ms_sans_serif 10"
    print #1, "trapclose [quit.1]"

colorOn=1
'Listview Report
    style =_WS_CHILD OR _WS_VISIBLE OR LVS.REPORT OR LVS.SHOWSELALWAYS OR LVS.EX.GRIDLINES
    hListview1 = CreateWindowEx(_WS_EX_CLIENTEDGE,"SysListView32","",style,0,  0, 380, 200,hwnd(#1),hInst)

'    call sendMessage  hListview1, _WM_SETFONT ,hFont ,1

    if colorOn=1 then
      '  call sendMessage hListview1,LVM.SETBKCOLOR,    0,holdBgColor
'        call sendMessage hListview1,LVM.SETTEXTBKCOLOR,0,413
      '  call sendMessage hListview1,LVM.SETTEXTCOLOR,  0,holdTxtColor
    end if

    if gridOn=0 then
       call sendMessage hListview1,LVM.SETEXTENDEDLISTVIEWSTYLE,LVS.EX.GRIDLINES,LVS.EX.GRIDLINES
     end if

'Set listview colum title, width, and format
    columnName$(1)="Nutrient"
    columnWidth(1)=200

    columnName$(2)="Unit"
    columnWidth(2)=75

    columnName$(3)="Amount"
    columnWidth(3)=100


    LVCOLUMN.fmt.struct = 3
    LVCOLUMN.mask.struct = LVCF.WIDTH OR LVCF.TEXT or LVCF.FMT

    for x=1 to 3
        if x=2 then 'Center justify 2nd column.
            format=LVCFMT.CENTER
            LVCOLUMN.fmt.struct = LVCFMT.CENTER
        end if

        if x=3 then 'Right justify 3rd column.
            format=LVCFMT.RIGHT
            LVCOLUMN.fmt.struct = LVCFMT.RIGHT
        end if

        LVCOLUMN.fmt.struct = format
        LVCOLUMN.cx.struct = columnWidth(x)
        LVCOLUMN.pszText$.struct =columnName$(x)

        call AddColumn hListview1,x-1
   next x

'fill the listview
    n$=chr$(0)
    a$(1)=  "Crude Protein"; n$; "%";     n$; "20.00"
    a$(2)=  "Crude Fat";     n$; "%";     n$; "3.50"
    a$(3)=  "Vitamin A";     n$; "IU/lb"; n$; "4000.00"
    a$(4)=  "Zinc";          n$; "ppm";   n$; "120.00"

    LVITEM.mask.struct = LVIF.TEXT

    for x=1 to 4

        label$  = word$(a$(x),1,n$)
        unit$   = word$(a$(x),2,n$)
        amount$ = word$(a$(x),3,n$)

'1st column info.
        LVITEM.iItem.struct    = x-1     'row
        LVITEM.iSubItem.struct = 0       'column
        LVITEM.pszText$.struct = label$
        call sendLvItemMessageStruct hListview1,LVM.INSERTITEM,0

'2nd column info.
        LVITEM.iSubItem.struct = 1
        LVITEM.pszText$.struct = unit$
        call sendLvItemMessageStruct hListview1,LVM.SETITEM,0

'3rd column info.
        LVITEM.iSubItem.struct = 2
        LVITEM.pszText$.struct = amount$

        if val(amount$)>2000 then
        holdBgColor=139119107
        call sendMessage hListview1,LVM.SETTEXTBKCOLOR,0,holdBgColor
        end if

        call sendLvItemMessageStruct hListview1,LVM.SETITEM,0
      next

wait

[quit.1] 'End the program
    close #1
    END
sub filBG  colnum


end sub

FUNCTION CreateWindowEx(extended,class$,title$,style,left,top,width,height,hParent,pInst)
    calldll #user32, "CreateWindowExA",_
                      extended as ulong,_
                        class$ as ptr,_
                        title$ as ptr,_
                         style as ulong,_
                          left as ulong,_
                           top as ulong,_
                         width as ulong,_
                        height as ulong,_
                       hParent as ulong,_
                             0 as long,_
                         pInst as ulong,_
                             0 as long,_
                CreateWindowEx as ulong
END FUNCTION

FUNCTION GetWindowLong(hWnd,type)
    calldll #user32, "GetWindowLongA",_
                      hWnd as ulong,_
                      type as long,_
             GetWindowLong as long
END FUNCTION

SUB sendMessage hWnd,msg,wParam,lParam
    calldll #user32, "SendMessageA",_
                      hWnd as ulong, _
                       msg as long,_
                    wParam as long, _
                    lParam as long,_
                         r as long
END SUB

'listview messages
SUB AddColumn hWnd,index
    CallDLL #user32, "SendMessageA",_
                      hWnd as ulong,_
                      4123 as long,_
                     index as long,_
                  LVCOLUMN as struct,_
                         r as long
END SUB

SUB sendLvItemMessageStruct h,m,l
    CallDLL #user32, "SendMessageA",_
                      h as ulong,_
                      m as long,_
                      l as long,_
                 LVITEM as struct,_
                      r as long
END SUB

Sub ListView.SetItemImage hWnd, iItem, iSubItem, iImage
    LVITEM.mask.struct = 2 'LVIF_IMAGE
    LVITEM.iItem.struct = iItem
    LVITEM.iSubItem.struct = iSubItem
    LVITEM.iImage.struct = iImage
    call sendLvItemMessageStruct hWnd,4102,0
End Sub
 

Re: ListView color cells
Post by Brandon Parker on Jun 16th, 2017, 12:39pm

You are just basically setting the entire background doing it that way.

Coloring of each individual sub-item is not an easy task and will require a decent amount of message trapping to do.

You might want to have a look at this page which shows everything that is involved in ListView Control coloring of individual cells (about half way down the page).

https://www.codeproject.com/Articles/2890/Using-ListView-control-under-Win-API


I'm not saying it is impossible; just a pain in the neck.


{:0)

Brandon

Re: ListView color cells
Post by metro on Jun 18th, 2017, 12:33am

Thanks Brandon,
is it just me or is there a missing link. huh

wait till your over 60 grin
Re: ListView color cells
Post by Dan Teel on Jun 19th, 2017, 6:34pm

Regardless, you would probably have to subclass the window, catch the NM_CUSTOMDRAW notification via the WM_NOTIFY message and do your own drawing for each item yourself. Liberty BASIC doesnt have a native way to do this, and dealing with all the APIs to do it is probably beyond the scope of what you want to do.

But if you really do, WMLiberty should give you a good base to accomplish this.

https://msdn.microsoft.com/en-us/library/windows/desktop/bb774865(v=vs.85).aspx

Heres code sample for catching double clicks in a listview, which should give you a good jumping off point for catching the customdraw notification

http://www.b6sw.com/forum/content.php?mode=snips2&t=443
Re: ListView color cells
Post by metro on Jun 19th, 2017, 11:11pm

Thanks Dan,
very helpful, I'm currently using similar code to trap double clicks in a listview
so I'll try and digest what microsoft hve exlpained about NM_CUSTOMDRAW

thanks for the help
Re: ListView color cells
Post by Brandon Parker on Jun 20th, 2017, 2:07pm

Sorry about that....

For some reason the part of the link script that handles what is displayed went missing. I've updated the link to display properly.


{:0)

Brandon
Re: ListView color cells
Post by NSbrown on Aug 22nd, 2017, 10:11am

Hello everyone
Has anyone been able to paint a specific cell? Can I see a sample code?
I can not figure it out