Results 1 to 8 of 8

Thread: How to Make Each Line of a Listbox a Different Colour?

  1. #1

    Thread Starter
    New Member
    Join Date
    Jun 2016
    Posts
    7

    How to Make Each Line of a Listbox a Different Colour?

    Hi there, thanks for taking the time to read this.

    I was wondering if it was possible to make each line of a listbox a different colour. This would greatly improve my design for an AI chatbox I was designing in VB6. The way it should function is this:

    When the user inputs their text into the listbox, it should be green.
    I then have some pre-set outputs in my code to allow the AI to respond straightaway, however, the text should be red.

    How can I integrate this into my code?

  2. #2
    Lively Member
    Join Date
    Oct 2010
    Posts
    75

    Re: How to Make Each Line of a Listbox a Different Colour?

    I don't think this is possible with a listbox. Use ListView instead.

  3. #3

  4. #4
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to Make Each Line of a Listbox a Different Colour?

    Put List1 and List2 on a Form and make their Style = Checkbox


    Form Code

    Code:
    Private Sub Form_Load()
     Dim I As Integer
        
     For I = 15 To 0 Step -1
       'Load a List of 0 to 15 with the Item Data
       'Set to the QBColors 0 - 15
       List1.AddItem "Color " & I
       List1.itemData(List1.NewIndex) = QBColor(I)
     Next
        
     For I = 0 To 15
       'Load a List of 0 to 15 with the Item Data
       'Set to the QBColors 0 - 15
       List2.AddItem "Color " & I
       List2.itemData(List2.NewIndex) = QBColor(I)
     Next
        
     'Subclass the "Form", to Capture the Listbox Notification Messages
     lPrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf SubClassedList)
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
     'Release the SubClassing, Very Import to Prevent Crashing!
     Call SetWindowLong(hwnd, GWL_WNDPROC, lPrevWndProc)
    End Sub
    .BAS Code

    Code:
    Option Explicit
    
    Public Type RECT
            Left As Long
            Top As Long
            Right As Long
            Bottom As Long
    End Type
    
    Public Type DRAWITEMSTRUCT
            CtlType As Long
            CtlID As Long
            itemID As Long
            itemAction As Long
            itemState As Long
            hwndItem As Long
            hdc As Long
            rcItem As RECT
            itemData As Long
    End Type
    
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Public Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    Public Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
    Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Public Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
    Public Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
    Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
    Public Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
    Public Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
    
    Public Const COLOR_HIGHLIGHT = 13
    Public Const COLOR_HIGHLIGHTTEXT = 14
    Public Const COLOR_WINDOW = 5
    Public Const COLOR_WINDOWTEXT = 8
    Public Const LB_GETTEXT = &H189
    Public Const WM_DRAWITEM = &H2B
    Public Const GWL_WNDPROC = (-4)
    Public Const ODS_FOCUS = &H10
    Public Const ODT_LISTBOX = 2
    
    Public lPrevWndProc As Long
    
    Public Function SubClassedList(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
     Dim tItem As DRAWITEMSTRUCT
     Dim sBuff As String * 255
     Dim sItem As String
     Dim lBack As Long
        
     If Msg = WM_DRAWITEM Then
       'Redraw the listbox
       'This function only passes the Address of the DrawItem Structure, so we need to
       'use the CopyMemory API to Get a Copy into the Variable we setup:
       Call CopyMemory(tItem, ByVal lParam, Len(tItem))
            
       'Make sure we're dealing with a Listbox
       If tItem.CtlType = ODT_LISTBOX Then
         'Get the Item Text
         Call SendMessage(tItem.hwndItem, LB_GETTEXT, tItem.itemID, ByVal sBuff)
                
         sItem = Left(sBuff, InStr(sBuff, Chr(0)) - 1)
                
         If (tItem.itemState And ODS_FOCUS) Then
           'Item has Focus, Highlight it, I'm using the Default Focus
           'Colors for this example.
           lBack = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT))
                    
           Call FillRect(tItem.hdc, tItem.rcItem, lBack)
           Call SetBkColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHT))
           Call SetTextColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT))
           TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
           DrawFocusRect tItem.hdc, tItem.rcItem
         Else
           'Item Doesn't Have Focus, Draw it's Colored Background
           'Create a Brush using the Color we stored in ItemData
           lBack = CreateSolidBrush(tItem.itemData)
           'Paint the Item Area
           Call FillRect(tItem.hdc, tItem.rcItem, lBack)
                    
           'Set the Text Colors
           Call SetBkColor(tItem.hdc, tItem.itemData)
           Call SetTextColor(tItem.hdc, IIf(tItem.itemData = vbBlack, vbWhite, vbBlack))
           
           'Display the Item Text
           TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
         End If
                
         Call DeleteObject(lBack)
         
         'Don't Need to Pass a Value on as we've just handled the Message ourselves
         SubClassedList = 0
         Exit Function
       End If
     End If
        
     SubClassedList = CallWindowProc(lPrevWndProc, hwnd, Msg, wParam, lParam)
    End Function


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  5. #5
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How to Make Each Line of a Listbox a Different Colour?

    You could also use a richtextbox or a MSHFlexgrid to do the job.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  6. #6

    Thread Starter
    New Member
    Join Date
    Jun 2016
    Posts
    7

    Re: How to Make Each Line of a Listbox a Different Colour?

    Quote Originally Posted by jmsrickland View Post
    Put List1 and List2 on a Form and make their Style = Checkbox


    Form Code

    Code:
    Private Sub Form_Load()
     Dim I As Integer
        
     For I = 15 To 0 Step -1
       'Load a List of 0 to 15 with the Item Data
       'Set to the QBColors 0 - 15
       List1.AddItem "Color " & I
       List1.itemData(List1.NewIndex) = QBColor(I)
     Next
        
     For I = 0 To 15
       'Load a List of 0 to 15 with the Item Data
       'Set to the QBColors 0 - 15
       List2.AddItem "Color " & I
       List2.itemData(List2.NewIndex) = QBColor(I)
     Next
        
     'Subclass the "Form", to Capture the Listbox Notification Messages
     lPrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf SubClassedList)
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
     'Release the SubClassing, Very Import to Prevent Crashing!
     Call SetWindowLong(hwnd, GWL_WNDPROC, lPrevWndProc)
    End Sub
    .BAS Code

    Code:
    Option Explicit
    
    Public Type RECT
            Left As Long
            Top As Long
            Right As Long
            Bottom As Long
    End Type
    
    Public Type DRAWITEMSTRUCT
            CtlType As Long
            CtlID As Long
            itemID As Long
            itemAction As Long
            itemState As Long
            hwndItem As Long
            hdc As Long
            rcItem As RECT
            itemData As Long
    End Type
    
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Public Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    Public Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
    Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Public Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
    Public Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
    Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
    Public Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
    Public Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
    
    Public Const COLOR_HIGHLIGHT = 13
    Public Const COLOR_HIGHLIGHTTEXT = 14
    Public Const COLOR_WINDOW = 5
    Public Const COLOR_WINDOWTEXT = 8
    Public Const LB_GETTEXT = &H189
    Public Const WM_DRAWITEM = &H2B
    Public Const GWL_WNDPROC = (-4)
    Public Const ODS_FOCUS = &H10
    Public Const ODT_LISTBOX = 2
    
    Public lPrevWndProc As Long
    
    Public Function SubClassedList(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
     Dim tItem As DRAWITEMSTRUCT
     Dim sBuff As String * 255
     Dim sItem As String
     Dim lBack As Long
        
     If Msg = WM_DRAWITEM Then
       'Redraw the listbox
       'This function only passes the Address of the DrawItem Structure, so we need to
       'use the CopyMemory API to Get a Copy into the Variable we setup:
       Call CopyMemory(tItem, ByVal lParam, Len(tItem))
            
       'Make sure we're dealing with a Listbox
       If tItem.CtlType = ODT_LISTBOX Then
         'Get the Item Text
         Call SendMessage(tItem.hwndItem, LB_GETTEXT, tItem.itemID, ByVal sBuff)
                
         sItem = Left(sBuff, InStr(sBuff, Chr(0)) - 1)
                
         If (tItem.itemState And ODS_FOCUS) Then
           'Item has Focus, Highlight it, I'm using the Default Focus
           'Colors for this example.
           lBack = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT))
                    
           Call FillRect(tItem.hdc, tItem.rcItem, lBack)
           Call SetBkColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHT))
           Call SetTextColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT))
           TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
           DrawFocusRect tItem.hdc, tItem.rcItem
         Else
           'Item Doesn't Have Focus, Draw it's Colored Background
           'Create a Brush using the Color we stored in ItemData
           lBack = CreateSolidBrush(tItem.itemData)
           'Paint the Item Area
           Call FillRect(tItem.hdc, tItem.rcItem, lBack)
                    
           'Set the Text Colors
           Call SetBkColor(tItem.hdc, tItem.itemData)
           Call SetTextColor(tItem.hdc, IIf(tItem.itemData = vbBlack, vbWhite, vbBlack))
           
           'Display the Item Text
           TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
         End If
                
         Call DeleteObject(lBack)
         
         'Don't Need to Pass a Value on as we've just handled the Message ourselves
         SubClassedList = 0
         Exit Function
       End If
     End If
        
     SubClassedList = CallWindowProc(lPrevWndProc, hwnd, Msg, wParam, lParam)
    End Function
    Hi there,

    Sorry for the late reply. I was able to test this code and it works fine, however, I don't think you understood my initial brief. I will repeat:

    I only have one listbox, not two. When the user inputs their text, it should be red and the AI's response should be green.

    Thank you for taking the time to help me with this and I hope we can figure this out together.

  7. #7
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How to Make Each Line of a Listbox a Different Colour?

    The listbox is limited in what it can do. Trying to alter how it works is an ugly business IMHO.

    The Listview or MSHFlexGrid controls allow you to change colors per line. They are also part of VB6.
    You just have to add them to your VB6 toolbox by selecting them from the main menu
    Projects | Components. Scroll down and check the one you want.

    The Microsoft Heirarchical Flexgrid Control (MSHFlexGrid) can even have different background colors per line if you like.
    It also has the added benefit of having multiple columns should you choose to use them.
    You can access every cell as a simple 2D coordinate of rows and columns.
    It schrolls as well.

    The Listview can do some of the same but does not have background colors per line.
    Also I found it a bit different to get use to.

    Both also allow icons per line if you need them.

    All of these features are built into the controls. You do not have to resort to anything more complex.

    Here is a MSHFlexGrid example.
    Name:  FlexGRidSample.PNG
Views: 9208
Size:  8.8 KB
    Last edited by Gruff; Jul 15th, 2016 at 11:34 AM.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  8. #8
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: How to Make Each Line of a Listbox a Different Colour?

    Quote Originally Posted by johnbobby View Post
    I was able to test this code and it works fine, however, I don't think you understood my initial brief. I will repeat:
    I understood your request. The code was not written especially for you and common sense tells you that you only need to use one of the Listboxes. However, I don't think you read my signature since if you had you will note that I state if what I post will be useful then it is up to you to make whatever changes you feel necessary


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width