最近在处理图形方面的东西在网上看到下面一段文字。
我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘 时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口 看起来在闪。
..........................
这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好,然后再一次性 的将内存中的图形按照一个点一个点地覆盖到屏幕上去(这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便用什么反差大的背景色进行清 除都不会闪,因为看不见。当贴到屏幕上时,因为内存中最终的图形与屏幕显示图形差别很小(如果没有运动,当然就没有差别),这样看起来就不会闪。
第一次写文章,有不对的地方请指正啊.. 双缓存:就是在内存中准备一块区域,把要显示的位图都加载到内存中,然后调用BitBlt函数,把内存设备复制到显示设备上,这样就可以防止闪屏了.. 下面是在VC中,实现的步骤..
1 新建一单文档MFC程序,取名为test1.
2在CTest1View中添加两个成员函数 void ShowBmpUseDbBuffer(); //用双缓存显示位图 void ShowBmp(); //没有使用双缓存就显示位图.. 添加一菜单命令,启动Timer,观察两种效果
3 主要实现代码如下:
//使用双缓存技术,显示位图,防止闪屏
void CTest1View::ShowBmpUseDbBuffer()
{
CDC *pDC = GetDC();
CBitmap BmpBack,BmpFront,BmpMem; //背景,前景,内存位图
CDC BackDC,FrontDC,MemDC; //背景设备,前景设备,内存设备
//创建与显示设备兼容的位图
BmpMem.CreateCompatibleBitmap(pDC, 1024, 768);
//加载位图
BmpBack.LoadBitmap(IDB_BITMAP_BACK);
BmpFront.LoadBitmap(IDB_BITMAP_FRONT);
//创建与显示设备兼容的设备
BackDC.CreateCompatibleDC(pDC);
FrontDC.CreateCompatibleDC(pDC);
MemDC.CreateCompatibleDC(pDC);
//将位图选入设备
MemDC.SelectObject(&BmpMem);
BackDC.SelectObject(&BmpBack);
MemDC.BitBlt(0, 0, 1024, 768, &BackDC, 0, 0, SRCCOPY);
//将前景位图选入设备
FrontDC.SelectObject(&BmpFront);
MemDC.BitBlt(0, 0, 1024, 768, &FrontDC, 0, 0, SRCCOPY);
//只一次性的向显示设备显示位图,不会出现闪屏
pDC->BitBlt(0, 0, 1024, 768, &MemDC, 0, 0, SRCAND);
//释放资源
pDC->DeleteDC();
BackDC.DeleteDC();
FrontDC.DeleteDC();
MemDC.DeleteDC();
}
//没有使用双缓存技术,出现闪屏
void CTest1View::ShowBmp()
{
CDC *pDC = GetDC();
CBitmap BmpBack,BmpFront; //背景,前景位图
CDC BackDC,FrontDC; //背景设备,前景设备,内存设备
//加载位图
BmpBack.LoadBitmap(IDB_BITMAP_BACK);
BmpFront.LoadBitmap(IDB_BITMAP_FRONT);
//创建与显示设备兼容的设备
BackDC.CreateCompatibleDC(pDC);
FrontDC.CreateCompatibleDC(pDC);
//将背景位图选入设备
BackDC.SelectObject(&BmpBack);
pDC->BitBlt(0, 0, 1024, 768, &BackDC, 0, 0, SRCCOPY); //显示背景位图
//将前景位图选入设备
FrontDC.SelectObject(&BmpFront);
pDC->BitBlt(0, 0, 1024, 768, &FrontDC, 0, 0, SRCCOPY); //显示前景位图
/************************
分两次的显示位图(先显示背景,再显示前景),
结果就出现了闪屏.
**************************/
//释放资源
pDC->DeleteDC();
BackDC.DeleteDC();
FrontDC.DeleteDC();
}
//
//添加一菜单命令,启动一个Timer
void CTest1View::OnMenuitemStart()
{
// TODO: Add your command handler code here
SetTimer(1,5,NULL);
}
//在OnTimer()函数中,查看两种效果
void CTest1View::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
ShowBmpUseDbBuffer(); //使用双缓存技术,显示位图,防止闪屏
//ShowBmp(); //没有使用双缓存技术,出现闪屏
CView::OnTimer(nIDEvent);
}