Delphi获取控件界面图像“新招”

    众所周知,Delphi是一种可视化编程方式的软件,在某些Delphi软件中,常常需要获取一些界面控件的图像,如TImage、TPaintBox、TPanel等控件。获取这些界面控件图像时,一般都是采用直接截屏的办法,但直接截屏的办法有一个缺陷,就是当这些控件完全或者部分被遮挡后,并不能获取其完整界面的图像。对TImage的截屏更是受到限制,因为除了BMP类型图像(即TImage.Picture.Graphic是TBitmap),其它格式图像时根本没法获取其有效画布(Canvas)。

    其实,在Delphi中采用截屏获取一些界面控件图像的办法,是一种惯性思维,是借用其它语言的办法,其它语言用截屏获取界面图像是不得已,如C/C++在编写Windows界面程序时,在响应绘制窗口消息时,往往都没有理会WM_PAINT消息的WPARAM参数(这个参数本应该是绘制窗口时所使用的设备上下文DC,但一般情况下是NULL,不能直接使用),而是使用BeginPaint或者GetDC等API获取窗口设备上下文DC后,来绘制界面的;而Delphi则不完全一样:除标准控件外,都是通过TWinControl和TGraphicControl,或者它们的派生类的WMPaint消息过程来绘制控件界面的,而WMPaint过程中Message.DC参数(也就是WM_PAINT消息的WPARAM参数)是有效的设备上下文DC(为什么这里的DC是有效的,本文就不详细解释了,可参阅VCL源码),这也就是说,除了标准控件外,只要我们有一个有效的设备上下文DC,就可以发送WM_PAINT消息给这些控件,让它们将“自己”完整的画在我们给定的设备上下文DC上!

    Ok,既然Delphi界面控件有这种“得天独厚”的优势,我们为什么不利用起来,而非要去截屏呢。下面就是本文所说的获取控件界面图像“新招”代码:

type TWControl = class(TWinControl) end; function GetControlBitmap(Control: TControl): TBitmap; overload; begin Result := TBitmap.Create; Result.PixelFormat := pf24Bit; Result.Canvas.Brush.Color := TWControl(Control).Color; Result.Width := Control.Width; Result.Height := Control.Height; if Control is TWinControl then TWControl(Control).PaintWindow(Result.Canvas.Handle) else Control.Perform(WM_PAINT, Result.Canvas.Handle, 0); end; function GetControlBitmap(Control: TControl; Rect: TRect): TBitmap; overload; var Bitmap: TBitmap; begin if IsRectEmpty(Rect) then begin Result := nil; Exit; end; Bitmap := GetControlBitmap(Control); if (Rect.Right - Rect.Left <> Control.Width) or (Rect.Bottom - Rect.Top <> Control.Height) then begin Result := TBitmap.Create; Result.PixelFormat := pf24Bit; Result.Width := Rect.Right - Rect.Left; Result.Height := Rect.Bottom - Rect.Top; Result.Canvas.CopyRect(Classes.Rect(0, 0, Result.Width, Result.Height), Bitmap.Canvas, Rect); Bitmap.Free; end else Result := Bitmap; end;

    实现代码很简单,稍具Delphi基础就可读懂。有一点还是要说明一下,因为本文过程不能获取标准控件的界面图像,所以在获取容器类控件界面图像时,干脆舍弃了所有的子控件界面,获取的容器类控件界面图像只包括其自身。

    当然,上面也说了,本办法也有局限性,即不能获取标准控件的界面图像,所以在某些需求下,使用截屏获取控件界面图像还是有必要的。

    下面的例子代码获取TImage的部分界面图像(被注释的语句是获取TImage完整界面图像):

var Bitmap: TBitmap; begin Bitmap := GetControlBitmap(Image1, Rect(50, 10, 250, 180)); // Bitmap := GetControlBitmap(Image1); Canvas.Draw(0, 0, Bitmap); Bitmap.Free; end;

    下面是例子运行界面截图:

Delphi获取控件界面图像“新招”_第1张图片

    截图右面是TImage控件,其上边被遮挡了一部分(超出窗体);左边是获取的TImage部分界面图像,其中就包含了TImage上边被遮挡的部分图像。

    指导和建议请来信:[email protected][email protected]

    后记:获取控件界面图像过程代码已于2009.11.25修改。

你可能感兴趣的:(编程,windows,image,Class,语言,Delphi)