橡皮线的工作原理:就必须不停地在新位置画出线段,并把以前的画出的线段擦掉。如果背景是单一的颜色,那就好办了,只需要构造一支背景颜色的画笔和一支前景颜色的画笔,然后首先用背景色画笔擦出上次的线段,再用前景颜色的画笔画出新的线段,就可以实现橡皮线了。由于橡皮线的起点是不变的,而终点在不停地改变,因此,还需要记录下前一条线段的终点位置。
但是,这种方法还有问题存在,一个问题是假如背景色不是单一的,就不好办了。另一个问题就算是单一背景色,移动的橡皮线还会把已存在的图形破坏掉。其解决办法是采用混合模式。
如果在画橡皮条是直接把线条混合模式设置为R2_NOT(反色)模式,则负负得正,画两次刚好回到屏幕上的图形。也可以设置为R2_NOTXORPEN(非异或)模式或者R2_XORPEN(异或)模式。
程序设置如下:
在视图类中添加如下成员变量:
CPoint m_begin,m_end; //记录线条的起点、终点
BOOL m_lMouseIsDown; //记录鼠标左键是否按下
BOOL m_lMouseIsUp; //记录鼠标左键是否弹起
在视图类成员函数中初始化这三个成员变量
m_begin.x=m_begin.y=0;
m_end.x=m_end.y=0;
m_lMouseIsDown=FALSE; //初始时鼠标左键没有被按下
m_lMouseIsUp=TRUE; //初始时鼠标左键处于弹起状态
在你的视图类添加一下三个消息处理函数
void CExampleLineView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_begin=point;
m_lMouseIsDown=TRUE; //鼠标左键被按下
SetCapture();
CView::OnRButtonDown(nFlags, point);
}
void CExampleLine3View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(GetCapture()!=this)return;
CClientDC dc(this);
if(m_lMouseIsDown) //鼠标左键被按下,拉出橡皮线
{
dc.SetROP2(R2_NOTXORPEN); //设置混合模式
if(!m_lMouseIsUp) //左键处于弹起状态,擦出上一次画的线段
{
dc.MoveTo(m_begin);
dc.LineTo(m_end);
}
m_mouseIsUp=FALSE;
m_end=point; //重新记录上一次线段的终点
dc.MoveTo(m_begin);
dc.LineTo(m_end);
}
CView::OnMouseMove(nFlags, point);
}
void CExampleLine3View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(GetCapture()!=this)return;
CClientDC dc(this);
dc.MoveTo(m_begin);
dc.LineTo(point);
m_lMouseIsUp=TRUE;
m_lMouseIsDown=FALSE;
ReleaseCapture();
CView::OnLButtonUp(nFlags, point);
}