delphi窗口的双缓冲绘制浅析
来源:互联网 发布:支持mac的大型网游 编辑:程序博客网 时间:2024/05/21 09:33
有时,在有大量图片或者复杂的界面下,会出现界面闪烁。这是由于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
- delphi窗口的双缓冲绘制浅析
- delphi窗口的双缓冲绘制浅析收藏
- Delphi 7 + GDIPlus 简单实现双缓冲绘制移动图形
- MFC窗口绘制浅析
- 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误
- mfc 双缓冲绘制背景
- delphi 使用双缓冲画图时的重要拷贝代码
- 如何处理窗口闪烁问题及双缓冲的原理
- NeHe的OpenGL教程1(Bang翻译Delphi版)-如何绘制OpenGL窗口
- 浅析 Android 的窗口
- 浅析 Android 的窗口
- 浅析 Android 的窗口
- 使用双缓冲技术绘制曲线图
- 双缓冲和绘制透明图
- 双缓冲解决绘制图象闪烁问题
- android绘制知识--双缓冲绘图技术
- Delphi实现正弦曲线的绘制
- VC绘制位图--BeginPaint()与GetDC()的区别和双缓冲
- 将墙上绘画做成连贯的flash,怎么做到的?
- RMReport3.51破解手札㈡
- 在弹出网页中 ,要语句不弹出新网页
- maven 项目转 eclipse
- IP 限制规则
- delphi窗口的双缓冲绘制浅析
- 生理卫生课的经典对白
- 在CLUSTER环境给SQL SERVER 2008打补丁时需要注意的问题
- RMReport3.51破解手札㈢
- Effective C# 备忘
- Google Book Search APIs——谷歌图书搜索API
- SQLServer2008中恼人的"阻止保存要求重新创建表的更改"
- 关于JNI 和JAVA 编码的问题小结
- linux任务自动化 初步接触crontab和at