Delphi/GDI+:设备上下文何时创建/销毁?

Ian*_*oyd 5 delphi graphics gdi+ paint

通常在 Delphi 中使用 GDI+,您可以使用 TPaintBox 并在OnPaint事件期间进行绘制:

\n\n
procedure TForm1.PaintBox1Paint(Sender: TObject);\nvar\n   g: TGPGraphics;\nbegin\n   g := TGPGraphics.Create(PaintBox1.Canvas.Handle);\n   try\n      g.DrawImage(FSomeImage, 0, 0);\n   finally\n      g.Free;\n   end;\nend;\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种范例的问题在于,每次创建并销毁Graphics对象都是浪费且性能不佳。此外, GDI+ 中有一些可用的构造,只有当您有持久的Graphics对象时才能使用。

\n\n

当然,问题是我什么时候可以创建该Graphics对象?我需要知道句柄何时可用,以及何时不再有效。我需要这些信息,以便我可以创建和销毁我的Graphics对象。

\n\n
\n\n

解决方案尝试 N\xc2\xba1

\n\n

我可以通过在真正需要时创建它来解决创建问题 - 在第一次调用绘制周期时:

\n\n
procedure TForm1.PaintBox1Paint(Sender: TObject);\nbegin\n   if FGraphics = nil then\n      FGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);\n\n   FGraphics.DrawImage(FSomeImage, 0, 0);\nend;\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我必须知道设备上下文何时不再有效,因此我可以销毁我的FGraphcis对象,以便下次需要时重新创建它。如果由于某种原因重新创建了TPaintBox的设备上下文,那么下次调用OnPaint时我将在无效的设备上下文上进行绘制。

\n\n

Delphi 中的预期机制是什么,让我知道何时创建、销毁或重新创建TPaintBox设备上下文句柄?

\n

Jer*_*ers 3

您不能使用标准 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;
Run Code Online (Sandbox Code Playgroud)

问题是 FreeHandle 和 SetControl 不是虚拟的。

但是:TControlCanvas 在这里创建并分配:

 constructor TGraphicControl.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas := TControlCanvas.Create;
   TControlCanvas(FCanvas).Control := Self;
 end;
Run Code Online (Sandbox Code Playgroud)

因此,您可以做的是创建一个具有虚拟方法的降序 TMyControlCanvas 和一个像这样分配 Canvas 的 TMyPaintBox:

 constructor TMyPaintBox.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas.Free;
   FCanvas := TMyControlCanvas.Create;
   TMyControlCanvas(FCanvas).Control := Self;
 end;
Run Code Online (Sandbox Code Playgroud)

然后您可以使用 TMyControlCanvas 中的方法动态创建和销毁您的 TGPGraphics。

这应该能让你继续前进。

——杰罗恩