Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

colour of DrawFocusRect()

961 views
Skip to first unread message

David Beardwood

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
hi all,

i'm drawing a focus rect for one of my components. it draws and undraws
itself correctly. i have finally figured out that the colour of the dots of
the rectangle depend on the brush colour of the canvas. unfortunately, it
_always_ comes out black. black is fine when you're drawing on silver (or
clBtnFace), but if you're drawing on navy blue (clHighlight) then black
doesn't show up. the colour i would expect is yellow. i looked at the code
for TDBLookupComboBox.Paint( ) as an example. their focus rect comes out
yellow on navy. from all i can see from the code is that the brush is set to
clHighlight and they draw the focus rect (yellow). how come mine doesn't
work??

thanks,
dave


Peter Below (TeamB)

unread,
Aug 25, 1999, 3:00:00 AM8/25/99
to
dave,

how are you drawing the focus rectangle? You should use DrawFocusRect, it
always draws with a xor pen and that usually makes the rectangle visble on any
background.


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!


David Beardwood

unread,
Aug 26, 1999, 3:00:00 AM8/26/99
to

> how are you drawing the focus rectangle? You should use DrawFocusRect, it
> always draws with a xor pen and that usually makes the rectangle visble on any
> background.

yes, i'm using DrawFocusRect. it still always comes out black unless the focus
rect is drawn on top of a colour that is not the canvas brush colour. i just wrote
this simple component to prove my point. i apologise for this longer than usual
code snippet. my focus rect still always comes out black, regardless of the Color
property value.

ideas??
thanks,
dave


unit DrawFocus_TestSimplePanel;

interface

uses Windows, Controls, Graphics, Messages;

type
TSimplePanel = class( TCustomControl )
private
procedure DrawFocus;
procedure WMSetFocus(var Msg: TMessage); message WM_SETFOCUS;
procedure WMKillFocus(var Msg: TMessage); message WM_KILLFOCUS;
protected
procedure Paint; override;
published
property Color;
end;

implementation

procedure TSimplePanel.DrawFocus;
var
r: TRect;
begin
r := ClientRect;
InflateRect( r, -6, -6 );
Canvas.Brush.Color := Color;
Canvas.DrawFocusRect( r );
end;

procedure TSimplePanel.WMSetFocus(var Msg: TMessage);
begin
DrawFocus;
end;

procedure TSimplePanel.WMKillFocus(var Msg: TMessage);
begin
DrawFocus;
end;

procedure TSimplePanel.Paint;
var
r: TRect;
begin
r := ClientRect;
Canvas.Pen.Color := clBlack;
Canvas.Brush.Color := Color;
Canvas.Rectangle( r.Left, r.Top, r.Right, r.Bottom );

if Focused then DrawFocus;
end;

David Beardwood

unread,
Aug 30, 1999, 3:00:00 AM8/30/99
to


> Well, DrawFocusrect has to decide on a pen color to use (which then
> gets xor'ed into the background) and it does this depending on brush
> color, in fact i think it simply used the brush color.

yeah, this is what i figured out.

> For kind of color selection there are color combinations that work well and
> others that do not. If you want to play a bit:..

unfortunately, i do not want to play. :) Color is quite often a published
property - it could be anything. i do not want to try to figure out how to
dynamically figure out what the brush colour should be for in order for the
focus rect to show up given some designer-defined color. it's not that i'm
particularly lazy or anything, but all the controls i've seen so far don't
have to do this. again, i return to the TDBLookupComboBox.Paint( ) method.
for some reason, they can set their brush to clHighlight (usually = clNavy)
and they get a yellow focus rectangle. yet still, mine comes out black.

all this tells me is that there's something i don't know, but it doesn't
suggest to me i should have to figure out a convenient brush color for my
focus rect to show up.

i don't suppose you have any other ideas....

dave

Peter Below (TeamB)

unread,
Aug 30, 1999, 3:00:00 AM8/30/99
to
> unfortunately, i do not want to play. :) Color is quite often a published
> property - it could be anything. i do not want to try to figure out how to
> dynamically figure out what the brush colour should be for in order for the
> focus rect to show up given some designer-defined color. it's not that i'm
> particularly lazy or anything, but all the controls i've seen so far don't
> have to do this. again, i return to the TDBLookupComboBox.Paint( ) method.
> for some reason, they can set their brush to clHighlight (usually = clNavy)
> and they get a yellow focus rectangle. yet still, mine comes out black.

I have looked at the VCL code you mentioned and cannot see any basic difference
to what my sample did. Setting the font.color does not change the outcome so it
does not seem to be involved. I have to punt, sorry.

David Beardwood

unread,
Aug 31, 1999, 3:00:00 AM8/31/99
to

> I have looked at the VCL code you mentioned and cannot see any basic difference
> to what my sample did. Setting the font.color does not change the outcome so it
> does not seem to be involved.

yeah, i even tried commenting out (almost) everything and recompiling, but their
code still works, and mine still doesn't. :(


> I have to punt, sorry.
>

:) thanks for the dialog - i appreciate it. i'll repost to see if anyone else has
some ideas.

thanks again,
dave


David Beardwood

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to mko...@mnic.net

i keep coming back to the TDBLookupComboBoxPlus.Paint( ) code. how come their's
works? well, i don't really have a complete answer for that, but i have determined
that the DrawFocusRect is more than a little tempermental...

using the code for the TSimplePanel that i posted earlier, i made a couple of changes
to my DrawFocus( ) method.

first, i replicated the yellow colour of the focus rect. the only really difference is
the TextRect call:

procedure TSimplePanel.DrawFocus;
var
r: TRect;
begin
r := ClientRect;
InflateRect( r, -6, -6 );
Canvas.Brush.Color := Color;

{*} Canvas.Font.Color := clHighlightText;
{*} Canvas.TextRect( r, 10, 10, '' );
Canvas.DrawFocusRect( r );
end;

the focus rect now draws a nice yellow on navy, grey on red, red on teal, etc. the
only place it doesn't work is when the colour is clBtnFace. note that you need _both_
of these lines. looking in the TextRect code is saw a special condition for brush
styles of bsClear. if just before the DrawFocusRect( ) call you change the bruch to
clear to solid (the default, and original style) you no longer get a dotted line but
rather a solid line, even though without the brush style lines the brush style is
bsSolid (i evaluated with a break point). it's messed up.


based on these results i found a relatively reasonable solution. at first i thought
that it was just setting the brush to the font colour somehow in the TextRect call. if
you take out the two new lines above, and just set the brush colour to clWhite (or
clHighlightText if you still have the default window colour settings) then you get
almost the ideal focus rect colours except for the light greys. for these it comes out
as a greyish colour, and not the black you would expect. there's still a contrast, but
the focus rect looks a little fuzzier than usual. this may be good enough. you could
also catch the special cases where the bkgnd colour is clBtnFace, clSilver, or some
similar shades, and set the brush colour to the bkgnd colour to get a black focus rect.

however, you should note the actual Windows functionality. i always assumed that the
focus rect should be the same colour as you get while dragging across the desktop to
create a selection rectangle. ie. if the desktop is red then the rect is grey, if it's
teal the rect is red(-ish), if it's dark blue the rect is yellow. turns out this isn't
what the default Windows colours are for _focus_ rects. if you change the colour of
the "3D Objects" (e.g buttons) in your display properties you find that the focus rects
are _always_ black. also note that if your desktop background is clSilver then you get
a dark grey selection rect as i got above with a brush colour of clWhite, not the black
that would look sharper.


so, in conclusion, if you want the always black focus rectangles windows functionality,
set the brush to the background colour. if you want the desktop selection rect
colours, set teh brush to clWhite. if you want some sort of inbetween to handle
variable colours and still get blacks, well, you have to write some special cases.

and that is focus rectangles....

good luck!
dave

Peter Below (TeamB)

unread,
Sep 1, 1999, 3:00:00 AM9/1/99
to
Thanks for the update, Dave. Sometimes Windows can try ones patience
<g>.
0 new messages