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
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.
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.
You should select TGraphicControl (or TCustomControl) as the parent of your own component to override Paint method properly.
精彩评论