双缓冲应用 之 窗口绘图防闪烁,基于对话框的绘图

来源:互联网 发布:js年月日转换为. 编辑:程序博客网 时间:2024/05/18 17:25

在使用VC++编写某些绘图程序时,你可能会发现,窗口在每次重绘时都会发生闪烁。特别是在绘制较复杂的图

像时,这种闪烁将会更加剧烈。这里介绍一种防止窗口绘图时闪烁的双缓冲技术。

首先,先解释一下什么叫双缓冲。双缓冲,即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。

通过这个简短的解释,你是否对双缓冲有了初步的理解?不理解没关系,继续往下看。

双缓冲实现过程如下:

 1、在内存中创建与画布一致的缓冲区

 2、在缓冲区画图

 3、将缓冲区位图拷贝到当前画布上

 4、释放内存缓冲区

 

举例:对话框中应用双缓冲绘图

编译环境:

操作系统 Windows XP

编译工具 Visual C++ v6.0

1、新建一个基于对话框的应用程序

在对话框中添加一个picture控件更改ID为IDC_FIGURE,在需要绘图的类的头文件中定义几个双缓冲用到的变量

CRect rect;  // 存储绘图控件的绘图区域

CDC *pDC;  // 控件的屏幕绘图设备指针

CDC memDC;              // 内存绘图设备

CBitmap memBitmap; // 用于内存绘图的位图

CBitmap* pOldBmp; // 备份旧的位图指针 

CWnd* pWnd;             // 绘图控件的指针

//添加一个成员函数:

void DrawFigure(CDC *pDC);

 

2、在对话框的初始化函数OnInitDialog()中添加以下代码

 pWnd = GetDlgItem(IDC_FIGURE); // 获得对话框上的picture控件的窗口句柄       

 pWnd->GetClientRect(&rect);         // 获取绘制区域 

 pDC = pWnd->GetDC();                 // 获得对话框上的picture的设备指针

 pOldBmp = NULL;    // 将旧的位图指针置空 

 // 创建内存绘图设备,使内存位图的DC与控件的DC关联
        memDC.CreateCompatibleDC(pDC);

 memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);  

 pOldBmp = memDC.SelectObject(&memBitmap);

 SetTimer(1,100,NULL);          // 启动定时器

3、DrawFigure函数的定义

void CMyDialog::DrawFigure(CDC *pDC) //CMyDialog,是需要绘图的对话框类

{

 //声明画笔对象,及画笔指针
         CPen pen,*oldpen; 

 //画一个矩形区域
        pDC->Rectangle(&rect);

 pDC->MoveTo(0,0);

 int x,y;

 for(int i =0; i<1000; i++)

 {

  pen.CreatePen(PS_SOLID,1, RGB(rand()%255,rand()%255,rand()%255));

  oldpen = pDC->SelectObject(&pen);

  x = rand()%rect.Width();

  y = rand()%rect.Height();  

  pDC->LineTo(x,y);

  pDC->SelectObject(oldpen);

pen.DeleteObject();

 }

}

 

4、添加Paint事件,在Paint事件处理代码中添加代码

 pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);

 

5、添加Timer事件,在Timer事件处理函数中添加代码

//在位图中画图片

DrawFigure(&memDC);

//使屏幕刷新

OnPaint();

 

6、在Close事件中添加代码,用来删除创建的对象,以释放内存

memDC.SelectObject(pOldBmp);

 memDC.DeleteDC();

 memBitmap.DeleteObject();

至此,对话框中应用双缓冲的简单例子就介绍完毕

 

若在View视图中应用双缓冲,需要将OnEraseBkgnd(CDC* pDC)函数中的返回语句改为

 return TRUE;

从而避免背景不同而形成闪烁


http://hi.baidu.com/dingxia0532/blog/item/33cadec39aca295ef21fe738.html

原创粉丝点击