描述:
当我们用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);
}