MFC绘图_基本图形绘制

其实这部分才是我最先学习MFC的部分,这里给出代码与原理,先看一下结果图(分别是绘点、绘线、绘面、绘注记):


MFC学习-绘图-图形绘制

首先说下MFC绘制图形,要写在项目view.cpp的ondraw里,得到pDC,或者用其他方法,如GetDC。
若要实现窗口变动图形仍在,就要给各个图像创建类来存储各个图形,然后根据存储的数据重绘图形。
(1)绘点:

struct PointFeature : public CObject
{
int      ID;
float    x,y;
int      radio;
COLORREF color;
public:
//重绘时候调用
void draw(DrawContext *drawContext);
};
这里用结构体或者用类存储数据都是可以的

把代码写在view的消息void CGISView::OnLButtonDown(UINT nFlags, CPoint point)中:

PointFeature *pointFeature = new PointFeature();
pointFeature->x = point.x;
pointFeature->y = point.y;
pointFeature->color = RGB(255,0,0);
pointFeature->radio = 5;
pointFeature->ID = activeLayer->pointFeatures.GetSize()+1;
//接之前的图层博客,这里指把点存在了当前图层中
activeLayer->pointFeatures.Add(pointFeature);
这里是之前提到的draw,自己定义的函数

void PointFeature::draw(DrawContext *drawContext)
{
CDC *pDC=drawContext->pDC;
CPoint *pM=new CPoint();
//结构体自身的
pM->x=x;
pM->y=y;
CRect r(pM->x - radio,pM->y - radio,pM->x + radio,pM->y + radio);
CPen *newPen = new CPen(PS_SOLID,1,this->color);
CPen *oldPen = pDC->SelectObject(newPen);
pDC->Ellipse(&r);
pDC->SelectObject(oldPen);
delete newPen;
CString str;
str.Format("%d",ID);
pDC->TextOut(pM->x+5,pM->y-5,str);
delete pM;
}
另外,别忘记写个for,把cobarray中所有点都draw一下,代码就不贴了。
(2)绘线:
首先在view.h中加入
 //记录鼠标左键按下的次数
int nDownNum; 
另外在加线的按钮里加入:
activeLine = new LineFeature();
activeLine->color=RGB(0,0,255);
activeLine->lineWidth=2;
struct LineFeature : public CObject
{
int      ID;
CObArray points;
int      lineWidth;
COLORREF color;
public:
~LineFeature();
void draw(DrawContext *drawContext);
};
把下面代码写在LButtonDown里:
if(activeLine != NULL)
{
CPoint *p = new CPoint();
p->x = point.x;
p->y = point.y;
activeLine->points.Add((CObject*)p);
}
startPt=point1;
endPt  =point1;
把下面代码写在OnRButtonDown里

CPoint *p = new CPoint();
p->x = point.x;
p->y = point.y;
activeLine->points.Add((CObject*)p);
if(activeLine->points.GetSize()>1)
{
activeLayer->lineFeatures.Add(activeLine);
activeLine = new LineFeature();
activeLine->color=RGB(0,0,255);
activeLine->lineWidth=2;
}
nDownNum=0;
把下面代码写在OnLButtonDblClk里
规定的双击时间限制之内再次按下鼠标左键时结束画线,和上面点击右键作用一样
CPoint *p = new CPoint();
p->x = point.x;
p->y = point.y;
activeLine->points.Add((CObject*)p);
if(activeLine->points.GetSize()>1)
{
activeLayer->lineFeatures.Add(activeLine);
activeLine = new LineFeature();
activeLine->color=RGB(0,0,255);
activeLine->lineWidth=2;
}
nDownNum=0;
//绘制
void LineFeature::draw(DrawContext *drawContext)
{
CDC *pDC=drawContext->pDC;
//线颜色、线型
CPen pen(PS_SOLID,lineWidth,color); 
CPen *pOldPen=pDC->SelectObject(&pen);
int num=points.GetSize();
if(num>1)
{   
CPoint *pPts=new CPoint[num];
for(int i=0 ; i< num;i++)
{
//这里是新内容,作用是不同放大缩小系数时,保持比例不便。
PMtoPV((CPoint *)points.GetAt(i),&pPts[i],drawContext);
}
pDC->Polyline(pPts,num);
pDC->SelectObject(pOldPen);
delete pPts;
}
}
上述只是实现了绘制,但是并没有“实时”的效果,这里给出“橡皮条”效果的代码(绘线和绘面对于“橡皮条的代码相同):
<pre name="code" class="cpp">if(nDownNum)
{
CClientDC dc(this);
CPen pNewPen(PS_SOLID,1,RGB(0,255,255));  
CPen* pOldPen=(CPen*)dc.SelectObject(&pNewPen);
<pre name="code" class="cpp">//设置反色,橡皮条的核心
 
dc.SetROP2(R2_XORPEN);
//第一次绘制反色,第二次是显示,然后每次把原来的抹去。
dc.MoveTo(startPt);
dc.LineTo(endPt);
dc.MoveTo(startPt);
dc.LineTo(point);
endPt=point;
}
 (3)绘面: 

struct AreaFeature : public CObject
{
int      ID;
CObArray points;
int      borderLineWidth;
COLORREF borderLineColor;
COLORREF fillColor;
public:
void draw(DrawContext *drawContext);
};
void AreaFeature::draw(DrawContext *drawContext)
{
CDC *pDC=drawContext->pDC;
int num=points.GetSize();
if(num>1)
{
CPoint *pPts=new CPoint[num];
for(int i=0 ; i< num;i++)
{
PMtoPV((CPoint *)points.GetAt(i),&pPts[i],drawContext);
}
CPen pen(PS_SOLID,borderLineWidth,borderLineColor); 
CBrush brush(fillColor);
CPen *pOldPen=pDC->SelectObject(&pen);
CBrush *pOldBrush=pDC->SelectObject(&brush);
pDC->Polygon(pPts,num);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
delete pPts;
}
}
(4)注记就十分类似,直接给出核心了:
void AnnoteFeature::draw(DrawContext *drawContext)
{
CDC *pDC=drawContext->pDC;
CPoint *pM=new CPoint();
pM->x=x;
pM->y=y;
CPoint *pV=new CPoint();
PMtoPV(pM,pV,drawContext);
pDC->TextOut(pV->x,pV->y,annote);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值