zoukankan      html  css  js  c++  java
  • 在MFC中,利用GDI绘制橡皮筋效果-直线,圆,椭圆,矩形

    这段时间学习了GDI和GDI+;如果想实现橡皮筋效果,还是离不开GDI。虽然GDI+也能实现,但比较麻烦,有局限性,必须用到双缓冲。

    下面贴出GDI绘制橡皮筋效果的示例代码


    ZKCADView.h:
    public:
    afx_msg void OnDrline();
    afx_msg void OnDrcircle();
    afx_msg void OnDrrect();
    afx_msg void OnDrellipse();
    // 鼠标左键点击次数
    bool nClick;
    // 绘图类型
    int flag;
    CPoint m_Start;
    CPoint m_End;
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    // 绘制直线
    void DrawLine(bool isRubber, CPoint ptStart, CPoint ptEnd);
    void DrawCircle(bool isRubber, CPoint ptCenter, CPoint ptOnCircle);
    void DrawRect(bool isRubber, CPoint ptUL, CPoint ptLR);
    void DrawEllipse(bool isRubber, CPoint ptUL, CPoint ptLR);
    ZKCADView.cpp:
    // 绘制直线
    void CZKCADView::OnDrline()
    {
    // TODO: 在此添加命令处理程序代码
    flag = 1;
    }
    
    
    // 绘制圆
    void CZKCADView::OnDrcircle()
    {
    // TODO: 在此添加命令处理程序代码
    flag = 2;
    }
    
    
    // 绘制矩形
    void CZKCADView::OnDrrect()
    {
    // TODO: 在此添加命令处理程序代码
    flag = 3;
    }
    
    
    // 绘制椭圆
    void CZKCADView::OnDrellipse()
    {
    // TODO: 在此添加命令处理程序代码
    flag = 4;
    }
    
    
    
    
    void CZKCADView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if(0!=flag)
    {
    // 绘制直线
    if(1==flag)
    {
    if( false==nClick)
    {
    m_Start = m_End = point;
    DrawLine(false,m_Start,m_End);
    nClick=true;
    }
    else
    {
    DrawLine(false,m_Start,m_End);
    nClick=false;
    }
    }
    // 绘制圆
    if(2==flag)
    {
    if( false==nClick)
    {
    m_Start = m_End = point;
    DrawCircle(false,m_Start,m_End);
    nClick=true;
    }
    else
    {
    DrawCircle(false,m_Start,m_End);
    nClick=false;
    }
    }
    // 绘制矩形
    if(3==flag)
    {
    if( false==nClick)
    {
    m_Start = m_End = point;
    DrawRect(false,m_Start,m_End);
    nClick=true;
    }
    else
    {
    DrawRect(false,m_Start,m_End);
    nClick=false;
    }
    }
    
    
    // 绘制椭圆
    if(4==flag)
    {
    if( false==nClick)
    {
    m_Start = m_End = point;
    DrawEllipse(false,m_Start,m_End);
    nClick=true;
    }
    else
    {
    DrawEllipse(false,m_Start,m_End);
    nClick=false;
    }
    }
    
    
    }
    CView::OnLButtonDown(nFlags, point);
    }
    
    
    
    
    void CZKCADView::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if(0!=flag)
    {
    // 直线
    if(1==flag)
    {
    if(nClick)
    {
    DrawLine(true,m_Start,m_End);
    DrawLine(true,m_Start,point);
    m_End=point;
    }
    }
    //圆
    if(2==flag)
    {
    if(nClick)
    {
    DrawCircle(true,m_Start,m_End);
    DrawCircle(true,m_Start,point);
    m_End=point;
    }
    }
    //矩形
    if(3==flag)
    {
    if(nClick)
    {
    DrawRect(true,m_Start,m_End);
    DrawRect(true,m_Start,point);
    m_End=point;
    }
    }
    //椭圆
    if(4==flag)
    {
    if(nClick)
    {
    DrawEllipse(true,m_Start,m_End);
    DrawEllipse(true,m_Start,point);
    m_End=point;
    }
    }
    }
    CView::OnMouseMove(nFlags, point);
    }
    
    
    
    
    // 绘制直线
    void CZKCADView::DrawLine(bool isRubber, CPoint ptStart, CPoint ptEnd)
    {
    CDC* pDC = GetDC();
    if(isRubber)
    {
    pDC->SetROP2(R2_NOT);
    }
    CPen pen(PS_SOLID,1,RGB(255,0,0));
    CPen *pOldPen = pDC->SelectObject(&pen);
    pDC->MoveTo(ptStart.x,ptStart.y);
    pDC->LineTo(ptEnd.x,ptEnd.y);
    pDC->SelectObject(pOldPen);
    ReleaseDC(pDC);
    }
    
    
    // 绘制圆
    void CZKCADView::DrawCircle(bool isRubber, CPoint ptCenter, CPoint ptOnCircle)
    {
    CDC* pDC = GetDC();
    // 半径计算
    float r1 = (float)((ptCenter.x-ptOnCircle.x)*(ptCenter.x-ptOnCircle.x) + (ptCenter.y-ptOnCircle.y)*(ptCenter.y-ptOnCircle.y));
    LONG r = sqrt(r1);
    // 设置透明画刷
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    CBrush *pOldBrush =pDC->SelectObject(pBrush);
    if(isRubber)
    {
    pDC->SetROP2(R2_NOT);
    pDC->MoveTo(ptCenter.x,ptCenter.y);
    pDC->LineTo(ptOnCircle.x,ptOnCircle.y);
    // 半径
    pDC->Ellipse(ptCenter.x-r,ptCenter.y-r,ptCenter.x+r,ptCenter.y+r);
    }
    else
    {
    CPen pen(PS_SOLID,1,RGB(255,0,0));
    CPen *pOldPen = pDC->SelectObject(&pen);
    pDC->Ellipse(ptCenter.x-r,ptCenter.y-r,ptCenter.x+r,ptCenter.y+r);
    pDC->SelectObject(pOldPen);
    pDC->SetROP2(R2_NOT);
    pDC->MoveTo(ptCenter.x,ptCenter.y);
    pDC->LineTo(ptOnCircle.x,ptOnCircle.y);
    }
    ReleaseDC(pDC);
    }
    
    
    // 绘制矩形,ptUL: 左上,ptLR: 右下
    void CZKCADView::DrawRect(bool isRubber, CPoint ptUL, CPoint ptLR)
    {
    CDC* pDC = GetDC();
    // 设置透明画刷
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    CBrush *pOldBrush =pDC->SelectObject(pBrush);
    if(isRubber)
    {
    pDC->SetROP2(R2_NOT);
    pDC->Rectangle(ptUL.x,ptUL.y,ptLR.x,ptLR.y);
    }
    else
    {
    CPen pen(PS_SOLID,1,RGB(255,0,0));
    CPen *pOldPen = pDC->SelectObject(&pen);
    pDC->Rectangle(ptUL.x,ptUL.y,ptLR.x,ptLR.y);
    }
    
    ReleaseDC(pDC);
    }
    
    
    
    
    void CZKCADView::DrawEllipse(bool isRubber, CPoint ptUL, CPoint ptLR)
    {
    CDC* pDC = GetDC();
    // 设置透明画刷
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    CBrush *pOldBrush =pDC->SelectObject(pBrush);
    if(isRubber)
    {
    pDC->SetROP2(R2_NOT);
    pDC->Ellipse(ptUL.x,ptUL.y,ptLR.x,ptLR.y);
    }
    else
    {
    CPen pen(PS_SOLID,1,RGB(255,0,0));
    CPen *pOldPen = pDC->SelectObject(&pen);
    pDC->Ellipse(ptUL.x,ptUL.y,ptLR.x,ptLR.y);
    }
    
    ReleaseDC(pDC);
    }
    


    附件为源码及程序

    http://download.csdn.net/detail/xingkongtianyuzhao/9104257

  • 相关阅读:
    为CheckBoxList每个项目添加一张图片
    计算字符串中各个字符串出现的次数
    显示相同数字相乘的结果,直到数值大于150为止
    实例4 函数的引用调用
    嵌入式BootLoader技术内幕(二)
    实例2 关系和逻辑运算
    linux环境变量的系统设置
    嵌入式BootLoader技术内幕(三)
    supervivi的一点秘密
    Bootloader之vivi
  • 原文地址:https://www.cnblogs.com/AlexanderZhao/p/12878982.html
Copyright © 2011-2022 走看看