借鉴自http://blog.csdn.net/hong__fang/article/details/44200811
双缓冲的实质就是在显示下一幅图像时,阻止程序自动调用OnEraseBkgnd来绘制背景(先把原图像区域显示为背景(默认白色),再显示下一幅图,因此会出现闪屏的现象)。所采取的方法就是对OnEraseBkgnd进行重载,并且在内存绘好图之后直接覆盖在上一幅图上面。代码如下:
//处理闪屏,将背景绘制函数清空,同时onpaint中的新图要覆盖上一次的图
BOOL CViewRight::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
return CScrollView::OnEraseBkgnd(pDC);
}
void CViewRight::OnPaint()
{
CstereoUAVDoc* pDoc = (CstereoUAVDoc*)GetDocument();
int nImgWidth = pDoc->GetImgWith();
int nImgHeight = pDoc->GetImgHeight();
float m_fExpand = pDoc->GetExpandNum();
CRect ClientRect;
GetClientRect(&ClientRect); //获取客户区大小
//此处:宽高取屏幕与滚动条长度的最大值,不然放大缩小时,不能完全刷去上一次的图
int nWidth = (nImgWidth*m_fExpand> ClientRect.Width()) ? int(nImgWidth*m_fExpand) : ClientRect.Width(); int nHeight = (nImgHeight*m_fExpand> ClientRect.Height()) ? int(nImgHeight*m_fExpand) : ClientRect.Height();
CPaintDC dc(this); // 此处会自动调用OnEraseBkgnd重刷背景
// TODO: 在此处添加消息处理程序代码
OnPrepareDC(&dc);
RECT ClipBox;
dc.GetClipBox(&ClipBox);
HDC hDC = dc.GetSafeHdc();
HDC hMemDC = ::CreateCompatibleDC(hDC);
HBITMAP Bitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
HBITMAP OldBitmap = (HBITMAP)::SelectObject(hMemDC, Bitmap);
::SetWindowOrgEx(hMemDC, ClipBox.left, ClipBox.top, NULL);//设置设备原点
CDC MemDC;
MemDC.Attach(hMemDC);
//用背景色把位图清理干净,这里选用白色做背景
MemDC.FillSolidRect(0,0,max(nWidth,lastWidth),max(nHeight,lastHeight),RGB(255,255,255));//!!!有待修改
lastWidth = nWidth;
lastHeight = nHeight;
OnDraw(&MemDC);
//正常显示,一个图像像素对应一个屏幕像素
::BitBlt(hDC, ClipBox.left, ClipBox.top,ClipBox.right - ClipBox.left,
ClipBox.bottom - ClipBox.top, hMemDC, ClipBox.left, ClipBox.top, SRCCOPY);
::SelectObject(hMemDC, OldBitmap);
::DeleteObject(Bitmap);
::DeleteDC(hMemDC);
}
void CViewRight::OnDraw(CDC* pDC)
{
CstereoUAVDoc* pDoc = (CstereoUAVDoc*)GetDocument();
// TODO: 在此处为本机数据添加绘制代码
CxImage* pImage;
pImage = pDoc->GetImage();
if(pImage == NULL)
return ;
int nImgWidth,nImgHeight;
nImgWidth = pDoc->GetImgWith();
nImgHeight = pDoc->GetImgHeight();
//绘图
pImage->Draw(pDC->m_hDC,0,0,int(nImgWidth * pDoc->GetExpandNum()),int(nImgHeight * pDoc->GetExpandNum()));
//获取主框架窗口指针
CMainFrame* pMainFrm = (CMainFrame*)AfxGetApp()->GetMainWnd();
if(pMainFrm == NULL)
AfxMessageBox(_T("获取主框架指针失败!"));
CSize sizeTotal;
// TODO: 计算此视图的合计大小
sizeTotal.cx = int(nImgWidth * pDoc->GetExpandNum());
sizeTotal.cy =int(nImgHeight * pDoc->GetExpandNum());
SetScrollSizes(MM_TEXT, sizeTotal);//会调用onpaint
}
这种方法在浏览大图时还是会出现bug,具体情况是把进度条拖到右下角,然后点击缩小,暂时还未解决。