我看的第五版,第十一章<位图>第二个例子(ex11b)OnPaint有点晕.请高手指点,谢谢
void CEx11bView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CScrollView::OnPaint() OnPrepareDC(&dc);
CRect rectUpdate;
dc.GetClipBox(&rectUpdate);--->//得到的rect是OnMouseMove算来的吗?如何传递过来的?
CBitmap* pOldBitmap=m_pdcMemory->SelectObject(m_pBitmap);
m_pdcMemory->SelectClipRgn(NULL);
m_pdcMemory->IntersectClipRect(&rectUpdate);
CBrush backgroundBrush((COLORREF)::GetSysColor(COLOR_WINDOW));
CBrush* pOldBrush=m_pdcMemory->SelectObject(&backgroundBrush);
m_pdcMemory->PatBlt(rectUpdate.left,rectUpdate.top,rectUpdate.Width  (),rectUpdate.Height(),PATCOPY);---------> //在msdn里说PatBlt建立一个位模版,这里有什么用?
OnDraw(m_pdcMemory);-----------> //感觉应和BitBlt交换位置,交换了又不对,为什么?
dc.BitBlt(rectUpdate.left,rectUpdate.top,rectUpdate.Width(),rectUpdate.Height(),m_pdcMemory,rectUpdate.left,rectUpdate.top,SRCCOPY);-->//把位图从m_pdcMemory copy to dc是这样吗?copy过去有什么用?
m_pdcMemory->SelectObject(pOldBitmap);
m_pdcMemory->SelectObject(pOldBrush);
}
//OnMouseMovevoid CEx11bView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
     if (m_bCaptured) {
        CClientDC dc(this);
        OnPrepareDC(&dc);
        CRect rectOld(m_pointTopLeft, m_sizeEllipse);
        dc.LPtoDP(rectOld);
        InvalidateRect(rectOld, FALSE);
        m_pointTopLeft = point - m_sizeOffset;
        dc.DPtoLP(&m_pointTopLeft);
        CRect rectNew(m_pointTopLeft, m_sizeEllipse);
        dc.LPtoDP(rectNew);
        InvalidateRect(rectNew, FALSE);
    }
}

解决方案 »

  1.   

    -->//把位图从m_pdcMemory copy to dc是这样吗?copy过去有什么用?
    是的,DC(device contex)是指设备上下文,一个dc总是和设备相关的,位图copy到dc,就能显示在相应的dc代表的设备上面,如显示器
      

  2.   

    先在后台做好准备工作后,直接将最终结果copy到前台
      

  3.   

    得到的rect是OnMouseMove算来的吗?如何传递过来的?这一句:
    InvalidateRect(rectNew, FALSE);使得指定矩形rectNew刷新,在OnPaint()中通过GetClipBox()得到的就是这个矩形。注意,这个DC必须是用CPaintDC dc(this);得到的,或者用API函数BeginPaint()得到。
    在msdn里说PatBlt建立一个位模版,这里有什么用?注意Blt后缀的函数表示位图操作,对于PatBlt就是用指定的模式位图来填充一个矩形,这个模式就是最后一个参数指定的,这里PATCOPY指的是用选中的画刷来填充,和选用空画笔用RectAngle来绘制矩形是类似的。OnDraw(m_pdcMemory);-----------> //感觉应和BitBlt交换位置,交换了又不对,为什么?
    dc.BitBlt(rectUpdate.left,rectUpdate.top,rectUpdate.Width(),rectUpdate.Height(),m_pdcMemory,rectUpdate.left,rectUpdate.top,SRCCOPY);-->//把位图从m_pdcMemory copy to dc是这样吗?copy过去有什么用?两个问题是一个。这里传递给OnDraw的参数是m_pdcMemory,意思是在内存中进行绘制,可以看看原来的CView的OnPaint()函数,调用的是OnDraw(&dc),表示在窗口DC上绘图。内存中绘制好以后,再用BitBlt从内存DC往屏幕DC拷贝位图,达到显示到屏幕上的目的。这种技术就是双缓冲。