这个程序长方形和椭圆.在菜单中设置所绘图形的种类,然后用鼠标拖动画图.在菜单中有一个橡皮命令.它一次擦除一个已有图形.我是这样实现的:首先将计数器减1,再调用Invalidate(int)来重画视图,我不知道Invalidate函数的参数是干什么用的,我先用计数器作实参,发现不行.用橡皮命令有时不擦除图形,有时一次擦除两个图形.我又用计数器的值加1作实参就没问题了.请大侠为我解释一下Invalidate函数参数的意义.多谢了.
        (MyDrawView.cpp摘录如下,前面都没问题,有问题的地方在这个文件的倒数第八行左右)
#include "stdafx.h"
#include "MyDraw1.h"#include "MyDraw1Doc.h"
#include "MyDraw1View.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMyDraw1ViewIMPLEMENT_DYNCREATE(CMyDraw1View, CView)BEGIN_MESSAGE_MAP(CMyDraw1View, CView)
//{{AFX_MSG_MAP(CMyDraw1View)
ON_COMMAND(ID_TOOL_RECTANGLE, OnToolRectangle)
ON_COMMAND(ID_TOOL_ELLIPSE, OnToolEllipse)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_UPDATE_COMMAND_UI(ID_TOOL_RECTANGLE, OnUpdateToolRectangle)
ON_UPDATE_COMMAND_UI(ID_TOOL_ELLIPSE, OnUpdateToolEllipse)
ON_COMMAND(ID_VISUAL_CAN, OnVisualCan)
ON_COMMAND(ID_VISUAL_CNANOT, OnVisualCnanot)
ON_UPDATE_COMMAND_UI(ID_VISUAL_CAN, OnUpdateVisualCan)
ON_UPDATE_COMMAND_UI(ID_VISUAL_CNANOT, OnUpdateVisualCnanot)
ON_COMMAND(ID_TOOL_ERASE, OnToolErase)
ON_COMMAND(ID_TOOL_ERASE_ALL, OnToolEraseAll)

//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMyDraw1View construction/destructionCMyDraw1View::CMyDraw1View()
{
// TODO: add construction code here
    m_typeNext = shpRectangle;
m_bCaptured = false;
m_pBrushOld = NULL;
m_countShapes = 0;
m_bVisual = false;
    
 
}CMyDraw1View::~CMyDraw1View()
{
}BOOL CMyDraw1View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs return CView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CMyDraw1View drawingvoid CMyDraw1View::OnDraw(CDC* pDC)
{
CMyDraw1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
for(int nShp = 0; nShp < m_countShapes; nShp++)
{
ASSERT(m_arShps[nShp].m_typeShape == shpRectangle ||
m_arShps[nShp].m_typeShape == shpEllipse);
SetPenBrush(pDC);
switch(m_arShps[nShp].m_typeShape)
{
case shpRectangle:
pDC->Rectangle(m_arShps[nShp].m_boxShape);
break;
case shpEllipse:
pDC->Ellipse(m_arShps[nShp].m_boxShape);
break;
}

}

}/////////////////////////////////////////////////////////////////////////////
// CMyDraw1View diagnostics#ifdef _DEBUG
void CMyDraw1View::AssertValid() const
{
CView::AssertValid();
}void CMyDraw1View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}CMyDraw1Doc* CMyDraw1View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDraw1Doc)));
return (CMyDraw1Doc*)m_pDocument;
}
#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CMyDraw1View message handlersvoid CMyDraw1View::OnToolRectangle() 
{
// TODO: Add your command handler code here
m_typeNext = shpRectangle;

}void CMyDraw1View::OnToolEllipse() 
{
// TODO: Add your command handler code here
m_typeNext = shpEllipse;

}
void CMyDraw1View::OnLButtonDown(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
SetCapture();
m_bCaptured = true; ASSERT(m_typeNext == shpRectangle || m_typeNext ==
shpEllipse);
m_shpTemp.m_typeShape = m_typeNext;
m_shpTemp.m_boxShape.left = m_shpTemp.m_boxShape.right = point.x;
m_shpTemp.m_boxShape.top = m_shpTemp.m_boxShape.bottom = point.y;
CView::OnLButtonDown(nFlags, point);
}void CMyDraw1View::OnMouseMove(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
if(m_bCaptured)
{
CClientDC dc(this);
        m_shpTemp.m_boxShape.bottom = point.y;
m_shpTemp.m_boxShape.right = point.x;
}

CView::OnMouseMove(nFlags, point);
}void CMyDraw1View::OnLButtonUp(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
if(m_bCaptured)
{
::ReleaseCapture();
m_bCaptured = false;
        
CClientDC dc(this);     m_shpTemp.m_boxShape.right = point.x;
m_shpTemp.m_boxShape.bottom = point.y; m_arShps[m_countShapes] = m_shpTemp;
m_countShapes++; Draw(&dc,m_shpTemp);
}

CView::OnLButtonUp(nFlags, point);
}void CMyDraw1View::SetPenBrush(CDC *pDC )
{
   if(m_bVisual)

   m_pBrushOld = (CBrush* )pDC->SelectStockObject(NULL_BRUSH);
   else
   m_pBrushOld = (CBrush* )pDC->SelectStockObject(WHITE_BRUSH);
}
void CMyDraw1View::OnUpdateToolRectangle(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_typeNext == shpRectangle);

}void CMyDraw1View::OnUpdateToolEllipse(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_typeNext == shpEllipse);
}void CMyDraw1View::Draw(CDC *pDC, Shape &s)
{
ASSERT(pDC != NULL);
SetPenBrush(pDC);
switch(s.m_typeShape)
{
case shpRectangle: pDC->Rectangle(s.m_boxShape);
break;
case shpEllipse: pDC->Ellipse(s.m_boxShape);
break;
}}
void CMyDraw1View::OnVisualCan() 
{
// TODO: Add your command handler code here
m_bVisual = true;


}void CMyDraw1View::OnVisualCnanot() 
{
// TODO: Add your command handler code here
m_bVisual = false;


}void CMyDraw1View::OnUpdateVisualCan(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_bVisual == true);

}void CMyDraw1View::OnUpdateVisualCnanot(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_bVisual == false);
}void CMyDraw1View::OnToolErase() 
{
// TODO: Add your command handler code here
m_countShapes--;

Invalidate(m_countShapes+1); /*问题在这儿,Invalidate函数的参数 是什么意思   */
    
}void CMyDraw1View::OnToolEraseAll() 
{
// TODO: Add your command handler code here
m_countShapes = 0;

Invalidate(m_countShapes+1);
}