在我们在使用微软的绘图程序时。当要画一条直线,先用鼠标确定起始位置,然后鼠标在屏幕上来回移动时,我们会发现,这条直线就像橡皮筋一样,随着鼠标在屏幕中的位置,长短和终点都随之变化。我们在编制自己的程序时,有时也需实现类似的功能,本文将通过简单的编程实例,并说明实现原理。
private:
CPoint m_ptTarget;
bool m_MouseIsButtonDown;
CPoint m_ptOrigin;
-----------------------------------------------------------
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptOrigin=point;
m_ptTarget=point;
m_MouseIsButtonDown=1;
//MessageBox("View Clicked!");
CView::OnLButtonDown(nFlags, point);
}
-----------------------------------------------------------
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if ( !m_MouseIsButtonDown )
return;//如果鼠标左键没有被按下,则不响应直接返回
CClientDC ClientDC(this);
ClientDC.SelectStockObject(NULL_BRUSH);//SelectStockObject
选择的是系统预定义的GDI对象
//SelectObject 选择你自己自定义的的GDI对象
CPen
pen, *oldPen;
pen.CreatePen(PS_SOLID,10,RGB(255,0,0));
oldPen
= ClientDC.SelectObject(&pen);
ClientDC.SetROP2(R2_NOTXORPEN);//执行到这一句时,画面上已有前一次响应鼠标移动事件时画出的直线,这句代码把当前的直线擦掉
//R2_NOTXORPEN是C++中一种绘画模式,它先把画笔颜色(比如这里是红色)与屏幕颜色(上次画出的直线的颜色
也是红色)异或(1与1为0,1与0为1,红色与红色异或=黑色),异或之后再取反(变成白色)最后得到一个颜色值显示在屏幕上(屏幕是白色、新线条也是白色、即原来的红线条被擦掉)。
ClientDC.MoveTo(m_ptOrigin.x,m_ptOrigin.y);
ClientDC.LineTo(m_ptTarget.x,m_ptTarget.y);
m_ptTarget = point;
ClientDC.MoveTo(m_ptOrigin.x,m_ptOrigin.y);
//这两句画本次鼠标移动事件的直线因为有异或操作
ClientDC.LineTo(m_ptTarget.x,m_ptTarget.y);
ClientDC.SelectObject(oldPen);
CView::OnMouseMove(nFlags,
point);
}
---------------------------------------------------------
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (!m_MouseIsButtonDown )
return;//如果鼠标左键没有被按下,则不响应直接返回
m_MouseIsButtonDown = false;
CClientDC ClientDC(this);
ClientDC.SelectStockObject(NULL_BRUSH);
CPen pen, *oldPen;
pen.CreatePen(PS_SOLID,10,RGB(255,0,0));//在鼠标松开的时候要再次画一条线是因为:鼠标移动画出的线条,在交叉处会是白色的,这里再画一条直线覆盖掉交叉处白色的部分,这样直线交叉处也是红色的了。
oldPen = ClientDC.SelectObject(&pen);
ClientDC.SetROP2( R2_COPYPEN ); //
ClientDC.MoveTo(m_ptOrigin.x,m_ptOrigin.y);
ClientDC.LineTo(m_ptTarget.x,m_ptTarget.y);
ClientDC.SelectObject(oldPen);//
CView::OnLButtonUp(nFlags, point);
}