Bootstrap

MFC 双缓冲绘图

描述:
       当我们用GDI绘图技术去自绘界面时,如果界面的刷新频率较高,界面就会出现闪烁情况,这是因为刷新界面的速度大于绘制界面的速度,界面还没绘制完就要刷新界面,界面就会出现图像不连续。而使用双缓冲绘图方法就可以解决这种问题,当我们绘制图像时在缓存CDC上绘图,绘制完成时用CDC::BitBlt()函数将缓存CDC上的图像拷贝到界面CDC上,这样就不会出现界面不连续(闪烁)情况。

void UICustom::OnDraw(CDC* pDc)
{
	if (m_bDoubleBuffer)//是否采用双缓冲绘图
	{
		//采用双缓冲绘图(为了避免闪烁,建立一个内存cdc,绘制到它,然后BitBlt它到客户端)
		CDC memDc;
		CBitmap memBitmap;
		memDc.CreateCompatibleDC(pDc);
		memBitmap.CreateCompatibleBitmap(pDc, m_rect.Width(), m_rect.Height());

		if (memDc.GetSafeHdc() != NULL)
		{
			CBitmap* pOldBitmap = (CBitmap*)memDc.SelectObject(&memBitmap);

			DoDraw(&memDc);
			pDc->BitBlt(
				0,					//指定目标矩形左上角的逻辑x坐标
				0,					//指定目标矩形左上角的逻辑y坐标
				m_rect.Width(),		//指定目标矩形的宽度(逻辑单位)
				m_rect.Height(),	//指定目标矩形的高度(逻辑单位)
				&memDc,				//指向CDC对象的指针,标识待拷贝位图的设备上下文。如果dwRop指定不包括源的光栅操作,则它必须为NULL。
				0,					//指定源位图左上角的逻辑X坐标
				0,					//指定源位图左上角的逻辑Y坐标
				SRCCOPY				//指定要执行的光栅操作(SRCCOPY:拷贝源位图到目标位图)
			);

			memDc.SelectObject(pOldBitmap);
		}
		else
		{
			DoDraw(pDc);
		}

		memBitmap.DeleteObject();
		memDc.DeleteDC();
	}
	else
	{
		DoDraw(pDc);
	}
}

void UICustom::DoDraw(CDC* pDc)
{
	//绘制边框和背景
	COLORREF colorBorder = RGB(0, 0, 0);			//边框颜色
	COLORREF colorBackground = RGB(255, 255, 255);	//背景颜色

	CPen penBorder(PS_SOLID, 1, colorBorder);
	CPen* pOldPen = pDc->SelectObject(&penBorder);
	CBrush brushBackground(colorBackground);
	CBrush* pOldBrush = pDc->SelectObject(&brushBackground);
	pDc->Rectangle(m_rect);	//绘制矩形(用画笔画线,用画刷填充颜色)
	pDc->SelectObject(pOldPen);
	pDc->SelectObject(pOldBrush);
}
;