MFC中雙快取技術
阿新 • • 發佈:2021-02-18
MFC 在進行繪圖的時候,有些情況可能會發生影象閃爍的現象。這時就需要使用二級快取技術對圖形進行處理。
雙快取技術主要是用於處理以下幾種情況:
1)非客戶區和客戶區不能同步更新畫面造成的閃爍,可以去掉視窗的標題和邊框只在WM_PANINT訊息回撥時繪畫,而在WM_NCPAINT訊息回撥中不繪畫。
2)客戶區內背景和前景不能同步更新畫面,在WM_ERASEBKGND背景更新和WM_PAINT前景更新兩個訊息中,只選擇一種訊息回撥函式。
3)Invalidate強制更新客戶區函式,帶入資源的ID編號載入影象false只更新前景而不更新背景,可以減少客戶區閃爍。或者說帶入false只通過WM_PAINT訊息回撥,而不是通知WM_ERASEBKGND訊息回撥
4)即使只在客戶區中輸出畫面,如果畫面輸出的背景圖和角色圖形太多,還會發生背景圖和交圖發生互相覆蓋而閃爍。解決這個問題的方法就是使用雙緩衝防閃爍技術。
雙快取技術的技術原理:
雙快取技術的原理是將一些需要顯示的圖片先繪製在一個記憶體DC中(裝置上下文中)。繪製將所有要顯示的圖片繪製完成之後,然後直接拷貝至螢幕DC統一將其顯示在視窗中。
相當於一個畫家在作畫的過程不展示給別人,當畫作完成之後在統一拿出來讓別人觀看。
雙快取的使用例子:
此例子是使用MFC中的定時器對圖片進行多次重新整理,顯示多張圖片。分別以使用雙緩衝技術和不使用雙緩衝技術。
- 建立需要用到的CBitmap點陣圖物件載入需要顯示的圖片(在.h 檔案中)
CBitmapbitmap;//定義顯示圖片的點陣圖物件
CBitmapmainbitmap;//定義雙緩衝的繪圖點陣圖
CBitmapbit[8];//定義繪圖物件點陣圖陣列,用於載入蝴蝶點陣圖
2.建立在繪圖過程中需要使用的CDC類上下文繪圖裝置(在.h 檔案中)
CDCmainDC;//定義雙緩衝上下文裝置
CDCbackDC;//定義背景圖繪圖裝置
CDCdc[8];//定義蝴蝶突變裝置
3.建立定時器和向點陣圖中載入圖片(在初始化視窗函式中)
bitmap.LoadBitmap(IDB_MAINPICTURE);//載入背景點陣圖 for(inti=0;i<8;i++)//載入蝴蝶點陣圖 { bit[i].LoadBitmap(IDB_1+i); }
SetTimer(1,10,NULL);//設計定時器,沒10ms觸發一次
4.在定時器中顯示需要顯示的圖片
- 不使用雙緩衝技術程式碼
voidC二級快取Dlg::OnTimer(UINT_PTRnIDEvent)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
CClientDCcd(this);//建立客戶區繪圖裝置
staticinti=0;
if(i>7)
{
i=0;
}
//獲取客戶區大小
CRectrect;
GetClientRect(rect);//獲取客戶區大小
//顯示藍色背景
cd.FillSolidRect(0,0,rect.right,rect.Height(),RGB(0,255,0));//將藍色背景直接繪製在螢幕上
//建立背景顯示DC,顯示背景圖片
backDC.CreateCompatibleDC(&cd);//使用零時話圖物件產生與pDC指定裝置相容的裝置上下文記憶體
backDC.SelectObject(bitmap);//將載入的點陣圖物件物件選入裝置上下文中
cd.BitBlt(0,0,600,400,&backDC,0,0,SRCCOPY);//將背景圖直接繪製在螢幕上
//建立蝴蝶顯示DC ,顯示蝴蝶
dc[i].CreateCompatibleDC(&cd);
dc[i].SelectObject(bit[i]);
cd.BitBlt(20,20,300,400,&dc[i],100,20,SRCCOPY);//將蝴蝶直接繪製在螢幕上
//釋放DC
dc[i].DeleteDC();//釋放記憶體DC
backDC.DeleteDC();//釋放記憶體DC
i++;
CDialogEx::OnTimer(nIDEvent);
}
展示效果:
- 使用雙緩衝技術
voidC二級快取Dlg::OnTimer(UINT_PTRnIDEvent)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
CClientDCcd(this);
staticinti=0;
if(i>7)
{
i=0;
}
//獲取客戶區大小
CRectrect;
GetClientRect(rect);
CDCmemDC;//用於緩衝作圖記憶體DC
CBitmapbmp;//記憶體中承載臨時影象的點陣圖mainDC.CreateCompatibleDC(&cd);//依附視窗DC建立相容DC
mainbitmap.CreateCompatibleBitmap(&cd,rect.Width(),rect.Height());//建立相容點陣圖,cd為最後需要繪製到螢幕上當的繪圖裝置,
mainDC.SelectObject(&mainbitmap);//將點陣圖選擇進記憶體DC
//顯示藍色背景
mainDC.FillSolidRect(0,0,rect.right,rect.Height(),RGB(0,255,0));//在緩衝DC上繪製藍色背景
建立背景顯示DC,顯示背景圖片
backDC.CreateCompatibleDC(&mainDC);//使用零時話圖物件產生與pDC指定裝置相容的裝置上下文記憶體
backDC.SelectObject(bitmap);//將載入的點陣圖物件物件選入裝置上下文中
mainDC.BitBlt(0,0,600,400,&backDC,0,0,SRCCOPY);//將背景圖片繪製到緩衝DC上
///建立蝴蝶顯示DC ,顯示蝴蝶
dc[i].CreateCompatibleDC(&cd);
dc[i].SelectObject(bit[i]);
mainDC.BitBlt(100,100,rect.Width(),rect.Height(),&dc[i],0,0,SRCCOPY);//將蝴蝶圖片繪製到緩衝DC中
cd.BitBlt(0,0,rect.Width(),rect.Height(),&mainDC,0,0,SRCCOPY);//最後統一將緩衝DC中的內容繪製到螢幕上。
//釋放DC
backDC.DeleteDC();//釋放記憶體DC
mainDC.DeleteDC();//釋放記憶體DC
dc[i].DeleteDC();//釋放記憶體DC
mainbitmap.DeleteObject();
i++;
CDialogEx::OnTimer(nIDEvent);
}
效果如下: