tags:

views:

199

answers:

3

I had this problem when I was developing my own component from this class: TImage And I used this code:

procedure Paint;override;
begin
inherited
canvas.TextOut(5,5,'Hi')
end;

Thanks in advance

+3  A: 

Because the TImage is descendant of TGraphicControl and the procedure Paint is handled inside WMPaint (windows WM_PAINT) message. So when you paint (inside paint procedure) to the TImage canvas the windows send WM_PAINT message and Paint is called again.

EDIT: One way to do this is...

procedure TMyImage.Paint;
const
  Text = 'Hi';
begin
  inherited;
  Windows.ExtTextOut(Canvas.Handle, 5, 5, 0, nil, PChar(Text), Length(Text), nil);
end;

Because Windows.ExtTextOut is API call and will not send WM_PAINT message like...

canvas.TextOut(5,5,'Hi') 

...which internaly call FreeImage procedure.

GJ
Where does `TextOut` call `FreeImage`?
Rob Kennedy
@Rob Kennedy: TCanvas.TextOut call TCanvas.Changing. TCanvas.Changing call event OnChanging. Event OnChanging is set to TBitmap.Changing. First line in TBitmap.Changing call FreeImage.
GJ
+2  A: 

You should select TGraphicControl (or TCustomControl) as the parent of your own component to override Paint method properly.

Keeper
Not necessary. Even in overriden Paint procedure you can do this right (paint text), but this is another question.
GJ
+3  A: 

When you paint to a TImage, you're really painting to the underlying TPicture object that it displays. If the Picture property isn't yet assigned, then the control will allocate a new TBitmap for itself so you can draw on that instead. But when it assigns its own Picture property, that triggers it to repaint itself.

TImage isn't really designed to draw on itself the way you're doing it. You're going to deface whatever graphic your users assign, which usually isn't what people expect from a TImage. If you want to draw an overlay for the TImage without modifying the contained graphic, then you should draw to inherited Canvas instead of just Canvas.

Or, if you don't really want to display a user's graphic and just want something to paint on, then plain old TGraphicControl is probably the better base class. Or you might not even need a custom control at all. Just put a TPaintBox on your form and put your drawing commands in its OnPaint event.

Rob Kennedy