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?
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
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.
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
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
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.
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
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