MFC 读取图像双缓冲

借鉴自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,具体情况是把进度条拖到右下角,然后点击缩小,暂时还未解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值