MFC基礎知識(四)——雙緩衝解決刷屏時閃爍
阿新 • • 發佈:2019-01-04
本文主要介紹:在利用MFC畫圖或影象顯示時,有時候需要呼叫OnDraw()函式重新整理螢幕,而螢幕往往會發生閃爍,本文主要介紹利用雙緩衝解決閃屏問題。
關於閃屏方面的介紹分析見博文:
http://blog.csdn.net/longzaitianya1989/article/details/18266899
博文中關於雙緩衝實現部分不夠詳盡,實現過程中可能會出現問題,下面再介紹一下:
1.過載OnEraseBkgnd()函式,OnEraseBkgnd對應訊息WM_ERASEBKGND,修改其程式:
必須過載該函式並修改,不然仍會閃屏。BOOL C***View::OnEraseBkgnd(CDC* pDC) { // TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值 return TRUE; return CScrollView::OnEraseBkgnd(pDC); }
2.修改OnDraw()函式:
注:CRect ClientRect; GetClientRect(&ClientRect); //獲取客戶區大小 int nWidth = (nImgWidth*m_fExpand> ClientRect.Width()) ? int(nImgWidth*m_fExpand) : ClientRect.Width(); //此處:寬高取螢幕與滾動條長度的最大值,不然放大縮小時,不能完全刷去上一次的圖, //會有殘餘,nImgWidth nImgHeight 影象的寬與高 m_fExpand對影象放大縮小比例,不縮放則為1 int nHeight = (nImgHeight*m_fExpand> ClientRect.Height()) ? int(nImgHeight*m_fExpand) : ClientRect.Height(); CDC memDC; //定義一個顯示裝置物件 CBitmap bmp;//定義一個位圖物件 memDC.CreateCompatibleDC(pDC); //建立與螢幕顯示相容的記憶體顯示裝置 //建立一個與螢幕顯示相容的點陣圖 bmp.CreateCompatibleBitmap(pDC, nWidth,nHeight); memDC.SelectObject(&bmp); //將點陣圖選入到記憶體顯示裝置中 //先用背景色將點陣圖清除乾淨,這裡我用的是白色作為背景 memDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); ////////////////////////下面新增繪圖或影象顯示程式/////////////////////////// //通過點陣圖顯示影象 ::SetStretchBltMode(memDC.m_hDC,STRETCH_HALFTONE); //設定拉伸方式,避免縮小時失真 ::StretchDIBits(memDC.m_hDC, 0, 0, int(nImgWidth * m_fExpand), int(nImgHeight * m_fExpand),0, 0, nImgWidth, nImgHeight, pDoc->m_pImageData, pDoc->m_pBmInfo, DIB_RGB_COLORS, SRCCOPY) ; //繪圖 if(m_AoiShapeList.m_AoiList.GetSize()) m_AoiShapeList.Draw(&memDC,m_fExpand); /////////////////////////////////////////////////////////////////////////////// /將記憶體中的圖拷貝到螢幕上進行顯示 pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY); //繪圖完成後的清理 bmp.DeleteObject(); memDC.DeleteDC();
1.上面兩行“///////”線之間的畫圖與顯示中用到的CDC物件,要是memDC不能是pDC;
2.memDC進行繪圖,繪圖函式引數要為邏輯座標,邏輯座標和裝置座標區別見:
http://blog.csdn.net/hong__fang/article/details/44134195
3.上面的nWidth和nHeight不能隨便設,因為你設定的大小就是重新整理區域的大小,當進行影象放大與縮小時,應該重新整理的是整個影象放大縮小後的區域大小,不然會有殘留。