views:

95

answers:

1

I need to write some text to a paintbox, and I do it in the OnPaint event. When I set the fontsize twice in the method, the OnPaint-event is called repeatedly.

To see for yourself, try this:

  1. Create a new VCL Forms application
  2. Place a paintbox on the form
  3. Put the following code in the OnPaint-event:
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.MoveTo(random(PaintBox1.Width),random(PaintBox1.Height));
  PaintBox1.Canvas.LineTo(random(PaintBox1.Width),random(PaintBox1.Height));

  PaintBox1.Font.Size := 10; 
  PaintBox1.Font.Size := 12; 
end;

When you run the application you will see a line "jumping" around on the paintbox. However, if you remove one or both of the lines setting the fontsize, you will see a single, stationary line.

Why does this happen, and what can I do to work around it?

+6  A: 

Set PaintBox1.Canvas.Font.Size instead of PaintBox1.Font.Size and your problem will be solved.

As for why it happens: Changing the font property of a control will cause it to be invalidated and redraw, and doing this in the event that does the redrawing causes an infinite loop. Luckily paint events are synthesized and have lower priority than other messages, otherwise your program would hang.

mghie
All true, but I don't see why simple "if Field <> Value then" is not used. This would prevent needles repaints when font has not changed. VCL should use comparison like this in almost all setters.
Runner
@Runner: But the font *has* changed, twice in fact. And in both cases the check for inequality evaluated to `True`. That the change was revoked immediately doesn't really matter, as that is outside the scope of the setter. What you are asking for seems impossible to me.
mghie
@mghhie: I know that in his code the change must occour. I am talking about how VCL works. If you change the font size to 10 for instance and the size already is 10 you will fire a font change event event if nothing really changes. A simple compare would solve the problem. This is sloppy programming in my opinion. Yes I know I should not assign size if it is the same. But the VCL should check for such simple conditions. And TFont class is only one of many that has this weakness. And to make it worse, they do check the value when setting font name for instance.
Runner
Thanks, mghie, that solved it :-)
Svein Bringsli