在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

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值