一个小程序大体是这么个样,移动时闪的很厉害 Graphics  backGraph (dc.GetSafeHdc());//要传给函数的参数的构造方法void DrawBackMap(Graphics* pGraph)
{
 Image* pImage=Image::FromFile(文件名);
 pGraph->DrawImage(pImage,*******);
//这里画很多很多}
怎么改成双缓冲的呢

解决方案 »

  1.   

    网上很多双缓冲的实例的,Google一下就可以了
      

  2.   

    创建一个 Bitmap *m_pCahceBmp = new Bitmap(w,h,PixelFormat32bppARGB );创建一个 Graphics *m_pCacheGS = new Graphics (m_pCahceBmp );然后 DrawBackMap(m_pCacheGS);在
    Graphics backGraph (dc.GetSafeHdc());//要传给函数的参数的构造方法
    backGraph->DrawImage(m_pCahceBmp ,.....);m_pCahceBmp 和 m_pCacheGS  最好作为类成员,但要注意尺寸调整
      

  3.   

    楼主的意思我懂了:
    还是双缓存,双缓存的主要用意,一次性输出用户想看的东西,从而达到不闪的目的。你首先要得到你每次MOVE后的图象的坐标位置,然后你在内存的dc里先画好你每次拖拽后图片的样子,最后用TEXTOUT文字画在DC上,然后stretchblt或者bitblt一次性输出,这样就不闪了,而且每次都能看到固定的文字。
      

  4.   

    首先,底图是不变的,在鼠标移动的过程中,从底图的指定Rect内将图像拷贝至屏幕需要显示的DC上,然后再在DC的某个位置绘制文字。
      

  5.   

    可以在类中创建个 cpaintdc 的public变量么,我创建了个程序就一运行就会死 
      

  6.   

    我右使用如下方式,结果屏幕全是黑的,不知道怎么回事,但是还能拖动,拖动的时候能清楚的
    看到背景色出来的样子void CPicShowDlg::OnPaint() 
    {
      CPaintDC dc(this); 
      CDC memdc;
      memdc.CreateCompatibleDC(&dc);
      CBitmap bmp;
      CRect rc;
      GetClientRect(&rc);  bmp.CreateCompatibleBitmap(&dc, 1000,1000);
      memdc.SelectObject(&bmp);
      
      // 创建GDI+画图对象
      Graphics backGraph(memdc);
      
      // Graphics  backGraph (dc.GetSafeHdc());
      if (NULL!=m_pMainDlg)
      {
        
        m_pMainDlg->DrawBackMap(&backGraph,m_paintDc);
        m_pMainDlg->DrawChild(&backGraph);
        dc.BitBlt(0, 0, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
       
        
      }
      
    }
      

  7.   

     m_pMainDlg->DrawBackMap(&backGraph,m_paintDc);
     m_pMainDlg->DrawChild(&backGraph);
    这两句如果里面有画图的动作,必定闪,你记住,画图动作执行一次才能不闪。所以你要在内存里都画完才到屏幕上画
      

  8.   

    GDI+都用上了,还搞MEMDC干吗..直接用几个Bitmap或者Image不可以吗?
    Bitmap* pImage = new Bitmap(L"ddd.jpg");Graphic* pGraph = Graphic::FromHandle(dc.GetSafeHdc());// dc为ClientDC,非PaintDC
    pGraph->DrawImage(pImage,几个另外的参数);// 目的:将原图像的指定区域的图像绘制到窗口的指定区域中,    Status DrawImage(IN Image* image,
                         IN const Rect& destRect,
                         IN INT srcx,
                         IN INT srcy,
                         IN INT srcwidth,
                         IN INT srcheight,
                         IN Unit srcUnit,
                         IN const ImageAttributes* imageAttributes = NULL,
                         IN DrawImageAbort callback = NULL,
                         IN VOID* callbackData = NULL)
    这个是函数原形之一,你看他的定义应该就明白了。
    你需要做的就是在MouseMove的时候将新的红色部分计算出来,供OnPaint使用
      

  9.   


    HDC hdc = ::CreateCompatibleDC(dc);
    HBITMAP hNewBitmap = ::CreateCompatibleBitmap(dc, rc.right-rc.left, rc.bottom-rc.top);
    HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdc, hNewBitmap);// 在hdc上绘图
    Gdiplus::Graphics graphics(hdc);
      

  10.   

    我重载了OnEraseBkgnd(CDC* pDC),重画时怎么没调用这个 
    只是因为窗口大小造成的重画调用么 另外楼上 JF什么意思啊
      

  11.   

    其实现在每次往图像上画的东西并不多,双缓冲也起不了多大作用,再看看别的原因了。现在是改成了局部刷新,只是擦除以前写文字的地方,但是擦除的过程还会闪现出窗口的背景色,我想用图片坐背景刷新怎么办呢,这样刷新的时候就看不出来了,另外就是onerasebkgnd重载的问题了,没发现被调用。 还有我的程序是动态库,这里面对话框类并没有实际的窗口的,就看调用的主程序的窗口了
      

  12.   

    好了解决了,方法如下:
    1.局部刷新。
    2.重写onerasebkgnd函数
    BOOL OnEraseBkgnd(CDC* pDC)
    {
      //AfxMessageBox("55");
      if (m_bErase)
      {
         return CDialog::OnEraseBkgnd(pDC);
      } 
      else
      {
        return TRUE;
      }
     
    }
    3.初始化m_bErase为true,我的动态库有两个对话框类,其中一个是关于背景图片的,在这个OnPaint
    的末尾 m_bErase重新为false.
    4.因为每次加载的地图的大小不同,在从一副背景图片进入另一幅的时候,m_bErase为false,
    然后再Invalidate();