delphi窗口的双缓冲绘制浅析收藏
有时,在有大量图片或者复杂的界面下,会出现界面闪烁。这是由于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
posted on 2009-07-06 22:55 伊布 阅读(...) 评论(...) 编辑 收藏转载于:https://www.geek-share.com/detail/2457892100.html
- 点赞
- 收藏
- 分享
- 文章举报
- delphi窗口的双缓冲绘制浅析收藏
- delphi窗口的双缓冲绘制浅析收藏
- delphi窗口的双缓冲绘制浅析收藏
- delphi窗口的双缓冲绘制浅析
- MFC窗口绘制浅析
- WM_ERASEBKGND官方解释(翻译),以及Delphi里所有的使用情况(就是绘制窗口控件背景色,并阻止进一步传递消息)
- NeHe的OpenGL教程1(Bang翻译Delphi版)-如何绘制OpenGL窗口
- Delphi 7 + GDIPlus 简单实现双缓冲绘制移动图形
- [Delphi]制作类似WinAmp一样的“磁性”窗口【转载/收藏】
- Qt自定义界面类并提升(提升的窗口部件),把OpenGL绘制的图形显示在QT的ui界面上
- Delphi中MessageBox用法收藏
- Delphi 开发易语言支持库再获重大进展,支持窗口控件了
- [Borland.Delphi.V1.V2.V.3.古董.怀旧.供爱好者收藏用].Borland.Delphi5.rar
- 循序渐进实现仿QQ界面(一):园角矩形与双缓冲贴图窗口
- 請各位delphi前輩將如下這段BCB防重開同一窗口的代碼轉成delphi,我試了好久都不成功,對delphi認識太少,多謝了。
- Delphi AnimateWindow 用法 淡入淡出窗口
- delphi中关于bpl发布时将vcl60.bpl,vcldb60.bpl......等多个bpl 打包成一个bpl的方法=====转帖收藏
- Delphi 类与对象内存结构浅析(附件1)
- Delphi获取其它进程窗口句柄的3种方法
- Android 绘制原理浅析【干货】