大家好:
我根据网上大家的说法和例子(在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中图片位置。可能是鼠标移动过程中刷新比较频繁,所以就会闪烁,请问有人遇到类似的问题吗?或者知道怎么解决?
我根据网上大家的说法和例子(在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中图片位置。可能是鼠标移动过程中刷新比较频繁,所以就会闪烁,请问有人遇到类似的问题吗?或者知道怎么解决?
但是,这样引入一个新问题!就是你以前的位置刷新不了!
所以,这样的话,就要求,在移动的时候,必须先要将以前的位置也一起贴出来!
fandh你好:
我的OnEraseBkgnd已经返回true了的。这里的闪烁是我自己在OnDraw函数里用代码用背景色填充背景的,目的是擦掉之前的图片位置。如果我不自己先填充背景色,哪么前次贴的图片不会消失,我再继续贴就很乱了。
还有你后面两句的解决办法没看明白。
{
...
...
...
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是拖动过程中的图片位移,这样就能在拖动过程中动态绘制新的位置。
}
你现在闪烁的原因就是pDC->FillSolidRect()的时候将窗口图像覆盖图片,再贴图片上去,然后MouseMove的时候不断重绘,所以才会产生闪烁的。
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直接在屏幕上乱刷~~
首先,你贴图的话,背景是什么?背景有其他的底图么?还是仅仅填充色就可以了?如果仅仅填充色,可以在内存DC里面计算出以前的位置,把以前的位置填充后,再贴上现在位置的图,然后,以以前的位置与现在的位置的大小将内存的空间贴出来就可以了!
如果有底图,那么必须先要保存一个底图,然后,在这个底图上面重新贴图(这有点象三缓冲),每次内存DC在画图前,先拷贝保存的底图,然后,再重新画图,画完了,再贴出来!
nintendo_dskay你好:
我理解你的意思,但是我就是想实现在拖动的过程中(从鼠标按下到抬起这过程)的图片的动态绘制,内存DC的内容在这过程中是不变的,(内存DC的重绘耗时很多,若重绘拖动就很卡),只是贴内存DC的时候改变位置。所以为了先清除上一次位置的图片,就只好在pDC中调用pDC->FillSolidRect()了。
你的做法我觉得没有解决问题。因为我在拖动过程中重复的动作就是:刷背景色,贴图片到新位置。因为mousemove过程中重绘很快,所以造成了背景色和内存图片之前的快速切换所以闪烁。你的做法每次刷新也是先贴背景图(这里背景图就是纯背景色的屏幕大小图片),再贴内存DC图,还是会有频繁的背景色和内存图片的切换啊。不过我去实际试试。再回来说结果。
lambochan 你好:
理解你的意思了,感觉有点“三缓冲的意思”,应该能解决问题。我去实际使用下再回来讨论。