Delphi / GDI +:设备上下文何时创建/销毁? [英] Delphi/GDI+: When is a Device Context created/destroyed?

查看:146
本文介绍了Delphi / GDI +:设备上下文何时创建/销毁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  procedure TForm1.PaintBox1Paint(Sender:TObject); 
var
g:TGPGraphics;
begin
g:= TGPGraphics.Create(PaintBox1.Canvas.Handle);
尝试
g.DrawImage(FSomeImage,0,0);
终于
g.Free;
end;
end;

这个范例的问题是创建一个破坏图形对象时间浪费,表现不佳。此外,还有一些在GDI +中构建可用的,您可以 当你有一个持久的图形对象时使用。



这个问题当然是 em>我可以创建图形对象吗?我需要知道句柄何时可用,然后何时不再有效。我需要这些信息,所以我可以创建并销毁我的图形对象。




解决方法尝试Nº1



我可以在真正需要时创建它来解决创建问题 - 第一次调用 paint cycle 时:

  procedure TForm1.PaintBox1Paint(Sender:TObject); 
如果FGraphics = nil,则开始
然后
FGraphics:= TGPGraphics.Create(PaintBox1.Canvas.Handle);

FGraphics.DrawImage(FSomeImage,0,0);
end;

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



Delphi中的目标机制是什么,以便我知道何时创建,销毁或重新创建 TPaintBox 设备上下文句柄

解决方案

不能使用标准TPaintBox,因为TPaintBox具有TControlCanvas类型的Canvas,问题是这些:

  TControlCanvas =类(TCanvas)
私人
...
程序SetControl(AControl:TControl);
保护
过程CreateHandle;覆盖;
public
过程FreeHandle;
...
属性控制:TControl读取FControl写入SetControl;
end;

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



但是:TControlCanvas是在这里创建和分配的:

 构造函数TGraphicControl.Create(AOwner:TComponent); 
begin
继承创建(AOwner);
FCanvas:= TControlCanvas.Create;
TControlCanvas(FCanvas).Control:= Self;
end;

所以你可以做的是创建一个具有虚方法的递减TMyControlCanvas,以及一个赋值的TMyPaintBox这样的画布:

 构造函数TMyPaintBox.Create(AOwner:TComponent); 
begin
继承创建(AOwner);
FCanvas.Free;
FCanvas:= TMyControlCanvas.Create;
TMyControlCanvas(FCanvas).Control:= Self;
end;

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



这应该让你继续。



- jeroen


Normally using GDI+ in Delphi you can use a TPaintBox, and paint during the OnPaint event:

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;

The problem with this paradigm is that creating a destroying a Graphics object each time is wasteful and poorly performing. Additionally, there are a few constructs availabe in GDI+ you can only use when you have a persistent Graphics object.

The problem, of course, is when can i create that Graphics object? i need to know when the handle becomes available, and then when it is no longer valid. i need this information so i can create and destroy my Graphics object.


Solution Attempt Nº1

i can solve the creation problem by creating it when it is really needed - on the first time the paint cycle is called:

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
   if FGraphics = nil then
      FGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);

   FGraphics.DrawImage(FSomeImage, 0, 0);
end;

But i have to know when the device context is no longer valid, so i can destroy my FGraphcis object, so that it is re-created the next time it's needed. If for some reason the TPaintBox's device context gets recreated, i would be drawing on an invalid device context the next time OnPaint is called.

What is the intended mechanism in Delphi for me to know when the device context handle of a TPaintBox is created, destroyed, or re-created?

解决方案

You can't with the standard TPaintBox because the TPaintBox has a Canvas of type TControlCanvas, for which members relevant to this issue are these:

TControlCanvas = class(TCanvas)
private
  ...
  procedure SetControl(AControl: TControl);
protected
  procedure CreateHandle; override;
public
  procedure FreeHandle;
  ...
  property Control: TControl read FControl write SetControl;
end;

The problem is that FreeHandle and SetControl are not virtual.

But: the TControlCanvas is created and assigned here:

 constructor TGraphicControl.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas := TControlCanvas.Create;
   TControlCanvas(FCanvas).Control := Self;
 end;

So what you could do is create a descending TMyControlCanvas that does have virtual methods, and a TMyPaintBox that assigns the Canvas like this:

 constructor TMyPaintBox.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas.Free;
   FCanvas := TMyControlCanvas.Create;
   TMyControlCanvas(FCanvas).Control := Self;
 end;

Then you can use the methods in TMyControlCanvas to dynamically create and destroy your TGPGraphics.

That should get you going.

--jeroen

这篇关于Delphi / GDI +:设备上下文何时创建/销毁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆