大家好:
      我根据网上大家的说法和例子(在VC++6.0中),已经把我的绘图过程使用双缓冲绘制了。但是还有有一种情况下的闪烁不能解决,再次求助!
      我的双缓冲机制和网上的代码是一样的,就是刷新的时候先在内存DC上绘图,最后才一次Bitblt到屏幕上。
      但是由于我的绘图过程比较长,所以当我只是用鼠标拖动屏幕图片的时候(我的判断依据时鼠标左键按下了),我并没有重绘图片的内容,而只是重绘图片的位置!!
      pDC->Bitblt(span.x, span.y,bm.bmWidth,bm.bmHeight,&dem,0,0,SRCCOPY);
      其中的span.x, span.y就是拖动过程中的图片的位移,我要实现的就是拖动图片,但是不引起图片内容的绘制(绘制量非常大,等到拖动完成鼠标抬起再绘制)。网上的用法都是贴图时完全覆盖屏幕的,而且每次重绘都会重新绘制内存DC再贴回来。像我现在这样的做法,在拖动过程中每次重绘都要先自己用代码刷一下背景,然后在贴内存DC中的内容在拖动后的位置上,但是这样就会很闪了。
      其实我在拖动过程中就做两件事,一是刷背景色,二是重新贴内存DC中图片位置。可能是鼠标移动过程中刷新比较频繁,所以就会闪烁,请问有人遇到类似的问题吗?或者知道怎么解决?

解决方案 »

  1.   

    就是刷背景色导致的闪,你在OnEraseBkgnd里面直接返回TRUE!这样,就不会闪了!
    但是,这样引入一个新问题!就是你以前的位置刷新不了!
    所以,这样的话,就要求,在移动的时候,必须先要将以前的位置也一起贴出来!
      

  2.   


    fandh你好:
          我的OnEraseBkgnd已经返回true了的。这里的闪烁是我自己在OnDraw函数里用代码用背景色填充背景的,目的是擦掉之前的图片位置。如果我不自己先填充背景色,哪么前次贴的图片不会消失,我再继续贴就很乱了。
    还有你后面两句的解决办法没看明白。
      

  3.   

    我的代码框架说明如下,闪烁就是由于我填充背景造成的,但是又是必须的。请问有什么比较好的解决办法没?既能实现拖动过程中动态绘制图片到新的位置而不重绘内容,又不至于造成闪烁。欢迎大家讨论。OnDraw(CDC * pDC)
    {
      ...
    ...
    ...
      if(!m_bDown) //m_bDown表示鼠标左键按下,表示这是一次拖动过程中的重绘,就不重绘内存DC。
       {
           。
        重绘内存DC的内容
        
       }
       //把整个屏幕填上背景色,否则之前贴的内容不会消失。
       pDC->FillSolidRect()
      //贴回屏幕
      pDC->Bitblt(span.x, span.y,bm.bmWidth,bm.bmHeight,&dem,0,0,SRCCOPY);
        //span.x, span.y是拖动过程中的图片位移,这样就能在拖动过程中动态绘制新的位置。
    }
      

  4.   

    补充一点:我的OnEraseBkgnd已经重载并只返回true了。
      

  5.   

    不要在pDC中调用FillSolidRect(),直接在内存DC里面调用FillSolidRect()就可以了,这样绝对不会闪
      

  6.   

    其实最好还是这样,直接把整个窗口的图像在内存dc里面全都绘制好,然后再BitBlt到窗口dc上,不会有多慢的。
    你现在闪烁的原因就是pDC->FillSolidRect()的时候将窗口图像覆盖图片,再贴图片上去,然后MouseMove的时候不断重绘,所以才会产生闪烁的。
      

  7.   

    用两个位图对象分别保存背景图和前景图(被拖动的图片),鼠标移动时调用InvalidateRect刷新图片移动前和移动后的位置,OnDraw函数中先贴背景、再贴前景。
      

  8.   

    少做了一步...
    Create个客户大小的bg,fill上底色(通常是白色吧,当然其它色随便),所有东西都帖在这个bg上,最后才pDC->bitblt(), like :
    ondraw(cdc *pdc ){
    crect clientrect;
    getclientrect( &clientrect );
    cdc memdc;
    memdc.createcompatibledc(pdc);
    cbitmap bg;
    bg.createcompatibelbitmap(pDC, clientrect.width(),clientrect.height());
    cbitmap *pold = ( cbitmap * )memdc.selectobject( &bg );
    memdc.fillsolidrect()..
    memdc.bitblt(your memdc);
    last:
    pdc->bitblt(0,0,clientrect.width(),clientrect.height(), &memdc, 0, 0, srccopy );
    memdc.selectobject(pold);=============================================================
    也就是说,多一个中转..不要直接用屏幕DC直接在屏幕上乱刷~~
      

  9.   

    回来看看,居然这么多人都说了,我也再说一点吧!希望能帮助你解决问题!
    首先,你贴图的话,背景是什么?背景有其他的底图么?还是仅仅填充色就可以了?如果仅仅填充色,可以在内存DC里面计算出以前的位置,把以前的位置填充后,再贴上现在位置的图,然后,以以前的位置与现在的位置的大小将内存的空间贴出来就可以了!
    如果有底图,那么必须先要保存一个底图,然后,在这个底图上面重新贴图(这有点象三缓冲),每次内存DC在画图前,先拷贝保存的底图,然后,再重新画图,画完了,再贴出来!
      

  10.   


      nintendo_dskay你好:
        我理解你的意思,但是我就是想实现在拖动的过程中(从鼠标按下到抬起这过程)的图片的动态绘制,内存DC的内容在这过程中是不变的,(内存DC的重绘耗时很多,若重绘拖动就很卡),只是贴内存DC的时候改变位置。所以为了先清除上一次位置的图片,就只好在pDC中调用pDC->FillSolidRect()了。
      

  11.   

         cnzdgs你好:
              你的做法我觉得没有解决问题。因为我在拖动过程中重复的动作就是:刷背景色,贴图片到新位置。因为mousemove过程中重绘很快,所以造成了背景色和内存图片之前的快速切换所以闪烁。你的做法每次刷新也是先贴背景图(这里背景图就是纯背景色的屏幕大小图片),再贴内存DC图,还是会有频繁的背景色和内存图片的切换啊。不过我去实际试试。再回来说结果。 
      

  12.   

     
      lambochan 你好:
        理解你的意思了,感觉有点“三缓冲的意思”,应该能解决问题。我去实际使用下再回来讨论。