MFC_雙緩衝技術
雙緩衝簡介
我們看電視時,看到的螢幕稱為OSD層,也就是說,只有在OSD層上顯示影象我們才能看到。現在,我需要建立一個虛擬的、看不見但是可以在上面畫圖(比如說畫點、線)的OSD層,我稱之為offscreen(後臺緩衝區)。這個offscreen存在於記憶體中,我們在上面畫圖,這個offscreen上面的東西可以顯示在OSD層上,需要一個建立這個offscreen的函式,返回這個offscreen的控制代碼(整型指標)、寬度、高度、指向新建offscreen資料緩衝區的指標,該緩衝區是一個在函式外建立的offscreen的資料緩衝區,大小是offscreen的高度寬度每個畫素點資料的大小。閃爍是圖形程式設計的一個常見問題。需要多重複雜繪製操作的圖形操作會導致呈現的影象閃爍或具有其他不可接受的外觀。雙緩衝的使用解決這些問題。雙緩衝使用記憶體緩衝區來解決由多重繪製操作造成的閃爍問題。當啟用雙緩衝時,所有繪製操作首先呈現到記憶體緩衝區,而不是螢幕上的繪圖圖面。所有繪製操作完成後,記憶體緩衝區直接複製到與其關聯的繪圖圖面。因為在螢幕上只執行一個圖形操作,所以消除了由複雜繪製操作造成的影象閃爍。
以上摘自百度百科
在ondraw函式中直接進行繪製會出現螢幕的閃爍現象,原因是在繪製之前有一個擦除原影象然後填充背景色的過程,如果背景色與新影象顏色相差過大,就會出現閃爍現象,解決這個問題的辦法就是利用雙緩衝。
MFC中雙緩衝的實現
我通常是將雙緩衝部分封裝成一個函式,在函式中繪製,然後在ondraw中呼叫這個函式即可
1、在CView類中新增WM_ERASEBKGND訊息的訊息響應函式,直接令其返回true
BOOL CXXXView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
return true ;
}
2、在CView類的標頭檔案中新增兩個變數並宣告雙緩衝函式
CDC bufferdc;//用於雙緩衝的DC
CBitmap bufferbmp;//承載臨時物件的點陣圖
void BufferDraw(CDC* pdc);
3、在CView的原始檔中實現雙緩衝函式
void CXXXView::BufferDraw(CDC* pDC)
{
BITMAP bmp;//儲存點陣圖資訊的結構體
CRect rect;
GetClientRect(rect);//獲取客戶區域的矩形
bufferdc.CreateCompatibleDC(NULL );//建立相容DC
bufferbmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());//建立相容點陣圖
bufferdc.SelectObject(&bufferbmp);//將點陣圖選入記憶體區域
CBitmap *pOldBit = bufferdc.SelectObject(&bufferbmp);
bufferbmp.GetBitmap(&bmp);//獲取記憶體點陣圖的資訊
//在此處新增繪製程式碼
SetStretchBltMode(pDC->m_hDC, STRETCH_HALFTONE);
pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &bufferdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);//將記憶體中的內容複製到裝置
bufferdc.DeleteDC(); //刪除DC
bufferbmp.DeleteObject(); //刪除點陣圖
}
4、在Ondraw中呼叫雙緩衝函式
void CXXXView::OnDraw(CDC* pDC)
{
CMikuDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
BufferDraw(pDC);
}