当我使用Canvas时,为什么要一次又一次地重写Paint过程调用自身?

时间:2010-08-29 07:05:56

标签: delphi

当我从这个类开发自己的组件时遇到了这个问题:TImage 我使用了这段代码:

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

提前致谢

3 个答案:

答案 0 :(得分:4)

因为TImage是TGraphicControl的后代,所以在内部处理Paint程序 WMPaint(windows WM_PAINT)消息。因此,当您在TImage画布上绘制(绘制内部程序)时,窗口会发送WM_PAINT消息并再次调用Paint。

编辑: 一种方法是......

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

因为Windows.ExtTextOut是API调用,不会发送WM_PAINT消息,如...

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

......内部称为FreeImage程序。

答案 1 :(得分:3)

当您绘制到TImage时,您实际上正在绘制它所显示的基础TPicture对象。如果尚未分配Picture属性,则控件将为自己分配新的TBitmap,以便您可以在其上进行绘制。但是当它分配自己的Picture属性时,会触发它重绘自己。

TImage并非真正意图以您自己的方式绘制。您将污损您的用户指定的任何图形,这通常不是人们对TImage的期望。如果您想为TImage绘制叠加层而不修改包含的图形,那么您应该绘制到inherited Canvas而不是Canvas

或者,如果您不想显示用户的图形并且只想要绘制某些内容,那么普通的TGraphicControl可能是更好的基类。或者你可能根本不需要自定义控件。只需在表单上放置一个TPaintBox,然后将绘图命令放在OnPaint事件中。

答案 2 :(得分:2)

您应该选择TGraphicControl(或TCustomControl)作为您自己组件的父级,以正确覆盖Paint方法。