双缓冲技术能消除窗口绘制时的闪烁,使得窗体控件能够平滑绘制,这谁都知道。
但并不是每个人都理解它,我不就是其中一个么。
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) 编辑 收藏 引用