drawDoc.cpp
上传用户:y440e3
上传日期:2010-03-08
资源大小:200k
文件大小:75k
- // DrawDoc.cpp : implementation of the CDrawDoc class
- //
- #include <float.h>
- #include "stdafx.h"
- #include "Draw.h"
- #include <float.h>
- #include <math.h>
- #include "DrawDoc.h"
- #include "Drawview.h"
- #include "CntrItem.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CGraphPara *p_GraphPara; //初试化一个公用的关于图形参数的实例
- extern CDrawView *p_View;
- extern CMemFile pFile;
- float xMinScreen,yMinScreen,xMaxScreen,yMaxScreen;
- int RunTimes=0;
- extern BOOL b_Draw;
- void DPtoVP(float x,float y,int *X,int *Y);
- void VPtoDP(int x,int y,float *X,float *Y);
- int DLtoVL(float l);
- float VLtoDL(int l);
- BOOL IsRectCross(float minx,float miny,float maxx,float maxy);
- BOOL IsRectCross(float minx,float miny,float maxx,float maxy)
- {
- if(minx>xMaxScreen||maxx<xMinScreen||miny>yMaxScreen||maxy<yMinScreen) //两个矩形区域不相交
- return 0; //如不相交函数返回0
- else
- return 1; //如果相交就返回1
- }
- void DPtoVP(float x,float y,int *X,int *Y)
- {
- p_View->DPtoVP(x,y,X,Y);
- }
- void VPtoDP(int x,int y,float *X,float *Y)
- {
- p_View->VPtoDP(x,y,X,Y);
- }
-
- int DLtoVL(float l)
- {
- return p_View->DLtoVL(l);
- }
- float VLtoDL(int l)
- {
- return p_View->VLtoDL(l);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc
- IMPLEMENT_DYNCREATE(CDrawDoc, COleDocument)
- BEGIN_MESSAGE_MAP(CDrawDoc, COleDocument)
- //{{AFX_MSG_MAP(CDrawDoc)
- ON_UPDATE_COMMAND_UI(ID_SELECT_CLEAR, OnUpdateSelectClear)
- ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
- ON_UPDATE_COMMAND_UI(ID_SELECT_DELETE, OnUpdateSelectClear)
- ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateSelectClear)
- ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateSelectClear)
- ON_COMMAND(IDC_TEST, OnTest)
- //}}AFX_MSG_MAP
- // Enable default OLE container implementation
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, COleDocument::OnUpdatePasteMenu)
- ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, COleDocument::OnUpdatePasteLinkMenu)
- ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, COleDocument::OnUpdateObjectVerbMenu)
- ON_COMMAND(ID_OLE_EDIT_CONVERT, COleDocument::OnEditConvert)
- ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, COleDocument::OnUpdateEditLinksMenu)
- ON_COMMAND(ID_OLE_EDIT_LINKS, COleDocument::OnEditLinks)
- ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, COleDocument::OnUpdateObjectVerbMenu)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc construction/destruction
- CDrawDoc::CDrawDoc()
- {
- b_IsOleSelect=0;
- p_GraphPara=&m_GraphPara; //将公用的GraphPara类的指针指向当前文档的GraphPara对象
- n_GraphSelect=0;
- GraphSelect=new GraphSelectStruct[2000]; //最多可选中2000个图形元素
- n_MaxUnIndex=10000; //规定可以进行1万步的逆操作
- m_UndoList=new UndoStruct[n_MaxUnIndex];
- m_UndoList[0].l_Start=0;
- char p1[4];
- sprintf(p1,"%d",RunTimes);
- FileName="c:\draw";
- FileName+=p1;
- FileName+=".tmp";
- Fundo.Open(FileName,CFile::modeCreate|CFile::modeReadWrite|CFile::typeBinary);
- RunTimes++;
- n_CurUnIndex=0; //当前的逆操作序号为0
- EnableCompoundFile();
- m_Index=new int[20000];
- m_MaxScreen=1000; //最多能够记录在100个历史屏幕
- m_Screen=new ScreenStruct[m_MaxScreen];//给记录历史屏幕的数组分配空间
- //以下设置首屏的参数并将目前屏幕设置为首屏
- m_CurrentScreen=0;
- m_Screen[0].sx=0;
- m_Screen[0].sy=0;
- m_Screen[0].blc=1;
-
- strcpy(DataInfo[0].Name,"城市信息");
- DataInfo[0].only_ID=1;
- strcpy(DataInfo[1].Name,"连接信息");
- DataInfo[1].only_ID=2;
- m_NumbData=2;
- }
- CDrawDoc::~CDrawDoc()
- {
- delete GraphSelect;
- delete m_UndoList;
- delete m_Index;
- delete m_Screen;
- Fundo.Close();
- remove(FileName);
- }
- //绘制选中的图形元素
- //Lb-图形类别 Index-绘制图形的序列号 Mode-绘制覆盖模式 Mode1-绘制方式
- void CDrawDoc::DrawGraph(CDC* pDC,int Lb,int Index,int Mode,int Mode1,short BackColor)
- {
- if(Lb==1) //如果是直线
- GetLine(Index)->Draw(pDC,Mode,Mode1,BackColor);
- else if(Lb==2) //如果是连续直线
- GetPLine(Index)->Draw(pDC,Mode,Mode1,BackColor);
- else if(Lb==3) //如果圆
- GetCircle(Index)->Draw(pDC,Mode,Mode1,BackColor);
- else if(Lb==4) //如果是圆弧
- GetArc(Index)->Draw(pDC,Mode,Mode1,BackColor);
- else if(Lb==5) //如果是标注文字
- GetText(Index)->Draw(pDC,Mode,Mode1,BackColor);
- }
- void CDrawDoc::Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)
- {
- int nn=GetNumbLines();//得到直线的数目
- while(b_Draw&&nn--) //绘制所有直线
- GetLine(nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
- nn=GetNumbPLines(); //得到连续直线和多边形区域数目
- while(b_Draw&&nn--) //绘制所有连续直线和多边形区域
- GetPLine(nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
- nn=GetNumbCircles(); //得到圆的数目
- while(b_Draw&&nn--) //绘制所有圆
- GetCircle(nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
- nn=GetNumbArcs(); //得到圆弧的数目
- while(b_Draw&&nn--) //绘制所有圆弧
- GetArc(nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
- nn=GetNumbTexts(); //得到文本的数目
- while(b_Draw&&nn--) //绘制所有文本
- GetText(nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
- for(int i=0;i<n_GraphSelect;i++)
- DrawGraph(pDC,GraphSelect[i].Lb,GraphSelect[i].Index,0,1,BackColor);
- }
- BOOL CDrawDoc::OnNewDocument()
- {
- if (!COleDocument::OnNewDocument())
- return FALSE;
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc serialization
- /*
- void CDrawDoc::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- // TODO: add storing code here
- }
- else
- {
- //line1=new CLine (0,0,0,0,0,0,0,0,100,100);
- // ar>>line1;
- // TODO: add loading code here
- }
- int nn=m_LineArray.GetSize();
- while(nn--)
- {
- if(m_LineArray.GetAt(nn)->IsDelete())
- {
- delete m_LineArray.GetAt(nn);
- m_LineArray.RemoveAt(nn);
- }
- }
- nn=m_PLineArray.GetSize();
- while(nn--)
- {
- if(m_PLineArray.GetAt(nn)->IsDelete())
- {
- delete m_PLineArray.GetAt(nn);
- m_PLineArray.RemoveAt(nn);
- }
- }
- nn=m_CircleArray.GetSize();
- while(nn--)
- {
- if(m_CircleArray.GetAt(nn)->IsDelete())
- {
- delete m_CircleArray.GetAt(nn);
- m_CircleArray.RemoveAt(nn);
- }
- }
- nn=m_ArcArray.GetSize();
- while(nn--)
- {
- if(m_ArcArray.GetAt(nn)->IsDelete())
- {
- delete m_ArcArray.GetAt(nn);
- m_ArcArray.RemoveAt(nn);
- }
- }
- nn=m_TextArray.GetSize();
- while(nn--)
- {
- if(m_TextArray.GetAt(nn)->IsDelete())
- {
- delete m_TextArray.GetAt(nn);
- m_TextArray.RemoveAt(nn);
- }
- }
- m_LineArray.Serialize(ar);
- m_PLineArray.Serialize(ar);
- m_CircleArray.Serialize(ar);
- m_ArcArray.Serialize(ar);
- m_TextArray.Serialize(ar);
- n_CurUnIndex=0;
- SetModifiedFlag(0);
- // Calling the base class COleDocument enables serialization
- // of the container document's COleClientItem objects.
- COleDocument::Serialize(ar);
- }
- */
- void CDrawDoc::Serialize(CArchive& ar)
- {
- CFile *file1;
- int n_LineNumb,n_PLineNumb,n_CircleNumb,n_ArcNumb,n_TextNumb;
- file1=ar.GetFile();
- if (ar.IsStoring())
- {
- int nn=m_LineArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_LineArray.GetAt(nn)->IsDelete())
- {
- delete m_LineArray.GetAt(nn);
- m_LineArray.RemoveAt(nn);
- }
- }
- nn=m_PLineArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_PLineArray.GetAt(nn)->IsDelete())
- {
- delete m_PLineArray.GetAt(nn);
- m_PLineArray.RemoveAt(nn);
- }
- }
- nn=m_CircleArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_CircleArray.GetAt(nn)->IsDelete())
- {
- delete m_CircleArray.GetAt(nn);
- m_CircleArray.RemoveAt(nn);
- }
- }
- nn=m_ArcArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_ArcArray.GetAt(nn)->IsDelete())
- {
- delete m_ArcArray.GetAt(nn);
- m_ArcArray.RemoveAt(nn);
- }
- }
- nn=m_TextArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_TextArray.GetAt(nn)->IsDelete())
- {
- delete m_TextArray.GetAt(nn);
- m_TextArray.RemoveAt(nn);
- }
- // TODO: add storing code here
- }
- n_LineNumb=m_LineArray.GetSize();
- n_PLineNumb=m_PLineArray.GetSize();
- n_CircleNumb=m_CircleArray.GetSize();
- n_ArcNumb=m_ArcArray.GetSize();
- n_TextNumb=m_TextArray.GetSize();
- file1->Write((unsigned char *)&n_LineNumb,sizeof(int));
- file1->Write((unsigned char *)&n_PLineNumb,sizeof(int));
- file1->Write((unsigned char *)&n_CircleNumb,sizeof(int));
- file1->Write((unsigned char *)&n_ArcNumb,sizeof(int));
- file1->Write((unsigned char *)&n_TextNumb,sizeof(int));
- if(n_LineNumb>0)
- {
- nn=m_LineArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_LineArray.GetAt(nn))
- GetLine(nn)->Save(file1,1);
- }
- }
- if(n_PLineNumb>0)
- {
- nn=m_PLineArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_PLineArray.GetAt(nn))
- GetPLine(nn)->Save(file1,1);
- }
- }
- if(n_CircleNumb>0)
- {
- nn=m_CircleArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_CircleArray.GetAt(nn))
- GetCircle(nn)->Save(file1,1);
- }
- }
- if(n_ArcNumb>0)
- {
- nn=m_ArcArray.GetUpperBound()+1;
- while(nn--)
- {
- if(m_ArcArray.GetAt(nn))
- GetArc(nn)->Save(file1,1);
- }
- }
- if(n_TextNumb>0)
- {
- nn=m_TextArray.GetUpperBound();
- while(nn--)
- {
- if(m_TextArray.GetAt(nn))
- GetText(nn)->Save(file1,1);
- }
- }
- }
- else
- {
- file1->Read((unsigned char *)&n_LineNumb,sizeof(int));
- file1->Read((unsigned char *)&n_PLineNumb,sizeof(int));
- file1->Read((unsigned char *)&n_CircleNumb,sizeof(int));
- file1->Read((unsigned char *)&n_ArcNumb,sizeof(int));
- file1->Read((unsigned char *)&n_TextNumb,sizeof(int));
- for(int i=0;i<n_LineNumb;i++)
- {
- CLine* p_Line=new CLine();
- p_Line->Save(file1,0);
- m_LineArray.Add(p_Line);
- }
- for(i=0;i<n_PLineNumb;i++)
- {
- CPline* p_PLine=new CPline();
- p_PLine->Save(file1,0);
- m_PLineArray.Add(p_PLine);
- }
- for(i=0;i<n_CircleNumb;i++)
- {
- CCircle* p_Circle=new CCircle();
- p_Circle->Save(file1,0);
- m_CircleArray.Add(p_Circle);
- }
- for(i=0;i<n_ArcNumb;i++)
- {
- CArc* p_Arc=new CArc();
- p_Arc->Save(file1,0);
- m_ArcArray.Add(p_Arc);
- }
- for(i=0;i<n_TextNumb;i++)
- {
- CText* p_Text=new CText();
- p_Text->Save(file1,0);
- m_TextArray.Add(p_Text);
- }
-
- // TODO: add loading code here
- }
- SetModifiedFlag(0);
- n_CurUnIndex=0;
- COleDocument::Serialize(ar);
- }
- CLine* CDrawDoc::AddLine(short ColorPen,short ColorBrush,short LineWide,short LineType,short Layer,int id_only,float X1,float Y1,float X2,float Y2)
- {
- CLine* p_Line=new CLine(ColorPen,ColorBrush,LineWide,LineType,Layer,id_only,0,X1,Y1,X2,Y2);
- m_LineArray.Add(p_Line);
- return p_Line;
- }
- CLine* CDrawDoc::AddLine()
- {
- CLine* p_Line=new CLine();
- m_LineArray.Add(p_Line);
- return p_Line;
- }
- CLine * CDrawDoc::GetLine(int Index)
- {
- if(Index<0||Index>m_LineArray.GetUpperBound())
- return 0;
- return m_LineArray.GetAt(Index);
- }
- int CDrawDoc::GetNumbLines()
- {
- return m_LineArray.GetSize();
- }
- CPline* CDrawDoc::AddPLine(short ColorPen,short ColorBrush,short LineWide,short LineType,short Layer,int id_only,int Numble,PointStruct* PointList,BOOL Fill)
- {
- CPline* p_Pline=new CPline(ColorPen,ColorBrush,LineWide,LineType,Layer,id_only,0,Numble,PointList,Fill);
- m_PLineArray.Add(p_Pline);
- return p_Pline;
- }
- CPline* CDrawDoc::AddPLine()
- {
- CPline* p_Pline=new CPline();
- m_PLineArray.Add(p_Pline);
- return p_Pline;
- }
- CPline* CDrawDoc::GetPLine(int Index)
- {
- if(Index<0||Index>m_PLineArray.GetUpperBound())
- return 0;
- return m_PLineArray.GetAt(Index);
- }
- int CDrawDoc::GetNumbPLines()
- {
- return m_PLineArray.GetSize();
- }
- CCircle* CDrawDoc::AddCircle(short ColorPen,short ColorBrush,short LineWide,short LineType,short Layer,int id_only,float CircleX,float CircleY,float CircleR,BOOL Fill)
- {
- CCircle* p_Circle=new CCircle(ColorPen,ColorBrush,LineWide,LineType,Layer,id_only,0,CircleX,CircleY,CircleR,Fill);
- m_CircleArray.Add(p_Circle);
- return p_Circle;
- }
- CCircle* CDrawDoc::AddCircle()
- {
- CCircle* p_Circle=new CCircle();
- m_CircleArray.Add(p_Circle);
- return p_Circle;
- }
- CCircle* CDrawDoc::GetCircle(int Index)
- {
- if(Index<0||Index>m_CircleArray.GetUpperBound())
- return 0;
- return m_CircleArray.GetAt(Index);
- }
- int CDrawDoc::GetNumbCircles()
- {
- return m_CircleArray.GetSize();
- }
- CArc* CDrawDoc::AddArc(short ColorPen,short ColorBrush,short LineWide,short LineType,short Layer,int id_only,float CircleX,float CircleY,float CircleR,BOOL Fill,float Angle1,float Angle2)
- {
- CArc* p_Arc=new CArc(ColorPen,ColorBrush,LineWide,LineType,Layer,id_only,0,CircleX,CircleY,CircleR,Fill,Angle1,Angle2);
- m_ArcArray.Add(p_Arc);
- return p_Arc;
- }
- CArc* CDrawDoc::AddArc()
- {
- CArc* p_Arc=new CArc();
- m_ArcArray.Add(p_Arc);
- return p_Arc;
- }
- int CDrawDoc::GetNumbArcs()
- {
- return m_ArcArray.GetSize();
- }
- CText* CDrawDoc::AddText(short ColorPen,short ColorBrush,short LineWide,short LineType,short Layer,int id_only,float StartX,float StartY,float Angle1,float Angle2,float TextHeight,float TextWide,float OffWide,unsigned char TextFont,int TextLong,CString Text)
- {
- CText* p_Text=new CText(ColorPen,ColorBrush,LineWide,LineType,Layer,id_only,0,StartX,StartY,Angle1,Angle2,TextHeight,TextWide,OffWide,0,Text);
- m_TextArray.Add(p_Text);
- return p_Text;
- }
- CText* CDrawDoc::AddText()
- {
- CText* p_Text=new CText();
- m_TextArray.Add(p_Text);
- return p_Text;
- }
- CText* CDrawDoc::GetText(int Index)
- {
- if(Index<0||Index>m_TextArray.GetUpperBound())
- return 0;
- return m_TextArray.GetAt(Index);
- }
- int CDrawDoc::GetNumbTexts()
- {
- return m_TextArray.GetSize();
- }
- //在历史屏幕中增加一个屏幕,以供屏幕回溯操作
- //(StartX,StartY)屏幕起点,blc为屏幕的比例尺
- void CDrawDoc::AddScreen(float StartX,float StartY,float blc)
- {
- int i;
- if(m_CurrentScreen==m_MaxScreen)//如果当前屏幕在50屏上,即没有数组空间再存信息
- {
- //将数组做堆式滚动将第二屏去掉(screenxy[0]中存储的是首屏信息,操作时不改变)
- for(i=1;i<m_MaxScreen-1;i++)
- m_Screen[i]=m_Screen[i+1];
- }
- else //如果不是最大屏,屏幕记录号增加1
- m_CurrentScreen++;
- //记录下本屏幕的参数
- m_Screen[m_CurrentScreen].sx=StartX;
- m_Screen[m_CurrentScreen].sy=StartY;
- m_Screen[m_CurrentScreen].blc=blc;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDrawDoc diagnostics
- #ifdef _DEBUG
- void CDrawDoc::AssertValid() const
- {
- COleDocument::AssertValid();
- }
- void CDrawDoc::Dump(CDumpContext& dc) const
- {
- COleDocument::Dump(dc);
- }
- #endif //_DEBUG
- COLORREF CGraphPara::GetColor(int n)
- {
- return m_ColorList[n]; //返回第n种颜色的实际值
- }
- BOOL CGraphPara::GetDisplayStatue(int n)
- {
- return m_LayerList[n].b_Display;
- }
- //计算点(x1,y1)与点(x2,y2)间的距离
- float CDraw::CalDisp(float x1,float y1,float x2,float y2)
- {
- return (float)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
- }
- //作用:计算点(xx,yy)到线段(x1,y1)(x2,y2)的距离,返回计算的距离值
- float CDraw::PointLine(float xx,float yy,float x1,float y1,float x2,float y2)
- {
- float a,b,c,ang1,ang2,ang;
- //计算三条边的距离
- a=CalDisp(x1,y1,xx,yy);if(a==0.0)return 0.0;
- b=CalDisp(x2,y2,xx,yy);if(b==0.0)return 0.0;
- c=CalDisp(x1,y1,x2,y2);
- //如果(x1,y1)和(x2,y2)是一个点直接返回距离
- if(c==0.0) return a;
- if(a<b) //如果(xx,yy)的点(x1,y1)这条边较短
- {
- if(y1==y2)
- {
- if(x1<x2)
- ang1=0;
- else
- ang1=(float)pi;
- }
- else
- {
- ang1=(float)acos((x2-x1)/c);
- if(y1>y2)ang1=(float)pi*2-ang1; //直线(x1,y1)-(x2,y2)的弧度
- }
- ang2=(float)acos((xx-x1)/a);
- if(y1>yy)ang2=(float)pi*2-ang2; //直线(x1,y1)-(xx,yy)的弧度
- ang=ang2-ang1;
- if(ang<0)ang=-ang;
- if(ang>pi) ang=(float)pi*2-ang; //交角的大小
- if(ang>pi/2) return a; //如果为钝角,直接返回距离
- else
- return (a*(float)sin(ang)); //否则返回计算得到的距离
- }
- else //如果(xx,yy)的点(x2,y2)这条边较短
- {
- if(y1==y2)
- {
- if(x1<x2)
- ang1=(float)pi;
- else
- ang1=0;
- }
- else
- {
- ang1=(float)acos((x1-x2)/c); //直线(x2,y2)-(x1,y1)的斜率的弧度
- if(y2>y1)ang1=(float)pi*2-ang1;
- }
- ang2=(float)acos((xx-x2)/b); //直线(x2,x1)-(xx,yy)的斜率的弧度
- if(y2>yy)ang2=(float)pi*2-ang2;
- ang=ang2-ang1;
- if(ang<0) ang=-ang;
- if(ang>pi) ang=(float)pi*2-ang; //交角的大小