双缓冲绘图技术

更新时间:2023-11-05 10:57:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

双缓冲绘图技术.txt7温暖是飘飘洒洒的春雨;温暖是写在脸上的笑影;温暖是义无反顾的响应;温暖是一丝不苟的配合。8尊重是一缕春风,一泓清泉,一颗给人温暖的舒心丸,一剂催人奋进的强心剂由双缓冲绘图技术谈起到Delphi源码实现

摘要:双缓冲绘图技术在Delphi中的实现

关键字:Delphi,双缓冲,Canvas

作者:上海翰博数码科技实业有限公司 沈小云

说明:假设读者熟悉VCL

双缓冲绘图也不是什么新技术,简单的说:在绘图实现时不直接绘在窗口上,而是先绘在内存里,再一起“拷贝”至窗口。实现起来也不复杂,创建一兼容HDC,在此兼容HDC上绘图,最后拷贝到窗口HDC就行了。本人前段时间把一C++实现该技术的代码改成了Delphi代码,都是用Win32API写的。今改成了使用Delphi自带的类,试了一下(窗口类Canvas与TImage的Canvas)。实现方式大同小异,但不得不提的是在窗口中直接使用Canvas绘图与TImage.Canvas却不相同。使用TImage.Canvas绘图时,自动使用了双缓冲技术,而窗口的Canvas对像却未实现。怎么回事呢?看一下代码吧,“源码面前没有秘密”!

一.TImage类的Canvas

TImage = class(TGraphicControl) ...

property Canvas: TCanvas read GetCanvas; ...

function TImage.GetCanvas: TCanvas; var

Bitmap: TBitmap;

begin

if Picture.Graphic = nil then

begin

Bitmap := TBitmap.Create;

try

Bitmap.Width := Width;

Bitmap.Height := Height;

Picture.Graphic := Bitmap;

finally

Bitmap.Free;

end;

end;

if Picture.Graphic is TBitmap then

Result := TBitmap(Picture.Graphic).Canvas

else

raise EInvalidOperation.Create(SImageCanvasNeedsBitmap); end;

可知TImage.Canvas来自Bitmap.Canvas,好,那来看看TBitmap.Canvas

function TBitmap.GetCanvas: TCanvas;

begin

if FCanvas = nil then

begin

HandleNeeded;

if FCanvas = nil then // possible recursion

begin

FCanvas := TBitmapCanvas.Create(Self);

FCanvas.OnChange := Changed;

FCanvas.OnChanging := Changing;

end;

end;

Result := FCanvas; end;

显而易见TBitmap.Canvas = TBitmapCanvas.Create;也就是说TImage.Canvas=TBitmapCanvas.Create.即使用TImage.Canvas绘图时,实际是在TBitmapCanvas上绘图的。让我们再来看看TBitmapCanvas类:

TBitmapCanvas = class(TCanvas)

private

FBitmap: TBitmap;

FOldBitmap: HBITMAP;

FOldPalette: HPALETTE;

procedure FreeContext;

protected

procedure CreateHandle; override;

public

constructor Create(ABitmap: TBitmap);

destructor Destroy; override;

end;

关注一下CreateHandle函数:

procedure TBitmapCanvas.CreateHandle; var

H: HBITMAP;

begin

if FBitmap <> nil then

begin

Lock;

try

FBitmap.HandleNeeded;

DeselectBitmap(FBitmap.FImage.FHandle);

//!! DeselectBitmap(FBitmap.FImage.FMaskHandle);

FBitmap.PaletteNeeded;

H := CreateCompatibleDC(0);

if FBitmap.FImage.FHandle <> 0 then

FOldBitmap := SelectObject(H, FBitmap.FImage.FHandle) else

FOldBitmap := 0;

if FBitmap.FImage.FPalette <> 0 then

begin

FOldPalette := SelectPalette(H, FBitmap.FImage.FPalette, True);

RealizePalette(H);

end

else

FOldPalette := 0;

Handle := H;

BitmapCanvasList.Add(Self);

finally

Unlock;

end;

end; end;

读起来也不困难,FBitmap是Create构造函数传进来的。而我们应该关注的代码位于斜体部份,也很好理解:创建兼容DC,并选进设备。要的就是这个效果,现在知道为什么使用TImage.Canvas来绘图是使用的双缓冲技术的了吧?那么这个兼容DC是如何从内存“拷贝”到窗口的呢?

我们使用上面的分析方法,当TImage基类TGraphicControl收到WM_PAINT消息时,将执行下面的代码:

procedure TGraphicControl.WMPaint(var Message: TWMPaint);

begin

本文来源:https://www.bwwdw.com/article/s182.html

Top