1. 程式人生 > >MFC基礎知識(四)——雙緩衝解決刷屏時閃爍

MFC基礎知識(四)——雙緩衝解決刷屏時閃爍

本文主要介紹:在利用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不能隨便設,因為你設定的大小就是重新整理區域的大小,當進行影象放大與縮小時,應該重新整理的是整個影象放大縮小後的區域大小,不然會有殘留。