前言:

闪烁问题,之前的经验是使用双缓冲,借此机会,把双缓冲的研究心得总结下。

双缓冲的含义:

缓冲这个词,相信大家都不陌生,Cache。主要是为了解决上下游(或者模块、或者系统)等性能不匹配问题。如果把上游看成“生产者”,下游看成“消费者”,当“生产者”与“消费者”的处理速度不同时,为了避免干等,中间会加一些缓冲区。

无缓冲,双方都容易阻塞。

最常用的生产者-消费者模型,增加弹性缓冲,缺点是每生产+每消费都需要加锁

双缓冲,等消费者队列为空时加锁,执行exchange(如swap方法),大大减少了加锁次数。

双缓冲在界面的使用:

        在图形图象处理编程过程中,双缓冲是一种基本的技术。我们知道,如果窗体在响应WM_PAINT消息的时候要进行复杂的图形处理,那么窗体在重绘时由于过频的刷新而引起闪烁现象。解决这一问题的有效方法就是双缓冲技术。因为窗体在刷新时,总要有一个擦除原来图象的过程OnEraseBkgnd,它利用背景色填充窗体绘图区,然后在调用新的绘图代码进行重绘,这样一擦一写造成了图象颜色的反差。当WM_PAINT的响应很频繁的时候,这种反差也就越发明显。于是我们就看到了闪烁现象。
         双缓冲我们会很自然的想到,避免背景色的填充是最直接的办法。但是那样的话,窗体上会变的一团糟。因为每次绘制图象的时候都没有将原来的图象清除,造 成了图象的残留,于是窗体重绘时,画面往往会变的乱七八糟。所以单纯的禁止背景重绘是不够的。我们还要进行重新绘图,但要求速度很快,于是我们想到了使用 BitBlt函数。它可以支持图形块的复制,速度很快。我们可以先在内存中作图,然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消除了闪 烁。以上也就是双缓冲绘图的基本的思路。
 

GDI双缓冲:

WM_ERASEBKGND : 返回1,禁止背景重绘

HDC hDc = ::GetDC( m_hWnd) ;
RECT rcDest;
HDC hMemDc = CreateCompatibleDC(hDc);
HBITMAP hMemBitmap = CreateCompatibleBitmap(hDc); //内存画布,放到内存DC中就可以在内存中画图了
HBITMAP hOldBitmap = ::SelectObject (hDC, hBitmap);
//....hMemDc作画
::BitBlt (m_hDestDC, rc.left, rc.top, rc.Width(), rc.Height(), hDC, rc.left, rc.top, SRCCOPY); //拷贝到显示器缓冲 //资源释放与还原
::SelectObject (hDC, hOldBitmap);
DeleteObject(hMemBitmap);
DeleteDC(hMemDc);
ReleaseDC(m_hWnd,hDc);

  

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… )
}

Duilib双缓冲:

Duilib使用的GDI+引擎,也已经支持双缓冲,这里简单介绍下它的实现过程

1、Duilib也默认处理了WM_REASEBKGND 并返回1;

2、IRenderContext  类负责渲染。

目前由RenderContext_GdiPlus来实现。

1)构造函数中,创建内存DC

2) 获取绘图区域后,创建内存Bitmap

然后作画,细节暂时略,后续源码剖析会补充,敬请期待。

最后,拷贝到显示器缓冲。

Duilib的双缓冲实现,附带GDI、WTL的双缓冲实现的更多相关文章

  1. js 实现动态key value(JSON字符串注意事项:key和value都要用双引号,官网指定用双引号)

    1.JSON字符串注意事项:key和value都要用双引号,官网指定用双引号,如下: var mapStr='{"a":"a","b":&q ...

  2. WTL使用双缓冲避免重绘闪烁

    1.继承自CDoubleBufferImpl template <class T> class CDoubleBufferImpl { public: // Overrideables v ...

  3. 做双网卡绑定_______物理机在双网卡的情况下做多IP绑定

    公司的环境是这样的: 一台物理机需要做双网卡绑定,同时呢,在双网卡绑定的同时还要做多IP. 其实整个过程可以分为两个步骤: 第一个,物理机先做双网卡. 第二个,在bond上做多IP实例. 双网卡绑定的 ...

  4. JAVA中”单引号”,“双引号”,“没有单引号和双引号”区别:

    单引号引的数据 是char类型的——>单引号只能引一个字符(表示单个字符)双引号引的数据 是String类型的——>而双引号可以引0个及其以上(引用字符串) char类型的值用单引号引起来 ...

  5. linux中配置双网卡的目的?如何实现双网卡绑定,以实现负载均衡?

    配置双网卡的目的:========================== 1.你想做路由器,网关 2.实现冗余 3.负载均衡     linux 主机安装双网卡,共享一个IP地址,对外提供访问,实际 同 ...

  6. 缓冲流的原理和BufferedOutputStream字节缓冲输出流

    缓冲流的原理 BufferedOutputStream字节缓冲输出流 package com.yang.Test.BufferedStudy; import java.io.BufferedOutpu ...

  7. C#如何消除绘制图形缩放时抖动,总结

    一.手动双缓冲 首先定义一个BitmapBitmap backBuffer = new Bitmap(画布宽度, 画布高度);然后获取这个Bitmap的GraphicsGraphics graphic ...

  8. GDI+ 双缓冲实现

    早前曾为此问题在CSDN发帖求助(GDI+ 如何使用双缓冲绘制图像),得到了一个GDI+下较可行的方法,虽然绘制效果比直接绘制要好一些,不过还不能跟GDI的双缓冲方式比肩.   现在,我终于找到了一个 ...

  9. 陈灯WGF双缓冲绘图框架

    “木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...

随机推荐

  1. 风变编程(Python自学笔记)第11关-杀死那只“机”生虫

    1.Debug:为程序排除错误. 2.SyntaxError:语法错误. 3.append()函数是列表的一个方法,要用句点.调用,且append()每次只能接受一个参数. 4.解决思路不清的两个工具 ...

  2. 登陆框select绕过

    0x00 原理   思路来自美团杯2021,本来说出题人已经把select通过正则过滤了,就不该总是往用select进行查询那方面想-> select id from users where u ...

  3. calico NetworkPolicy on kubernetes

    什么是网络策略 在Kubernetes平台中,要实现零信任网络的安全架构,Calico与istio是在Kubernetes集群中构建零信任网络必不可少的组件. 而建立和维护整个集群中的"零信 ...

  4. [bug] Scala eclipse:找不到或无法加载主类

    原因 混合java 和scala 无法编译 解决 右键项目 > properties > scala Compiler >勾选Use Project Setting > Sca ...

  5. Linux 系统运行着许多子系统和应用程序。您可以使用系统日志记录从启动时就收集有关运行中系统的数据。有时

    概述 在本教程中,您将学习以下内容: 配置 syslog 守护程序 了解标准设施.优先级和操作 配置日志轮换 了解 rsyslog 和 syslog-ng 系统内部发生了什么 Linux 系统运行着许 ...

  6. Netperf测试技巧

    Netperf测试技巧   Netperf测试技巧 1.概况 Netperf是一种网络性能的测量工具,主要针对基于TCP或UDP的传输.Netperf根据应用的不同,可以进行不同模式的网络性能测试,即 ...

  7. 记一次 .NET 某电商交易平台Web站 CPU爆高分析

    一:背景 1. 讲故事 已经连续写了几篇关于内存暴涨的真实案例,有点麻木了,这篇换个口味,分享一个 CPU爆高 的案例,前段时间有位朋友在 wx 上找到我,说他的一个老项目经常收到 CPU > ...

  8. java学习之旅

    jar文件其实就是一个压缩包,里面包含很多class文件(一个class文件是一个类的字节码).方便在网络上传输.可以规定版本号,更容易进行版本控制. var只能在方法内使用,不能用于定义成员变量. ...

  9. ubuntu下 SVN 服务器搭建及使用

    简化篇 http://blog.csdn.net/Eric_lmy/article/details/51942931 详细篇 1.安装Subversion ServerSubversion serve ...

  10. PTH的几种食用姿势

    PTH PTH(pass the hash)也叫做hash传递.在内网渗透中是一种很经典的攻击方式,原理就是攻击者可以直接通过NTLM Hash(mimikatz或其他手段抓取到的密码hash)访问远 ...