• VC++ MFC橡皮筋技术


    在MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动

    //OnLButtionDown
           m_ptOrigin = m_ptEnd = point; 
    //OnMouseMove
        CClientDC dc(this);
        if (nFlags == MK_LBUTTON )
        {
            dc.SetROP2(R2_NOT);
            dc.MoveTo(m_ptOrigin);
            dc.LineTo(m_ptEnd);
            m_ptEnd = point;
            dc.MoveTo(m_ptOrigin);
            dc.LineTo(m_ptEnd);
        } 
    但是这个只能实现黑色直线的绘制,我们想要画其他颜色的线,并且希望使用不同类型的线和线宽,因此要建一个画笔,指定想要的画笔的类型,如实线、虚线、点线,指定线宽和画笔颜色。
    void CGraphic1View::OnMouseMove(UINT nFlags, CPoint point) 
    {    
        if(MK_LBUTTON == nFlags)
        {
            CClientDC dc(this);
            int oldmode=dc.SetROP2(R2_NOTXORPEN);
            CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
            oldpen = dc.SelectObject(&pen);

            dc.MoveTo(m_ptOrigin);
            dc.LineTo(m_ptEnd);

            m_ptEnd=point;

            dc.MoveTo(m_ptOrigin);
            dc.LineTo(m_ptEnd);

            dc.SelectObject(oldpen);
            dc.SetROP2(oldmode);
            ReleaseDC(&dc);
        }
        CScrollView::OnMouseMove(nFlags, point);
    }
    其中
    CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
    m_nLineStyle是线型,m_nLineWidth是线宽,m_clr是画笔颜色,也可以指定如下:
    CPen pen(0, 0, RGB(255, 0, 0)), *oldpen;

     

    下面说一下,橡皮筋效果是如何实现的。当我们按下鼠标左键后,有m_ptOrigin = m_ptEnd = point; 
    这时鼠标移动就会发送WM_MOUSEMOVE消息,调用OnMouseMove进行处理,我们就在这个响应函数中实现橡皮筋的效果。if(MK_LBUTTON == nFlags)判断是否左键按下的鼠标移动。SetROP2函数主要用于设定当前前景色的混合模式。参数取值R2_NOT就是取反的意思,即前景色为背景色的反色,经常用R2_NOT来画橡皮线,因为两次取反可以还原背景色,但是只能话黑色的线。

    而R2_NOTXORPEN画出来的颜色与R2_XORPEN相反,R2_XORPEN是屏幕颜色和画笔颜色的异或。OnMouseMove第一次被调用时,还没画线,所以屏幕的颜色是白色的,R2_XORPEN是当前画笔的颜色取反,那么R2_NOTXORPEN就是当前画笔颜色了。就是说第一次画的线是画笔的颜色。

    第二次调用OnMouseMove时,m_ptOrigin和m_ptEnd两个点还没变,所以可以用这两个点再画线,将第一次画的线覆盖掉,变成画布的颜色,然后在新的point点和m_ptOrigin之间重新画线,颜色为画笔颜色。在旧的直线上面画线,因为线本来有颜色,所以R2_XORPEN(屏幕的颜色==画笔颜色)就会变成黑色(1 xor 1=0,0 xor 0=0),取反,即R2_NOTXORPEN为白色,就是画布的颜色,看起来就像消失了一样,其实只不过是线变成白色了(如果画笔不是白色,比如使用你系统设置了护眼配色,客户区变成不伤眼的浅绿色,这样显示出来的颜色还是白色,而不是客户区的颜色)。旧的直线删除了,就可以在新的点point上再次画线了。

     

    扩展:如果想实现矩形、椭圆的橡皮筋效果将语句

    dc.MoveTo(m_ptOrigin);    
    dc.LineTo(m_ptEnd);
    换成:
    dc.Rectangle(CRect(this->m_ptOrigin, m_ptEnd));
    或者
    dc.Ellipse(CRect(this->m_ptOrigin, m_ptEnd));
    就可以了。
  • 相关阅读:
    hdu1158Employment Planning
    hdu1244Max Sum Plus Plus Plus
    .net客户端根据url获取字符串及图片,并保存本地
    wpf 3d文字
    .NET json格式 使用Newtonsoft.Json.JsonConvert类 附读取文件方法
    c# 按钮点击(开启||置顶)全局变量
    WPF 分辨率自适应,获取当前系统分辨率+窗口当前坐标
    WPF 循环读取文件中实现进度条显示
    WPF摄像头拍照+选择是否保存
    WPF Image显示本地照片 判断选择删除
  • 原文地址:https://www.cnblogs.com/jinsedemaitian/p/5589081.html
Copyright © 2020-2023  润新知