双缓冲技术

来源:互联网 发布:coc皮卡升级数据 编辑:程序博客网 时间:2024/06/05 14:20
/////////////////////////////////////////////////////////////////////////
//
//如下的做法能避免绘图闪烁
//
//主要思想是将以前直接画在pDC上的图,改画到一个内存DC(如dcMem)中去,
//然后使用BitBlt函数,将dcMem这个内存中的图复制到当前屏幕即pDC中去.
//
//具体步骤如下, 其中 a 和 b 选择一步即可, 不可二者都做: 
//a. 直接在 OnDraw()中增加如下语句, 以改变窗口背景为透明色:
// ::SetClassLong(this->m_hWnd, GCL_HBRBACKGROUND,
//(LONG)(HBRUSH)::GetStockObject(NULL_BRUSH));
//b. 在CxxxView类中增加OnEraseBkgnd()消息响应函数, 
// 将其中的代码改为: return TRUE;
//   直接返回TRUE表示告诉系统绘图时不再绘制背景,相当于设置窗口背景
// 为NULL刷子.
//c. 为CxxxView类增加一个成员函数 void OnDrawMem(CDC &dcMem),
//   并将你以前写在OnDraw()中的代码,移到OnDrawMem()中去即可.
//
/////////////////////////////////////////////////////////////////////////

//1. 改变当前View窗口的背景为空刷子
::SetClassLong(this->m_hWnd, GCL_HBRBACKGROUND, (LONG)(HBRUSH)::GetStockObject(NULL_BRUSH));

//2. 获取当前绘图区的宽度和高度
CRect rcClient;
this->GetClientRect(&rcClient);
int nWidth = rcClient.Width();
int nHeight= rcClient.Height();
//3. 创建一个和pDC兼容的内存DC: dcMem
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);//pDC换成NULL也可以,指定为显示器
//创建一个位图对象, 其宽度和高度就用当前绘图区的 nWidth 和 nHeight
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, nWidth, nHeight);

//将bmp选入到dcMem中, 只有选入了位图的dcMem才有地方绘图,画到指定的bmp位图上
CBitmap * pOldBit = dcMem.SelectObject(&bmp);
//4. 先用背景色将位图清除干净,这里我用的是白色作为背景
dcMem.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
//5. 执行真正的绘图代码, 如 dcMem.MoveTo(……); dcMem.LineTo(……); 等等
OnDrawMem(&dcMem);

//6. 将dcMem中的图拷贝到pDC上进行显示. 关键点.
pDC->BitBlt(0, 0, nWidth, nHeight, &dcMem, 0, 0, SRCCOPY);
//7. 绘图完成后的清理
bmp.DeleteObject();
dcMem.DeleteDC();
原创粉丝点击