zoukankan      html  css  js  c++  java
  • VC双缓冲实现

       续前面的聚类算法实验,想要达到可视化的实时更新,并且对聚类的图形进行染色,这里单独开辟一个线程刷新界面,这里为设定一个100ms的计时器不停的invalidate(),然后刷新,这时候发现屏幕上的图形一闪一闪的,或者一行一行的刷新,这样效果不是很理想,这时想到了java里双缓冲的一种实现方法,java中调用repaint()的时候中间会先进行update(),然后在进行paint(),这里MFC调用invalidate()的时候会先调用OnEraseBkgnd(CDC* pDC)函数进行背景填充,然后调用OnDraw(CDC* pDC)函数进行重新绘制。闪烁现象就是因为擦除、重绘这两种的颜色反差导致的,所以这里要取消这种反差。

        实现方法就是不进行擦除,每次重绘的时候在内存中绘制出一张和客户区同样大小的图片,背景颜色及为客户区的颜色,其他元素是你绘制上去的,绘制好这么一张图片之后直接利用CDC的BitBlt方法将内存位图绘制在客户区,这样就消除了闪烁,也及实现了双缓冲,聚类算法实验中实现代码如下:

       

    void CDataMiningExample1View::OnDraw(CDC* pDC)
    {
    	CDataMiningExample1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    
    	// TODO: 在此处为本机数据添加绘制代码
    	/*
    	int i,length=m_cCluster.m_dataPoints.size(),k=kMeans.size();
    	//绘制每个点
    	for (i=0;i<length;i++)
    	{
    		if (m_bEmplify)
    		{
    			m_cCluster.m_dataPoints[i]->drawSelf(pDC);
    		}
    		else
    		{
    			m_cCluster.m_dataPoints[i]->drawNormalSelf(pDC);
    		}
    	}
    	for (i=0;i<k;i++)
    	{
    		kMeans[i]->drawSelf(pDC);
    	}
    	*/
    	CRect rect;
    	GetClientRect(&rect);  //获取客户区的大小
    	CDC dcmem;              //创建一个内存DC
    	CBitmap bmp;            //创建一个内存位图
    	dcmem.CreateCompatibleDC(pDC); //创建一个内存DC
    	bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height()); //创建一个内存位图
    	dcmem.SelectObject(&bmp); //关联内存DC和内存位图
    	dcmem.FillSolidRect(rect,pDC->GetBkColor());//这个相当于擦除的步骤,背景保持背景颜色
    
    	
    	int i,length=m_cCluster.m_dataPoints.size(),k=kMeans.size();
    	//绘制每个点
    	for (i=0;i<length;i++)
    	{
    		if (m_bEmplify)
    		{
    			m_cCluster.m_dataPoints[i]->drawSelf(&dcmem);
    		}
    		else
    		{
    			m_cCluster.m_dataPoints[i]->drawNormalSelf(&dcmem);
    		}
    	}
    	for (i=0;i<k;i++)
    	{
    		kMeans[i]->drawSelf(&dcmem);
    	}
    	//以上是绘制部分
    	pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcmem,0,0,SRCCOPY);//内存位图显示出来
    	dcmem.DeleteDC();
    	bmp.DeleteObject();//清理工作
    }
    

      

    BOOL CDataMiningExample1View::OnEraseBkgnd(CDC* pDC)
    {
    	// TODO: 在此添加消息处理程序代码和/或调用默认值
    
    	//return CScrollView::OnEraseBkgnd(pDC);
    	return TRUE;
    }
    

      

      以上就是双缓冲的基本实现,其他可以参照。

       

  • 相关阅读:
    天真的误会
    Unity3D笔记
    http纪要
    JQuery中ajax错误处理之页面跳转
    php代码片段
    3D游戏相关笔记
    Javascript笔记
    PHP对观察者模式的支持
    为什么要使用多线程
    死锁和活锁
  • 原文地址:https://www.cnblogs.com/weixliu/p/2827207.html
Copyright © 2011-2022 走看看