【发布时间】:2011-12-18 18:44:40
【问题描述】:
我应该如何在画布上绘制文本,以使文本在重新绘制/更新/刷新后不会消失,而无需一次又一次地重新绘制?就像它被画成图像而不是临时画的一样。
【问题讨论】:
-
这取决于你在画什么画布。如果您正在使用自定义控件,则有一种方法可以使用。但如果您使用的是表单的画布之类的东西,那就另当别论了。
标签: delphi canvas delphi-7 paint
我应该如何在画布上绘制文本,以使文本在重新绘制/更新/刷新后不会消失,而无需一次又一次地重新绘制?就像它被画成图像而不是临时画的一样。
【问题讨论】:
标签: delphi canvas delphi-7 paint
例如,如果您谈论的是TPaintBox 控件或类似的东西,那么就没有可在其上绘制的持久画布。系统根本不是这样设计的,VCL 控件反映了底层的 Windows 框架。
正常做法如下:
有多种原因可能会导致您采用这种方法。通常,性能是一个因素。绘制和缓存图像可能会很昂贵。有时,绘制所需的信息可能是暂时的,再次缓存输出可能是一种解决方案。
【讨论】:
你不能。绘画只在屏幕上显示一次图像;如果您希望它持续存在,那么您必须在每次操作系统请求它时重新绘制它。
【讨论】:
使用 TLabel(或一些衍生产品)并将其放置在画布上。 TLabel 将在必要时重新绘制自身。
【讨论】:
你只需要在系统说你应该画的时候画。关于这个主题有两件事需要了解...
缓存
您还可以实现自己的缓存系统。在处理多个图层时,这可能会有些棘手。您可能有一个特定区域,预计该区域会发生高速变化。然后背景大概不会改变,除非它被调整大小,或者颜色已经改变,等等。比如针在一些照片上移动。只需在背景中保留两个不同的图像对象并将它们组合起来,确保至少顶部的对象是透明的。
您还可以使用Invalidate 命令告诉Windows 您的控件缓存何时失效(下一个主题...)。这将告诉 Windows 您控件中的某些内容已更改为您需要重绘所有内容的程度。然后,Windows 将决定何时准备好通过调用Paint 过程来实际告诉您的控件再次绘制。
系统绘制
正如大卫在他的回答中提到的那样,如果您正在使用控件,那么您应该在系统要求时重新绘制背景。这是通过从TGraphicControl 或TCustomControl(以及其他一些)继承Paint 过程来实现的。每次系统说您需要刷新控件的内容时,都会调用此过程。这是系统在缓存失效时通知您的方式。
procedure Paint; override;
...
procedure TMyCustomControl.Paint;
begin
DoSomeDrawingOnCanvas;
end;
另一方面,您也可以随时告诉 Windows 调用此 Paint 过程...
procedure TMyCustomControl.SetWidth(const Value: Integer);
begin
if Value <> FWidth then begin //Just a common check for performance reasons
FWidth:= Value;
Invalidate; //This tells Windows that you want to repaint your control
end;
end;
【讨论】: