PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Anonymous on January 20, 2006, 10:05:04 AM

Title: Combox Row Colours
Post by: Anonymous on January 20, 2006, 10:05:04 AM
Is it possible to have different text colors for each row in a combo box depending upon the value of the item in the row?
Title: Re: Combox Row Colours
Post by: Anonymous on January 20, 2006, 05:05:57 PM
Quote from: deadmontyIs it possible to have different text colors for each row in a combo box depending upon the value of the item in the row?

To answer my own question - Yes.  And I have found an example written in VB which I have converted to PB (and it works).  I shall post the code soon if anyone is interested.

Paul
Title: Combox Row Colours
Post by: TechSupport on January 20, 2006, 05:41:28 PM
Happy you found an answer to the question. I assume it involves custom draw much like the examples that I posted about coloring lines in a ListView.
Title: Combox Row Colours
Post by: Anonymous on January 20, 2006, 06:10:46 PM
Quote from: TechSupportHappy you found an answer to the question. I assume it involves custom draw much like the examples that I posted about coloring lines in a ListView.

No.  You used the CustomDraw message with the List View example.  I tried this initially, but never received the message.  After much pulling of hair I found an article that stated the CustomDraw message is only generated by a select few controls - the List Box and Combo Box not being amongst them.

So I found a VB example on CodeGuru which uses the WM_DrawItem message and that works very nicely.

Code to follow.

Paul
Title: Combox Row Colours
Post by: Anonymous on January 20, 2006, 06:39:09 PM
This is the code.  The code is taken out of context so could probably be tidied up.

ADDTIMESHEET is the form upon which the combo box STAFFLIST resides.  There are certain requirements placed upon the combo box for this to work, namely it must have the following properties; CBS_OWNERDRAWFIXED and CBS_HASSTRINGS.  

The combo box in question is filled with a list of names (in another piece of code).  Some of those names have an asterix after them (for example Fred Bloggs*).  It is these names that I wish to be coloured differently (red in this case).





Function ADDTIMESHEET_CUSTOM ( _
                            hWndForm      As Dword, _  ' handle of Form
                            wMsg          As Long,  _  ' type of message
                            wParam        As Dword, _  ' first message parameter
                            lParam        As Long   _  ' second message parameter
                            ) As Long

   Local myp As DRAWITEMSTRUCT Ptr
   

   Select Case wMsg 'process the messages

         
  Case %WM_DRAWITEM 'this is the one I want

  Dim sitem As Asciiz * 40  'this will hold the combo item text
  Local sitemlen As Long  'this will be its length
  Local lbackbrush As Long  'this is the back color for the box
 
  myp = lParam 'get the DRAWITEMSTRUCT Ptr
 
          If @myp.hwndItem = hwnd_ADDTIMESHEET_STAFFLIST Then  'that's me!

 
          SendMessage hwnd_ADDTIMESHEET_STAFFLIST, %CB_GETLBTEXT, @myp.itemID, VarPtr(sitem) 'get the combo item text

          sitemlen = SendMessage (hwnd_ADDTIMESHEET_STAFFLIST, %CB_GETLBTEXTLEN, @myp.itemID, 0) 'get the text length

'is this item selected?

If (@myp.itemState And %ODS_SELECTED) Then



          lbackbrush=CreateSolidBrush(GetSysColor(%COLOR_HIGHLIGHT))
          SetBkColor(@myp.hdc,GetSysColor(%COLOR_HIGHLIGHT))
          Else
          SetBkColor(@myp.hdc,GetSysColor(%COLOR_WINDOW))
          End If
         
          If Right$(sitem,1)="*" Then    'is a * appended to the name?
          SetTextColor(@myp.hdc, %Red)
          End If
         
         
         
          FillRect @myp.hdc, @myp.rcitem, lbackbrush  'paint the back colour
          TextOut @myp.hdc, @myp.rcitem.nLeft, @myp.rcitem.nTop, sitem, sitemlen  'draw the text
          End If        
           
   End Select
End Function



Apologies for quality and neatness of the code.

The only downside I have found with this, and I am sure if I had the time it could be fixed, is that it changes the height of the combo box (FF sets it initially at 21) and the spacing between lines.

Perhaps someone else could shed some light on how to set it back to its FF defaults.

Paul
Title: Combox Row Colours
Post by: TechSupport on January 20, 2006, 07:25:23 PM
I haven't had time to go through your code (its Friday night and my woman has plans for us tonight). One thing that I did notice is the brush lbackbrush does not seem to be deleted (via DeleteObject). This will cause a GDI leak... not good. ;)

I will take a close look tomorrow.
Title: Combox Row Colours
Post by: Anonymous on January 21, 2006, 05:56:25 PM
Found the solution to the row height and spacing.  Combo boxes fire a WM_MEASUREITEM event whenever a new item is added to the control's list.

The WM_MEASUREITEM event passes a MEASUREITEMSTRUCT which contains information concerning the item's box height and width, which can be changed during the event.

Paul
Title: Combox Row Colours
Post by: TechSupport on January 21, 2006, 06:29:11 PM
Hey Paul,

Yeah, I should have mentioned that message, sorry. I use custom draw for many of my controls. For example, the bitmaps that appear in FireFly's top menu are the result of dealing with WM_DRAWITEM and WM_MEASUREITEM and then drawing the menus myself.

Also, if you don't want to deal with creating and having to release a brush handle, you can use the following function to replace the FillRect one.


'//
'//  Fast way to paint a rectangular area without using a brush
'//
Sub PaintRect( ByVal hdc As Dword, rc As Rect, ByVal colour As Dword)
  Local oldcr As Dword
  oldcr = SetBkColor( hdc, colour )
  ExtTextOut hdc, 0, 0, %ETO_OPAQUE, rc, "", 0, 0
  SetBkColor hdc, oldcr
End Sub