【VC6.0】直线的橡皮筋绘图技术

本文介绍如何在自定义程序中实现类似微软绘图程序中弹性直线的功能。通过代码示例详细解释了鼠标点击、移动及释放时如何绘制一条随鼠标移动而变化长度和位置的直线。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       在我们在使用微软的绘图程序时。当要画一条直线,先用鼠标确定起始位置,然后鼠标在屏幕上来回移动时,我们会发现,这条直线就像橡皮筋一样,随着鼠标在屏幕中的位置,长短和终点都随之变化。我们在编制自己的程序时,有时也需实现类似的功能,本文将通过简单的编程实例,并说明实现原理。


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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值