delphi窗口的双缓冲绘制浅析收藏

来源:互联网 发布:windows7装mac双系统 编辑:程序博客网 时间:2024/06/05 20:27

======================================================
注:本文源代码点此下载
======================================================

有时,在有大量图片或者复杂的界面下,会出现界面闪烁。这是由于windows默认在绘制界面前会用背景色清空,然后重绘。

因为默认背景色一般是白色的,当重绘速度慢时,看起来界面就在闪烁了。

那有没有在不提高界面绘制速度的情况下,防止闪烁呢,常用的办法就是启用双缓冲机制。

双缓冲绘制,就是在内存预先绘制好图形,再拷贝到界面上。中途不再清白背景。

delphi的wincontrol组件提供了双缓冲机制,所以从该组件继承的比如窗体,各类windows控件都有双缓冲绘制功能。

但默认情况下双缓冲绘制是关闭的,在手工设置 doublebuffered 属性为true后双缓冲绘制机制开启。无需添加其他代码。

下面就delphi的双缓冲原理做一简单的注释。(为简单起见,用屏幕上的和内存中的来表示双缓冲的两个部分)

procedure twincontrol.wmpaint(var message: twmpaint);

var

dc, memdc: hdc;

membitmap, oldbitmap: hbitmap;

ps: tpaintstruct;

begin

if not fdoublebuffered or (message. dc <> 0) then//查看doublebuffered属性和指定消息值,如果双缓冲关闭或者dc值有效,那么直接绘制图像 注★

begin

if not (cscustompaint in controlstate) and (controlcount = 0) then

inherited

else

painthandler(message); //调用具体过程来重画到message指定的设备上(内存中的或者屏幕上的)

end

else

begin//进入双缓冲处理

dc := getdc(0);

membitmap := createcompatiblebitmap(dc, clientrect.right, clientrect.bottom); //创建一个设备兼容位图(内存中)

releasedc(0, dc);

memdc := createcompatibledc(0);//创建一个兼容上下文绘图设备(内存中的)

oldbitmap := selectobject(memdc, membitmap);//将位图选中为绘图设备的当前对象,返回值为老的对象,给予保存

try

dc := beginpaint(handle, ps);//申明开始绘制,该函数会返回当前控件的上下文绘图设备(屏幕上的)

perform(wm_erasebkgnd, memdc, memdc); //发送背景清空消息(内存中的)

message.dc := memdc; (注★ 内存中的设备,该值不为零,会被上面的代码处理)

wmpaint(message);(递归调用本过程,让前面部分流程代码绘制图像到内存中)

message.dc := 0;

bitblt(dc, 0, 0, clientrect.right, clientrect.bottom, memdc, 0, 0, srccopy); (将内存中的图像拷贝到屏幕上)

endpaint(handle, ps); (结束绘制,并使得当前屏幕的无效区域变为有效)

finally

selectobject(memdc, oldbitmap); (重新将老的对象选择回去)

deletedc(memdc); (删除内存中的上下文设备)

deleteobject(membitmap); (删除内存中的对象)

end;

end;

end;

另外 beginpaint和getdc虽然返回值相同,但他们有明显区别。

beginpaint和endpaint常用于wm paint消息,且仅绘制无效区域,并使其有效。

就是说 getdc属于主动型,而 beginpaint 属于被动型的需在存在无效区域时才工作。

更多细节部分,可参看msdn


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击