随笔-14  评论-8  文章-0  trackbacks-0

  双缓冲技术能消除窗口绘制时的闪烁,使得窗体控件能够平滑绘制,这谁都知道。
  但并不是每个人都理解它,我不就是其中一个么
  Goolge了半天,别人实现双缓冲的心得也看了半天多一点,还是不知其所然。接下来的事情有点机缘巧合,但都要感谢MSDN,这也再次印证了“MSDN是最好的老师”这句话。
   我选择了在 OnPaint() 函数中来实现它,按照MSDN中“CDC::CreateCompatibleDC”一文,左右修改,瞎猜乱碰,竟然给我把效果弄出来了。于是又看了半天才有一点点了解,原来这就是双缓冲。不多说了,代码最真:

void CRToolDlg::OnPaint()
{
    
//如果从托盘恢复,调用CDialog的OnPaint(),不然窗体无法画出
    if(m_bComeFromTray) {
        m_bComeFromTray 
= FALSE;
        CDialog::OnPaint();
        
return;
    }


    
//重置记忆位图和DC
    if(m_pBitmap->m_hObject != NULL)
        m_pBitmap
->DeleteObject();
    
if(m_pMemDC->m_hDC != NULL)
        m_pMemDC
->DeleteDC();

    CRect rc;
    GetClientRect(
&rc);

    
//获得屏幕DC
    m_pDC->m_hDC = ::GetDC(NULL);

    
//为屏幕DC创建兼容的内存DC 
    m_pMemDC->CreateCompatibleDC(m_pDC);

    
//使绘制的位图和客户区一样大
    m_pBitmap->CreateCompatibleBitmap(m_pDC, rc.Width(), rc.Height());
    m_pOldBitmap 
= m_pMemDC->SelectObject(m_pBitmap);    //m_pMemDC选中m_pBitmap,并且返回上一个object,和我的第一篇文档对应

    
//双缓冲
    m_pMemDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), m_pDC, rc.left, rc.top, SRCCOPY);
    m_pDC
->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), m_pMemDC, rc.left, rc.top, SRCCOPY);

    
//选回旧设备,以释放……
    m_pMemDC->SelectObject(m_pOldBitmap);
}

  还要注意的是对象的new与delete,以及清除窗口背景的函数,没了。
  以上只是对话框里的实现,至于文档视图,等待实践。
posted on 2009-03-18 10:20 崇文 阅读(869) 评论(1)  编辑 收藏 引用

评论:
# re: 对话框中的双缓冲 2010-01-23 23:12 | 崇文
2010/1/23 这篇文章的思想是错误的。现在在回头来看双缓冲,原理很简单,实现逻辑也并不复杂。当时我真昏了头了。For the heck of it , still keep it!  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理