昄囑Ş如何避免闪烁Q如何提高显C效率是问得比较多的问题。而且多数为MFC的绘囑և数效率很低,L惛_求其它的解决Ҏ?br />MFC的绘图效率的不高但也不差,而且它的l图函数使用非常单,只要使用Ҏ得当Q再加上一些技巧,用MFC可以得到效率很高的绘囄序?br />我想我长期Q呵呵当然也只有2q多Q用MFCl图的经验谈谈我的一些观炏V?br />
1、显C的囑ŞZ么会闪烁Q?br /> 我们的绘图过E大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏q显C时是由OnPaintq行调用的。当H口׃M原因需要重l时QL先用背景色将昄区清除,然后才调用OnPaintQ而背景色往往与绘囑ֆ容反差很大,q样在短旉内背景色与显C图形的交替出现Q得显C窗口看h在闪。如果将背景刯|成NULLQ这h论怎样重绘囑Ş都不会闪了。当Ӟq样做会使得H口的显CZؕ成一团,因ؓ重绘时没有背景色对原来绘制的囑Şq行清除Q而又叠加上了新的囑Ş。有的h会说Q闪烁是因ؓl图的速度太慢或者显C的囑Ş太复杂造成的,其实q样说ƈ不对Q绘囄昄速度寚w烁的影响不是Ҏ性的。例如在OnDraw(CDC *pDC)中这样写Q?br />pDC->MoveTo(0,0);
pDC->LineTo(100,100);
q个l图q程应该是非常简单、非常快了吧Q但是拉动窗口变化时q是会看见闪烁。其实从道理上讲Q画囄q程复杂越慢闪烁应该越,因ؓl图用的旉与用背景清除屏幕所q旉的比例越大h寚w烁的感觉会越不明显。比如:清楚屏幕旉?sl图旉也是?sQ这样在10s内的q箋重画中就要闪?ơ;如果清楚屏幕旉?s不变Q而绘图时间ؓ9sQ这?0s内的q箋重画只会闪烁一ơ。这个也可以试验Q在OnDraw(CDC *pDC)中这样写Q?br />for(int i=0;i<100000;i++)
{
pDC->MoveTo(0,i);
pDC->LineTo(1000,i);
}
呵呵Q程序有点变态,但是能说明问题?br /> 说到q里可能又有说了Qؓ什么一个简单图形看h没有复杂囑Ş那么闪呢Q这是因为复杂图形占的面U大Q重L造成的反差比较大Q所以感觉上要闪得厉害一些,但是闪烁频率要低。那Z么动ȝ重画频率高,而看h却不闪?q里Q我p再次了,闪烁是什么?闪烁是反差Q反差越大,闪烁厉実뀂因为动ȝq箋两个帧之间的差异很小所以看h不闪。如果不信,可以在动ȝ每一帧中间加一张纯白的帧,不闪才怪呢?br />
2、如何避免闪?br /> 在知道图形显C闪烁的原因之后Q对症下药就好办了。首先当然是LMFC提供的背景绘制过E了。实现的Ҏ很多Q?br />* 可以在窗口Ş成时l窗口的注册cȝ背景刷付NULL
* 也可以在形成以后修改背景
static CBrush brush(RGB(255,0,0));
SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);
* 要简单也可以重蝲OnEraseBkgnd(CDC* pDC)直接q回TRUE
q样背景没有了,l果囑Ş昄的确不闪了,但是昄也象前面所说的一P变得一团ؕ。怎么办?q就要用到双~存的方法了。双~冲是除了在屏q上有图形进行显CZ外,在内存中也有囑Ş在绘制。我们可以把要显C的囑Ş先在内存中绘制好Q然后再一ơ性的内存中的图形按照一个点一个点地覆盖到屏幕上去Q这个过E非常快Q因为是非常规整的内存拷贝)。这样在内存中绘图时Q随便用什么反差大的背景色q行清除都不会闪Q因为看不见。当贴到屏幕上时Q因为内存中最l的囑Ş与屏q显C图形差别很(如果没有q动Q当然就没有差别Q,q样看v来就不会闪?br />
3、如何实现双~冲
首先l出实现的程序,然后再解释,同样是在OnDraw(CDC *pDC)中:
CDC MemDC; //首先定义一个显C备对?br />CBitmap MemBitmap;//定义一个位囑֯?br />
//随后建立与屏q显C兼容的内存昄讑֤
MemDC.CreateCompatibleDC(NULL);
//q时q不能绘图,因ؓ没有地方?^_^
//下面建立一个与屏幕昄兼容的位图,至于位图的大嘛Q可以用H口的大?br />MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//位N入到内存显C备中
//只有选入了位囄内存昄讑֤才有地方l图Q画到指定的位图?br />CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除q净Q这里我用的是白色作?br />//你也可以用自己应该用的颜?br />MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
//l图
MemDC.MoveTo(…?;
MemDC.LineTo(…?;
//内存中的图拯到屏q上q行昄
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//l图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();
上面的注释应该很详尽了,废话׃多说了?br />