这段时间学习了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