橡皮線的工作原理:就必須不停地在新位置畫出線段,並把以前的畫出的線段擦掉。如果背景是單一的顏色,那就好辦了,只需要構造一支背景顏色的畫筆和一支前景顏色的畫筆,然後首先用背景色畫筆擦出上次的線段,再用前景顏色的畫筆畫出新的線段,就可以實現橡皮線了。由於橡皮線的起點是不變的,而終點在不停地改變,因此,還需要記錄下前一條線段的終點位置。
但是,這種方法還有問題存在,一個問題是假如背景色不是單一的,就不好辦了。另一個問題就算是單一背景色,移動的橡皮線還會把已存在的圖形破壞掉。其解決辦法是採用混合模式。
如果在畫橡皮條是直接把線條混合模式設置爲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);
}