基于WTL 双缓冲(double buffer)绘图的分析详解

 更新时间:2013年05月17日 16:16:56   作者:  
本篇文章是对WTL下使用双缓冲(double buffer)绘图进行了详细的分析介绍,需要的朋友参考下
WTL中有两个Mix-in类: CDoubleBufferImplCDoubleBufferWindowImpl,用于创建双缓冲绘图窗口,用法非常简单。
下面创建了一个普通的WTL窗口类,在窗口的客户区中有大量的绘图工作,使用CDoubleBufferImpl类来消除绘图时的闪烁现象:
复制代码 代码如下:

const COLORREF WHITE_COLOR = RGB(255,255,255);
const COLORREF BLUE_COLOR = RGB(0,0,255);
class CMainWindow :
 public CWindowImpl<CMainWindow,CWindow,CSimpleWinTraits>,
 public CDoubleBufferImpl<CMainWindow>
{
public:
 typedef CMainWindow _thisClass;
 typedef CDoubleBufferImpl<_thisClass> _baseDblBufImpl;
 BEGIN_MSG_MAP(CMainWindow)
  MSG_WM_CREATE(OnCreate)
  MSG_WM_DESTROY(OnDestroy)
  CHAIN_MSG_MAP(_baseDblBufImpl)
 END_MSG_MAP()
 int OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
  m_RectPen.CreatePen(PS_SOLID,1,BLUE_COLOR);
  return 0;
 }
 void OnDestroy()
 {
  PostQuitMessage(0);
 }

 void OnPaint(CDCHandle)
 {
  CPaintDC dc(m_hWnd);
  DoPaint(dc.m_hDC);
 }
 void DoPaint(CDCHandle dc)
 {
  CRect rc;
  GetClientRect(&rc);
  dc.FillRect(&rc,WHITE_COLOR);
  HPEN hOldPen = dc.SelectPen(m_RectPen);
  const int width = 5;
  int x = 0;
  int count = rc.Width()/width;
  int height = 0;
  for (int i=0; i<count; i++)
  {
   height = (int)((double)rand()*rc.Height())/RAND_MAX;
   dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
   x += width;
  }
  dc.SelectPen(hOldPen);
 }
 /*
 void DoPaint(CDCHandle dc)
 {
  CRect rc;
  GetClientRect(&rc);
  int width = rc.Width(), height = rc.Height();
  //use GDI+ to draw in the client area
  Graphics g(dc.m_hDC);
  SolidBrush whiteBrush(Color(255,255,255));
  g.FillRectangle(&whiteBrush,0,0,width,height);
  Pen bluePen(Color(0,0,255));
  const int dx = 5;
  int count = width/dx;
  int x = 0, y = 0, h = 0;
  for (int i=0;i<count;i++)
  {
   h = ((double)rand()*height)/RAND_MAX;
   g.DrawRectangle(&bluePen,x,y,dx,h);
   x += dx;
  }
 }
 */
private:
 CPen m_RectPen;
};

值得一提的是,Windows Vista操作系统增加了对Double buffered paint的内建支持,这里有一篇文章介绍如何在Win32程序中使用这些API:
Using Windows Vista Built-In Double Buffering
在WTL中使用Vista提供的这一功能非常容易,最新的WTL库中提供了CBufferedPaintImpl和CBufferedPaintWindowImpl两个类,这两个类的用法和前面提到的两个WTL自带的双缓冲类几乎一样。区别仅仅是所重载的DoPaint()函数的参数稍有不同。
对于CBufferedPaintImpl类,所需重载的DoPaint()函数的样子如下所示:
复制代码 代码如下:

void DoPaint(CDCHandle dc, RECT& rect)
{
 CRect rc(rect);
 dc.FillSolidRect(&rc,WHITE_COLOR);
 HPEN hOldPen = dc.SelectPen(m_RectPen);
 const int width = 5;
 int x = 0;
 int count = rc.Width()/width;
 int height = 0;
 for (int i=0; i<count; i++)
 {
  height = (int)((double)rand()*rc.Height())/RAND_MAX;
  dc.Rectangle(x,rc.Height(),x+width,rc.Height()-height);
  x += width;
 }
 dc.SelectPen(hOldPen);
}

相关文章

  • QT实现简单TCP通信

    QT实现简单TCP通信

    这篇文章主要为大家详细介绍了QT实现简单的TCP通信,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • 解析linux 文件和目录操作的相关函数

    解析linux 文件和目录操作的相关函数

    以下是对linux中文件和目录操作的相关函数进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • C语言实现静态存储通讯录的示例代码

    C语言实现静态存储通讯录的示例代码

    这篇文章主要为大家详细介绍了如何利用C语言实现一个静态存储的通讯录,文中的示例代码讲解详细,对我们学习C语言有一定帮助,需要的可以参考一下
    2022-09-09
  • C++ 二进制文件读写方式及示例详解

    C++ 二进制文件读写方式及示例详解

    这篇文章主要为大家介绍了C++ 二进制文件读写实现方式及示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • C++实现二叉树非递归遍历方法实例总结

    C++实现二叉树非递归遍历方法实例总结

    这篇文章主要介绍了C++实现二叉树非递归遍历方法实例总结,是算法设计中比较经典的一个遍历算法,需要的朋友可以参考下
    2014-08-08
  • C语言由浅入深讲解文件的操作下篇

    C语言由浅入深讲解文件的操作下篇

    C语言具有操作文件的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。与其他编程语言相比,C语言文件操作的接口相当简单和易学
    2022-04-04
  • 如何在C++中调用python代码你知道吗

    如何在C++中调用python代码你知道吗

    这篇文章主要为大家介绍了C++中调用python代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++中String增删查改模拟实现方法举例

    C++中String增删查改模拟实现方法举例

    这篇文章主要给大家介绍了关于C++中String增删查改模拟实现方法的相关资料,String是C++中的重要类型,程序员在C++面试中经常会遇到关于String的细节问题,甚至要求当场实现这个类,需要的朋友可以参考下
    2023-11-11
  • 深入探究C语言中的二叉树

    深入探究C语言中的二叉树

    树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。本文将带你深入探究C语言中的二叉树,感兴趣的同学跟着小编一起学习吧
    2023-05-05
  • C语言函数栈帧的创建与销毁详解

    C语言函数栈帧的创建与销毁详解

    函数栈帧(stack frame)就是函数调用过程中在程序的调用栈(call stack)所开辟的空间,下面这篇文章主要给大家介绍了关于C语言函数栈帧的创建与销毁的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09

最新评论