- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
通常在 Delphi 中使用 GDI+,您可以使用 TPaintBox,并在 OnPaint 事件期间进行绘制:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
g: TGPGraphics;
begin
g := TGPGraphics.Create(PaintBox1.Canvas.Handle);
try
g.DrawImage(FSomeImage, 0, 0);
finally
g.Free;
end;
end;
这种范例的问题在于,每次创建并销毁一个 Graphics 对象既浪费又性能不佳。此外,还有一些constructs availabe in GDI+ 仅当您拥有持久图形对象时才能使用。
问题当然是什么时候我可以创建那个Graphics对象?我需要知道句柄何时可用,以及何时不再有效。我需要这些信息,以便我可以创建和销毁我的图形对象。
<小时/>我可以通过在真正需要时创建它来解决创建问题 - 在第一次调用绘制周期时:
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
if FGraphics = nil then
FGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);
FGraphics.DrawImage(FSomeImage, 0, 0);
end;
但我必须知道设备上下文何时不再有效,这样我就可以销毁我的 FGraphcis 对象,以便下次需要时重新创建它。如果由于某种原因重新创建了 TPaintBox 的设备上下文,那么下次调用 OnPaint 时我将在无效的设备上下文上进行绘制。
Delphi 中的预期机制是什么,让我知道何时创建、销毁或重新创建 TPaintBox 的设备上下文句柄?
最佳答案
您不能使用标准 TPaintBox,因为 TPaintBox 有一个 TControlCanvas 类型的 Canvas,与此问题相关的成员如下:
TControlCanvas = class(TCanvas)
private
...
procedure SetControl(AControl: TControl);
protected
procedure CreateHandle; override;
public
procedure FreeHandle;
...
property Control: TControl read FControl write SetControl;
end;
问题在于 FreeHandle 和 SetControl 不是虚拟的。
但是:TControlCanvas 是在此处创建并分配的:
constructor TGraphicControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
end;
因此,您可以做的是创建一个具有虚拟方法的降序 TMyControlCanvas 和一个像这样分配 Canvas 的 TMyPaintBox:
constructor TMyPaintBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas.Free;
FCanvas := TMyControlCanvas.Create;
TMyControlCanvas(FCanvas).Control := Self;
end;
然后您可以使用 TMyControlCanvas 中的方法动态创建和销毁您的 TGPGraphics。
这应该能让你继续前进。
--杰罗恩
关于德尔福/GDI+ : When is a Device Context created/destroyed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1615984/
我是一名优秀的程序员,十分优秀!