“閃爍”的原因是擦除背景(用背景色重新填充)與繪制前景圖像之間有時(shí)間差,而且背景和前景顏色有差異,導(dǎo)致眼睛看上去好像在閃爍。
“閃爍”并不主要是因?yàn)镚DI或GDI+效率低造成的。
解決這個(gè)問(wèn)題需從兩個(gè)方面入手:1.縮短(或消除)前后景繪圖時(shí)間差,2.減少繪制次數(shù)
1.縮短(或消除)前后景繪圖時(shí)間差
OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
實(shí)際上背景填充是必須,否則前景圖像與殘留的背景混在一起非常雜亂,
這里取消的步驟,其實(shí)移到繪圖過(guò)程了(見(jiàn)2.),合成一張完整圖像。
2.減少繪制次數(shù)
采用“雙緩沖”技術(shù),先在內(nèi)存緩沖區(qū)中完成繪圖,再貼到屏幕上
另外如果緩沖圖像內(nèi)容不是變化的,應(yīng)存為成員對(duì)象之類,不要每次去畫(huà)
一般在OnDraw(CDC* pDC)中完成
///////////////////////////--GDI --////////////////////////////////////
int nWidth=1000;
int nHeight=1000;
CDC MemDC; //首先定義一個(gè)顯示設(shè)備對(duì)象
CBitmap MemBitmap;//定義一個(gè)位圖對(duì)象
//隨后建立與屏幕顯示兼容的內(nèi)存顯示設(shè)備
MemDC.CreateCompatibleDC(pDC); //這時(shí)還不能繪圖,因?yàn)闆](méi)有地方畫(huà) ^_^
//下面建立一個(gè)與屏幕顯示兼容的位圖,至于位圖的大小嘛,可以用窗口的大小
//,也可以自己定義(如:有滾動(dòng)條時(shí)就要大于當(dāng)前窗口的大小,在BitBlt時(shí)決定拷貝內(nèi)存的哪部分到屏幕上)
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//將位圖選入到內(nèi)存顯示設(shè)備中
//只有選入了位圖的內(nèi)存顯示設(shè)備才有地方繪圖,畫(huà)到指定的位圖上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色將位圖清除干凈,這里用原背景色作為背景
//你也可以用自己應(yīng)該用的顏色
MemDC.FillSolidRect(0,0,nWidth,nHeight,pDC->GetBkColor());
//繪圖
CBrush brush(RGB(0,255,0));
for(int i=0;i<50;i++)
{
for(int j=0;j<80;j++)
{
//MemDC.Rectangle(10*j,10*i,9,9);
CRect rc(10*j,10*i,10*j+8,10*i+8);
MemDC.FillRect(&rc,&brush);
}
}
//將內(nèi)存中的圖拷貝到屏幕上進(jìn)行顯示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//繪圖完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();
///////////////////////////--GDI+ --////////////////////////////////////
Bitmap* buf=new Bitmap(2000,2000) ;
Graphics gc(buf);//Graphics.FromImage(buf);
//反鋸齒
//gc.SetSmoothingMode(SmoothingModeAntiAlias);
SolidBrush bgbrush(Color(255,255,255,255));
gc.FillRectangle(&bgbrush,0,0,2000,2000);//背景填充
Pen pen(Color(255, 0, 0, 255));
SolidBrush sbrush(Color(255,0,255,255));
for(int i=0;i<60;i++)
{
for(int j=0;j<60;j++)
gc.FillRectangle(&sbrush,10*j,10*i,9,9);
}
Graphics G(pDC->GetSafeHdc());
G.DrawImage(buf ,0,0);