我在作业画图程序,画图形时不断重绘画面会闪烁,我想用双缓冲解决问题。网上查了一下是这样说的:
////////////////////////////////////////////////////////////////////////////////
在OnDraw(CDC *pDC)中: CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);
//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //绘图
MemDC.MoveTo(……);
MemDC.LineTo(……); //将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); //绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC(); //////////////////////////////////////////////////////////////////////////
我的ondraw函数中原本是:
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
    
pDoc->DrawShapes(pDC);    }其中DrawShapes(pDC)函数是画一遍每一个图形
void CMyDoc::DrawShapes(CDC *pDC)
{
  int size=m_shapes.GetSize();
  int i;
  for(i=0;i<size;i++)
  {
  CBaseGraph* p=m_shapes[i];
  p->Draw(pDC);
  if(p->IfSelectBefore)
  {
  p->HotPoints(pDC);
  }
  }
}
请高手帮帮我,应该怎么改双缓冲啊,虽然网上有模板,可我还是不会
MemDC.MoveTo(……);
MemDC.LineTo(……); 
在我的程序里要怎么改啊

解决方案 »

  1.   

    所谓的双缓冲其实很简单,就是先将图画在一个内存DC中,等画好了之后,再一次性的用BitBlt贴到实际的窗口DC中去。
    就你的程序其实很好改。你的绘图程序是void CMyDoc::DrawShapes(CDC *pDC);所以你在OnDraw中可以写成这样:
    void CMyView::OnDraw(CDC* pDC)
    {
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    CDC MemDC; //首先定义一个显示设备对象
    CBitmap MemBitmap;//定义一个位图对象  //随后建立与屏幕显示兼容的内存显示设备
    MemDC.CreateCompatibleDC(NULL);
    //这时还不能绘图,因为没有地方画 ^_^
    //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
    MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);  //将位图选入到内存显示设备中
    //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
    CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);  //先用背景色将位图清除干净,这里我用的是白色作为背景
    //你也可以用自己应该用的颜色
    MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));  
    //以上这些就是上面的建立内存DC的部分,是照抄你上面代码的。    pDoc->DrawShapes(&MemDC);//将图形画在内存DC上。pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);  //将内存DC中的内容贴到实际DC中    }
      

  2.   

    哦?我估计LZ没有重载OnEraseBkgnd.要return TRUE;我说的这种情况是对话框的.单文档和多文档我不熟悉.
      

  3.   

    一样的
    都是处理OnEraseBkgnd
      

  4.   

    参考这个帖子
    http://topic.csdn.net/u/20100929/09/115604fb-f8cb-43c9-93ff-da8af5dcab57.html
      

  5.   

    双缓冲的原理我上面说过了,它只是先将图画在一个内存DC上,然后再画到实际DC中去,它并不能解决所有的闪烁问题,如果你的作图工作有很多,那么双缓冲是可以,因为将图画在内存DC上这个过程并不显示,最后一次性贴到实际DC中去,避免闪烁。但是如果你的程序是短时间内要不停地更新,那么双缓冲也无能为力啊!
    另外如果你没有处理OnEraseBkgnd的话,应该处理一下OnEraseBkgnd,在里面返回TRUE,这样更新时就不会重画背景,效果应该会好一点。