Delphi 为什么在使用画布时重写的绘制过程会一次又一次地调用自身?

Delphi 为什么在使用画布时重写的绘制过程会一次又一次地调用自身?,delphi,Delphi,我从这个类开发自己的组件时遇到了这个问题:TImage 我使用了这个代码: procedure Paint;override; begin inherited canvas.TextOut(5,5,'Hi') end; 提前感谢,因为TImage是TGraphic Control的后代,程序绘制在内部处理 WMPaint(windows WM_PAINT)消息。因此,当您在TImage画布上绘制(内部绘制过程)时,windows会发送WM_绘制消息,并再次调用绘制 编辑: 一种方法是 proc

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

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

提前感谢

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

编辑: 一种方法是

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过程。

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

当您绘制到
TImage
时,您实际上是在绘制它显示的底层
TPicture
对象。如果尚未指定
Picture
属性,则控件将为其自身分配一个新的
TBitmap
,以便您可以使用该属性进行绘制。但当它指定自己的
Picture
属性时,会触发它重新绘制自己

TImage
的设计并不是为了利用你的工作方式。您将破坏用户指定的任何图形,这通常不是人们期望的
TImage
。如果要在不修改包含的图形的情况下为
TImage
绘制覆盖图,则应绘制到
继承的画布
,而不仅仅是
画布


或者,如果您不是真的想显示用户的图形,只是想在上面画画,那么纯旧的
TGraphicControl
可能是更好的基类。或者您甚至可能根本不需要自定义控件。只需在表单上放置一个
TPaintBox
,并在其
OnPaint
事件中放置绘图命令。

无需。即使在重写的绘制过程中,您也可以正确地进行绘制(绘制文本),但这是另一个问题。
TextOut
在哪里调用
FreeImage
?@Rob Kennedy:TCanvas.TextOut调用TCanvas.Changing。TCanvas。更改呼叫事件一次更改。事件OnChange设置为TBitmap.Changing。TBitmap中的第一行。更改呼叫自由映像。