MFC VC 双缓冲绘图基本原理与实现,详细解释
MFC做了一些時(shí)間了,不得不面對(duì) 的是在界面上畫(huà)圖的。
當(dāng)然你可以直接搜索到能用的代碼,并且基本能滿(mǎn)足要求。不過(guò)這樣總不是學(xué)習(xí)的態(tài)度。本著學(xué)習(xí)分享的態(tài)度,現(xiàn)做一些基本的分析吧。
在MSDN上知道,我們畫(huà)圖的對(duì)象都是窗口的DC,WINDOWS的繪圖更新時(shí),總是用背景色先填充這個(gè)區(qū)域,然后才是我們的繪圖代碼,
這就是說(shuō),如果我們繪圖的代碼與背景色差別較大,不管我們更新速度多快,總會(huì)有種閃爍的感覺(jué)。
要想避免,通常的做法都是雙緩沖了,
具體代碼上來(lái)了。
void CXX:DrawPic(CDC* pDC/*目標(biāo)DC指針*/)
{//這里面的CRect rect是你要畫(huà)圖的窗口的大小
????? CDC memDC;//
????? memDC.CreateCompatibleDC(pDC);//創(chuàng)建與目標(biāo)DC相兼容的內(nèi)存DC,
????? memBitmap.CreateCompatibleBitmap(pDC,rect.Width(), rect.Height());//根據(jù)目標(biāo)DC創(chuàng)建位圖,為什么?看后面
??????memDC.SelectObject(&memBitmap);//把位圖選入內(nèi)存DC
???? CBrush brush;
?? ? brush.CreateSolidBrush(RGB(255,0,0));//建立個(gè)紅色的畫(huà)刷給內(nèi)存DC
? ?? memDC.SelectObject(&brush)///選擇這個(gè)刷子
??? ?memDC.Rectangle(0, 0, 100, 100)//一個(gè)正方形
?? //將這個(gè)DC的全部?jī)?nèi)容放入pDC,這樣屏幕上才會(huì)有圖像
??? pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),&memDC, 0, 0,SRCCOPY);
???? //結(jié)束了 畫(huà)圖不要忘記釋放資源,DC是有限的
???? memBitmap.DeleteObject();
?? ? memDC.DeleteDC();
}
?
現(xiàn)在,我來(lái)說(shuō)說(shuō):
1.內(nèi)存DC;MSDN上說(shuō),內(nèi)存DC只存在于內(nèi)存中,當(dāng)我們使用memDC.CreateCompatibleDC(pDC)建立它的時(shí)候,它只是一個(gè)單色的長(zhǎng)寬各1像素(one monochrome pixel wide and one monochrome pixel high.)的一個(gè)顯示面。
2.上面我建立 了個(gè)位圖,為什么?同樣,MS說(shuō),一個(gè)DC建立后是不能繪圖的,你必須給它選擇一 個(gè)與它高寬對(duì)應(yīng)的位圖。于是上面 你可以看到,我用了
memBitmap.CreateCompatibleBitmap(pDC,rect.Width(), rect.Height());//這個(gè)位圖是與pDC色彩是一樣的,多色
?memDC.SelectObject(&memBitmap);//把位圖選入內(nèi)存DC,
做到上上面 的要求。并且還達(dá)到另一個(gè)目的,就是讓內(nèi)存DC成為多色的DC,慢慢體會(huì)吧
3.為了繪圖,你還要先個(gè)畫(huà)刷,用來(lái)填充繪圖區(qū)域,于是我用了
? CBrush brush;
?? ? brush.CreateSolidBrush(RGB(255,0,0));//建立個(gè)紅色的畫(huà)刷給內(nèi)存DC
? ?? memDC.SelectObject(&brush)///選擇這個(gè)刷子
這3句。然后使用memDC.Rectangle(0, 0, 100, 100)//一個(gè)正方形,畫(huà)了個(gè)紅色的正方形
?
4.使用pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),&memDC, 0, 0,SRCCOPY);
讓屏幕上有圖像顯示,
5.最后使用:
memBitmap.DeleteObject();
?? ? memDC.DeleteDC();
釋放GDI資源。
這里應(yīng)該說(shuō)的是十分清楚的了,如果你沒(méi)有成功,請(qǐng)聯(lián)系我。如果發(fā)現(xiàn)錯(cuò)誤,也歡迎指正。
另外,也可參照下面的一篇代碼:
| BOOL?CDataStructureView::OnEraseBkgnd(CDC* pDC) { ?????CRect rc; ?????CDC dcMem; ?????GetClientRect(&rc); ?????CBitmap bmp; //內(nèi)存中承載臨時(shí)圖象的位圖 ?????dcMem.CreateCompatibleDC(pDC);//依附窗口DC創(chuàng)建兼容內(nèi)存DC ?????//創(chuàng)建兼容位圖(必須用pDC創(chuàng)建,否則畫(huà)出的圖形變成黑色) ?????bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height()); ?????CBitmap *pOldBit=dcMem.SelectObject(&bmp); ?????//按原來(lái)背景填充客戶(hù)區(qū),不然會(huì)是黑色 ?????dcMen.FillSolidRect(rc,RGB(255,255,255)) ?????//畫(huà)圖,添加你要畫(huà)圖的代碼,不過(guò)用dcMem畫(huà),而不是pDC; ?????...... ?????pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dcMem,0,0,SRCCOPY); ?????//將內(nèi)存DC上的圖象拷貝到前臺(tái) ?????//繪圖完成后的清理 ?????dcMem.DeleteDC();????//刪除DC ?????bmp.DeleteObject();//刪除位圖 ?????return?true; ?????//這里一定要用return true,如果用自動(dòng)生成的,會(huì)調(diào)用基類(lèi),把畫(huà)出來(lái)的覆蓋,就什???? 么結(jié)果也沒(méi)有了 |
| } |
總結(jié)
以上是生活随笔為你收集整理的MFC VC 双缓冲绘图基本原理与实现,详细解释的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 怎么利用ffmpeg和AviSynth给
- 下一篇: CCD类详解