Page 1 of 1

TTreeView colours

PostPosted: Mon Feb 26, 2018 7:14 am
by denville
BCB6 TTreeView

Have need to colour items which I do thus and it works brilliantly...

TreeView1CustomDrawItem(..)
{
HDC hDC = Sender->Canvas->Handle;
TColor fcl = clBlack;
TColor bcl = clWhite;

DefaultDraw = true;

if ( Node->Data != NULL )
{
// modify colours as required
}

if ( State.Contains( cdsFocused ) )
{
fcl = clWhite ;
bcl = bcl & ~0x00808080 ; // darken bcl
}

SetBkColor(hDC, bcl);
SetTextColor(hDC, fcl);
}

(The Focused bit just ensures text remains legible when focused even with otherwise illegible colour combinations.) Only query .. I would like to be able some times to set the Font to Bold. Can't work out how to do that.

I messed around all weekend with variations on Canvas and HDC and OnAdvancedCustomDrawItem but with abject failure!

Thanks in advance ?
Denville.

Re: TTreeView colours

PostPosted: Mon Feb 26, 2018 9:55 am
by HsiaLin
been a while since i used TreeView but i think you have to use something
like this to make it bold

((TTreeView*)Sender)->Font->Style = TFontStyles() << fsBold;

and something like this to make it unbold

((TTreeView*)Sender)->Font->Style = TFontStyles() >> fsBold;

Re: TTreeView colours

PostPosted: Mon Feb 26, 2018 2:08 pm
by denville
Sender->Canvas->Font->Style
does the trick.

Can't believe I didn't see that myself. Thanks !

Denville.

Re: TTreeView colours

PostPosted: Tue Feb 27, 2018 10:32 am
by rlebeau
denville wrote:
Code: Select all
TColor fcl = clBlack;
TColor bcl = clWhite;



Why not use the TreeView's default colors instead?

Code: Select all
TColor fcl = static_cast<TTreeView*>(Sender)->Font->Color;
TColor bcl = static_cast<TTreeView*>(Sender)->Color;


denville wrote:
Code: Select all
if ( State.Contains( cdsFocused ) )



Why cdsFocused and not cdsSelected? Focus and Selection are two different things. You should highlight the item when it is "selected", and draw a focus rectangle around it when it is "focused". An item can be selected but not focused, and vice versa.

denville wrote:
Code: Select all
fcl = clWhite ;
bcl = bcl & ~0x00808080 ;                       // darken bcl



Why not use user-defined system colors instead?

Code: Select all
fcl = clHighlightText;
bcl = clHighlight;


denville wrote:
Code: Select all
SetBkColor(hDC, bcl);
SetTextColor(hDC, fcl);



You should use the RTL's ColorToRGB() function when passing a TColor value to a Win32 API that expects a COLORREF value:

Code: Select all
SetBkColor(hDC, ColorToRgb(bcl));
SetTextColor(hDC, ColorToRgb(fcl));


This is especially important when dealing with system-defined colors.

That being said, you don't really need to resort to using SetBkColor() and SetTextColor() directly, you can use the Sender->Canvas->Font->Color and Sender->Canvas->Brush->Color properties instead, and let the TreeView call the API functions for you after the event handler exits (when DefaultDraw=true).

Re: TTreeView colours

PostPosted: Tue Feb 27, 2018 1:30 pm
by 2ffat
You can also look at BCBCAQ.com for articles like these:
Mastering TTreeView Part 1
Mastering TTreeView Part 2

Re: TTreeView colours

PostPosted: Thu Mar 01, 2018 6:55 am
by denville
Thanks Remy

I took control of fcl and bcl directly as otherwise I had to remember to set the TTreeView's Color to clWhite instead of the default clWindow. (At that point I hadn't discovered this and bcl was rendered as black).

Re Focused and Selected, the TV is read-only and the only important thing is the one item the user is looking at (ie focused on). In this context I am not sure there is a difference but I am sure you are right. Having said that, the object was to defeat the default rendition because in certain combinations of text and background colours (over which I have little control, and are perfectly satisfactory when not selected)) the focused (or selected) item becomes unreadable. I found from previous experience that the colour combinations I use give a very effective and reliably readable alternative.

You should use the RTL's ColorToRGB() function when passing a TColor value to a Win32 API that expects a COLORREF value:

Wow, thanks for that, I didn't realise.

My initial experimentation just used the VCL's TCanvas but that just didn't work reliably (no doubt it was me but I couldn't work out what was wrong). Eventually I got it to work using the API, mainly as a result of what I found on-line and the Journal articles Mastering the TreeView back in 1998 (the pile of journals is still my most useful reference) (thanks 2ffat !) and particularly Tree-Listviews by David Bridges back in 2002, where he makes use of the API - and this worked for me.

I'll have another look at it in the light of what you say. Thanks again.