C++零食:WTL中使用双缓冲避免闪烁
双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板。首先我们在内存环境中建立一个“虚拟“的黑板,然后在这块黑板上绘制复杂的图形,等图形全部绘制完毕的时候,再一次性的把内存中绘制好的图形“拷贝”到另一块黑板(屏幕)上。采取这种方法可以提高绘图速度,极大的改善绘图效果。
例如在OnDraw()函数中可以如下所述实现双缓冲,其主要步骤分为四步:
CPen Pen;
Pen.CreatePen(PS_INSIDEFRAME,1,RGB(225,225,0));
CBrush Brush;
Brush.CreateSolidBrush(RGB(225,225,0));
CDC dcMem;
CBitmap bm;
CRect rc;
GetClientRect(&rc);
// Step 1:为屏幕DC创建兼容的内存DC :CreateCompatibleDC()
dcMem.CreateCompatibleDC(pDC);
// Step 2:创建位图:CreateCompatibleBitmap()
bm.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
// Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布
dcMem.SelectObject(&bm);
dcMem.SelectObject(Pen);
dcMem.SelectObject(Brush);
dcMem.Ellipse(0,0,50,50);//画椭圆
// Step 4:把绘制好的图形“拷贝“到屏幕上:BitBlt()
pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC();
bm.DeleteObject();
这样便实现了双缓冲,通过这个方法可以防止在VC中画图时出现屏幕闪烁的情况。
在自己画的窗口中,有时候会有闪烁现象。为什么会有闪烁现象呢?其实是因为程序在画窗口时需要用背景色清空显示区域,然后再画。由于这两者的反差比较大,就会被人眼睛捕捉到,感觉闪烁。
双缓冲就是先在内存中把图画好,然后直接复制到屏幕上去,这样的反差就比较小,也就不觉得闪烁了。

WTL中的CDoubleBufferImpl
WTL中有现成的双缓冲类实现,可以很方便的使用就达到效果。
CDoubleBufferImpl 在AtlFrame.h中。
1.首先继承自CDoubleBufferImpl
class TCtrl:
public CWindowImpl< TCtrl>,
public WTL::CDoubleBufferImpl<TCtrl> // 继承双缓冲类
2.由于双缓冲类中已经处理了WM_ERASEBKGND 和WM_PAINT消息,所以需要从你的代码中删除对这些消息的处理。然后加上双缓冲的消息处理即可。
BEGIN_MSG_MAP(TCtrl)
// MESSAGE_HANDLER(WM_PAINT, OnPaint)
CHAIN_MSG_MAP( WTL::CDoubleBufferImpl<TCtrl>)
END_MSG_MAP()
3.增加一个DoPaint函数,函数声明如下:
void DoPaint(CDCHandle dc);
4.将原来OnPaint函数中的代码移到DoPaint中,注意原来的CPaintDC需要改用参数中的CDCHandler
void TCtrl::DoPaint( CDCHandle dc )
{
//CPaintDC dc(m_hWnd);
dc.MoveTo( xx… )
}
OK,编译吧。
参考资料
VC画图不闪烁的方法(双缓冲技术)
http://hi.baidu.com/lovefqing/blog/item/3f86cdb6cc5c75f830add174.html
走近WTL--GDI篇
http://blog.iceyer.net/walk_up_to_wtl_gdi_part
Visual C++中实现双缓冲的基本原理
http://www.builder.com.cn/2007/1016/558583.shtml
C++零食:WTL中使用双缓冲避免闪烁的更多相关文章
- Qt组件中的双缓冲无闪烁绘图
双缓冲绘图在Qt4中,所有的窗口部件默认都使用双缓冲进行绘图.使用双缓冲,可以减轻绘制的闪烁感.在有些情况下,用户要关闭双缓冲,自己管理绘图.下面的语句设置了窗口部件的Qt::WA_PaintOn ...
- OpenGL中实现双缓冲技术
在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | G ...
- C#中利用双缓冲技术解决绘图闪屏问题。
这段时间在做一个小型游戏,在界面显示的时候用到了一些图形.一开始涉及到的图形全都用控件的背景图片代替了.这样游戏运行的时候存在的一个很大的问题是游戏运行很慢.小组成员费尽周折,即将放弃,每一个成员都愁 ...
- C#中使用双缓冲来避免绘制图像过程中闪烁
自己所做项目中,在显示医学图像的界面中,当鼠标拖动图像时,不断刷新从后台获取新的图像,而整个过程就很诡异,一直闪个不停. 找到的一个可行方法是:在用户控件的构造函数中加入以下代码: SetStyle( ...
- MFC中的双缓冲技术(解决绘图闪烁问题)
转自 MFC绘图不闪烁——双缓冲技术[转] 在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃. 所谓双缓冲技术,下面是百度百科的 ...
- [Qt2D绘图]-06QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题
本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题 大纲: 复合模式 双缓冲绘图 绘图中的其他问题 ...
- C++实现双缓冲
首先声明下,这篇资料也是整理别人的资料的基础上,总结来的. 在图形图像处理过程中,双缓冲技术是一种比较常见的技术.窗体在响应WM_PAINT消息时,需要对图像进行绘制处理.如果图像绘制次数过多,重绘过 ...
- MFC双缓冲绘图实例
本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...
- C#绘图双缓冲
C#绘图双缓冲 C#双缓冲解释: 简单说就是当我们在进行画图操作时,系统并不是直接把内容呈现到屏幕上,而是先在内存中保存,然后一次性把结果输出来,如果没用双缓冲的话,你会发现在画图过程中屏幕会闪的很厉 ...
随机推荐
- HDFS的HA集群原理分析
1.简单hdfs集群中存在的问题 不能存在两个NameNode 单节点问题 单节点故障转移 2.解决单节点问题 找额外一个NameNode备份原有的数据 会出现脑裂 脑裂:一个集群中多个管理者数据 ...
- (四)注册登录--重用Django
一.使用已有登录功能 (1)进入Lib\sitepackages\django\contrib\admin\templates\registration下,将对应模板,复制到项目template模板中 ...
- Flutter 不能热加载,热重载按钮灰色,无法点击,flutter doctor 显示NO_PROXY is not set
一.现象: Flutter 不能热加载 热重载按钮灰色,无法点击. 二.分析原因: 终端 flutter doctor 显示 NO_PROXY is not set 没有设置无代理的端口 终端:flu ...
- TensorFlow——学习率衰减的使用方法
在TensorFlow的优化器中, 都要设置学习率.学习率是在精度和速度之间找到一个平衡: 学习率太大,训练的速度会有提升,但是结果的精度不够,而且还可能导致不能收敛出现震荡的情况. 学习率太小,精度 ...
- cogs 1001. [WZOI2011 S3] 消息传递 Tarjan
1001. [WZOI2011 S3] 消息传递 ★★ 输入文件:messagew.in 输出文件:messagew.out 简单对比时间限制:1 s 内存限制:128 MB Prob ...
- 快速幂模板Super
//求x^nint ans=1;while(n){ if(n&1) ans=ans*x; x*=x; n>>=1;} 快速幂就是快速算底数的n次幂.其时间复杂度为 O(logN), ...
- Spring-cloud微服务实战【三】:eureka注册中心(中)
回忆一下,在上一篇文章中,我们创建了两个springboot项目,并且在consumer项目中通过restTemplate进行HTTP通信,成功访问到了producer提供的接口,思考一下这样的实 ...
- LCA - 倍增法去求第几个节点
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, ...
- 解析Json字符串中的指定的值
{ "head": { ", "Id": "20191008144448iAQE", "Message": & ...
- Centos 7.2 Jenkins+Ansible+Gitlab 基础配置
注意:首先准备jenkins服务器 如何搭建jenkins 由于上篇文章中jenkins是采用war并部署在tomcat中来完成的安装,所以这里隆重介绍下启动tomcat的用户:tomcat,下面会 ...