⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawdoc.cpp

📁 VC做的矢量画图程序!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DrawDoc.cpp : implementation of the CDrawDoc class
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <direct.h>
#include "Draw.h"
#include "tag.h"
#include "DrawDoc.h"
#include "tree.h"
#include "mainfrm.h"
#include "Drawview.h"
#include "block.h"
#include "CntrItem.h"
#include "tag.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CTree * pTree;
CPline* m_pPline;
CArc* m_pArc;
CGraphPara *p_GraphPara;	//初试化一个公用的关于图形参数的实例
//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);
extern CDrawView *p_View;
short indexColor[100];	//存储各个层的颜色号
char dqlj[60];

BOOL IsRectCross(float minx,float miny,float maxx,float maxy);
short IsRectCross(float minx,float miny,float maxx,float maxy,float x1,float y1,float x2,float y2);

//检查一个矩形是否与视图屏幕相交
//函数返回1-相交0-不相交
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
}

//0-不相交;1-第一个矩形在第二个矩形内;2-第二个矩形在第一个矩形内;3-相交
short IsRectCross(float minx,float miny,float maxx,float maxy,float x1,float y1,float x2,float y2)
{
	if(minx>x2||maxx<x1||miny>y2||maxy<y1) //两个矩形区域不相交
		return 0; //如不相交函数返回0
	else if(minx>x1&&maxx<x2&&miny>y1&&maxy<y2)	//第一个矩形在第二个矩形内
		return 1;
	else if(x1>minx&&x2<maxx&&y1>miny&&y2<maxy)	//第二个矩形在第一个矩形内
		return 2;
	else										//两个矩形相交
		return 3; //如果相交就返回1
}

//将实际坐标(x,y)转成逻辑坐标(*X,*Y)
void DPtoVP(float x,float y,int *X,int *Y)
{
	p_View->DPtoVP(x,y,X,Y);
}

//将逻辑坐标(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_WINDOW_TILE_HORZ, OnEditBlockMenu)
	ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
	ON_UPDATE_COMMAND_UI(ID_BLOCK_ADD, OnUpdateBlockAdd)
	ON_UPDATE_COMMAND_UI(ID_DRAW_TAG, OnUpdateDrawTag)
	ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnEditExit)
/*	ON_UPDATE_COMMAND_UI(ID_SELECT_WINDOW_IN, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_WINDOW_CROSS, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_WINDOW_ALL, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_CIRCLE_IN, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_CIRCLE_CROSS, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_CIRCLE_ALL, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_PLINE_IN, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_PLINE_CROSS, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_PLINE_ALL, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_SELECT_INFO, OnUpdateSelectClear)

	ON_UPDATE_COMMAND_UI(ID_GRAPH_MODIFY, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_GRAPHPARA_SET, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_RECORD_REDRAW, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_FILE_SELECT, OnUpdateRecordLink)
	ON_UPDATE_COMMAND_UI(ID_RECORD_LINK, OnUpdateRecordLink)
*/
    ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_BASEMAP_MANAGE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_SETUP, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_APP_EXIT, OnEditExit)
	ON_UPDATE_COMMAND_UI(ID_DATA_SERCHER, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_LAYER_SET, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_FORM_MANAGE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_VIEWFORM_MANAGE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_BLOCK_NEW, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_OBJECT_MANAGE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_WINDOW_CASCADE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_WINDOW_ARRANGE, OnEditDrawMenu)
	ON_UPDATE_COMMAND_UI(ID_BLOCK_INSERT, OnEditBlockMenu)
	ON_UPDATE_COMMAND_UI(ID_BLOCK_OK, OnEditBlockMenu)
	ON_UPDATE_COMMAND_UI(ID_BLOCK_CANCEL, OnEditBlockMenu)
	ON_UPDATE_COMMAND_UI(ID_SELECT_DELETE, OnUpdateSelectClear)

	ON_UPDATE_COMMAND_UI(ID_EDIT_MOVE, OnUpdateSelectClear)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateSelectClear)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateSelectClear)
	ON_UPDATE_COMMAND_UI(ID_OLE_INSERT_NEW, OnEditBlockMenu)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
	//}}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=2000;	//规定可以进行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";

//	getcwd(dqlj,30);	//得到当前路径
//	FileName="draw1.tmp";
	Fundo.Open(FileName,CFile::modeCreate|CFile::modeReadWrite|CFile::typeBinary);
	RunTimes++;
	n_CurUnIndex=0;		//当前的逆操作序号为0
	EnableCompoundFile();
	m_Index=new int[20000];
	BlockIndex=-1;
	for(int i=0;i<10;i++)
		GraphNumbStart[i]=0;
	p_Block=NULL;
	x_Insert=0;
	y_Insert=0;
	m_DrawEdit=0;			//进行普通的图形绘制
	m_MaxScreen=1000;		//最多能够记录在100个历史屏幕
	m_Screen=new ScreenStruct[m_MaxScreen];//给记录历史屏幕的数组分配空间
	m_CurrentScreen=0;
	m_CurrentScreen1=0;
	m_Screen[0].sx=0;
	m_Screen[0].sy=0;
	m_Screen[0].blc=1.0;
	m_BasemapNumb=0;		//底图的数目为0
}

//析构函数
CDrawDoc::~CDrawDoc()
{
	delete m_Screen;
	delete GraphSelect;
	delete m_UndoList;
	delete m_Index;
	Fundo.Close();
	remove(FileName);
}

//得到指向某个图形元素对象的指针
//LB-表示图形元素类别,Index-表示图形元素的序号
CDraw * CDrawDoc::GetGraph(short Lb,int Index)
{
	switch(Lb)
	{
	case 1:		//如果是直线
		if(Index<0||Index>m_LineArray.GetUpperBound())
			return 0;
		return m_LineArray.GetAt(Index);
		break;
	case 2:		//如果是连续直线
		if(Index<0||Index>m_PLineArray.GetUpperBound())
			return 0;
		return m_PLineArray.GetAt(Index);
		break;
	case 3:		//如果是圆
		if(Index<0||Index>m_CircleArray.GetUpperBound())
			return 0;
		return m_CircleArray.GetAt(Index);
		break;
	case 4:		//如果是圆弧
		if(Index<0||Index>m_ArcArray.GetUpperBound())
			return 0;
		return m_ArcArray.GetAt(Index);
		break;
	case 5:		//如果是标注文本
		if(Index<0||Index>m_TextArray.GetUpperBound())
			return 0;
		return m_TextArray.GetAt(Index);
		break;
	case 6:		//如果是图例
		if(Index<0||Index>m_TagArray.GetUpperBound())
			return 0;
		return (CDraw *)m_TagArray.GetAt(Index);
	case 7:		//如果是表格域
		if(Index<0||Index>m_FormrgnArray.GetUpperBound())
			return 0;
		return (CDraw *)m_FormrgnArray.GetAt(Index);
	default:
		return 0;
	}
}

//绘制选中的图形元素
//Lb-图形类别 Index-绘制图形的序列号 Mode-绘制覆盖模式 Mode1-绘制方式
void CDrawDoc::DrawGraph(CDC* pDC,int Lb,int Index,int Mode,int Mode1,short BackColor)
{
	GetGraph(Lb,Index)->Draw(pDC,Mode,Mode1,BackColor);
}

//所有图形元素的绘制函数,被CDrawView::OnDraw函数调用
void CDrawDoc::Draw(CDC *pDC,int m_DrawMode,int m_DrawMode1,short BackColor)
{
	int x1,y1;
	for(int i=1;i<=7;i++)	//对7类图形元素循环
	{
		int nn=GetGraphUpperBound(i)+1;	//得到图形元素的数目	
		while(b_Draw&&nn-->GraphNumbStart[i-1])	
			GetGraph(i,nn)->Draw(pDC,m_DrawMode,m_DrawMode1,BackColor);
	}
	for(i=0;i<n_GraphSelect;i++)	//特殊显示选中的图形元素
		DrawGraph(pDC,GraphSelect[i].Lb,GraphSelect[i].Index,1,1,RGB(0,0,0));//BackColor);
	if(m_DrawEdit==1||m_DrawEdit==2)	//如果在编辑图形块
	{
		CPen pen(0,1,p_GraphPara->GetColor(1));
		CPen* pOldPen=pDC->SelectObject(&pen);
		pDC->SetROP2(R2_COPYPEN);//设定覆盖的绘制模式
		DPtoVP(x_Insert,y_Insert,&x1,&y1);		
		pDC->SelectStockObject(NULL_BRUSH);		//设置不填充状态
		pDC->Ellipse(x1-4,y1-4,x1+4,y1+4);		//绘制圆(图例插入点)
		//以下绘制一个十字
		pDC->MoveTo(x1-4,y1);
		pDC->LineTo(x1+4,y1);
		pDC->MoveTo(x1,y1-4);
		pDC->LineTo(x1,y1+4);
		pDC->SelectObject(pOldPen);    //恢复画笔
	}
}

//得到各类图形元素的数目。Lb-图形元素类别
int CDrawDoc::GetGraphNumb(short Lb)
{
	switch(Lb)
	{
	case 1:		//如果是直线
		return m_LineArray.GetSize();
		break;
	case 2:		//如果是连续直线
		return m_PLineArray.GetSize();
		break;
	case 3:		//如果是圆
		return m_CircleArray.GetSize();
		break;
	case 4:		//如果是圆弧
		return m_ArcArray.GetSize();
		break;
	case 5:		//如果是标注文本
		return m_TextArray.GetSize();
		break;
	case 6:		//如果是图例
		return m_TagArray.GetSize();
		break;
	case 7:		//如果是表格域
		return m_FormrgnArray.GetSize();
		break;
	default:
		return 0;
	}
}

//得到存储各个图形元素对象数组的最大上标,Lb-图形元素类别
int CDrawDoc::GetGraphUpperBound(short Lb)
{
	switch(Lb)
	{
	case 1:		//如果是直线
		return m_LineArray.GetUpperBound();
		break;
	case 2:		//如果是连续直线
		return m_PLineArray.GetUpperBound();
		break;
	case 3:		//如果是圆
		return m_CircleArray.GetUpperBound();
		break;
	case 4:		//如果是圆弧
		return m_ArcArray.GetUpperBound();
		break;
	case 5:		//如果是标注文本
		return m_TextArray.GetUpperBound();
		break;
	case 6:		//如果是图例
		return m_TagArray.GetUpperBound();
		break;
	case 7:		//如果是表格域
		return m_FormrgnArray.GetUpperBound();
		break;
	}
	return -1;
}

//得到在各类图形元素中增加一个图形元素时的唯一识别号
//参数:Lb-图形元素类别
int CDrawDoc::GetGraphID(short Lb)
{
	int nn=GetGraphUpperBound(Lb);	//得到存储图形元素对象数组的上标
	for(int i=0;i<20000;i++)
		m_Index[i]=0;
	for(i=0;i<=nn;i++)
	{
		if(GetGraph(Lb,i))
			m_Index[GetGraph(Lb,i)->GetID()]=1;
	}
	for(i=0;i<20000;i++)
	{
		if(m_Index[i]==0)
			return i;
	}
	return -1;
}

//删除某个图形元素,Lb-图形元素类别,Index-图形元素的存储序号
void CDrawDoc::DeleteGraph(short Lb,int Index)
{
	switch(Lb)
	{
	case 1:		//如果是直线
		if(Index<0||Index>m_LineArray.GetUpperBound())
			return;
		m_LineArray.RemoveAt(Index);
		break;
	case 2:		//如果是连续直线
		if(Index<0||Index>m_PLineArray.GetUpperBound())
			return;
		m_PLineArray.RemoveAt(Index);
		break;
	case 3:		//如果是圆
		if(Index<0||Index>m_CircleArray.GetUpperBound())
			return;
		m_CircleArray.RemoveAt(Index);
		break;
	case 4:		//如果是圆弧
		if(Index<0||Index>m_ArcArray.GetUpperBound())
			return;
		m_ArcArray.RemoveAt(Index);
		break;
	case 5:		//如果是标注文本
		if(Index<0||Index>m_TextArray.GetUpperBound())
			return;
		m_TextArray.RemoveAt(Index);
		break;
	case 6:		//如果是图例
		if(Index<0||Index>m_TagArray.GetUpperBound())
			return;
		m_TagArray.RemoveAt(Index);
		break;
	case 7:		//如果是表格域
		if(Index<0||Index>m_FormrgnArray.GetUpperBound())
			return;
		m_FormrgnArray.RemoveAt(Index);
		break;
	default:
		return;
	}
	return;
}


BOOL CDrawDoc::OnNewDocument()
{
	if (!COleDocument::OnNewDocument())
		return FALSE;
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc serialization

//文档类的串行化函数
void CDrawDoc::Serialize(CArchive& ar)
{
	int id,i;
	if (ar.IsStoring())
	{
		for(i=1;i<=6;i++) //对6类图形元素循环,删除做了删除标志的图形元素
		{
			int nn=GetGraphUpperBound(i)+1;
			while(nn--)
			{
				if(GetGraph(i,nn)->IsDelete())	//如果图形元素处于删除状态
				{	
					id=GetGraph(i,nn)->GetID();	//得到图形元素的唯一识别号	
					delete GetGraph(i,nn);		//删除图形元素对象
					DeleteGraph(i,nn);			//在存储图形元素的对象中删除图形元素对象指针
				}
			}
		}
		ar<<m_BasemapNumb;
		for(i=0;i<m_BasemapNumb;i++)
			m_Basemap[i].Serialize(ar);
	}
	else
	{
		ar>>m_BasemapNumb;
		for(i=0;i<m_BasemapNumb;i++)
			m_Basemap[i].Serialize(ar);
	}
	m_GraphPara.Serialize(ar);
	m_LineArray.Serialize(ar);
	m_PLineArray.Serialize(ar);
	m_CircleArray.Serialize(ar);
	m_ArcArray.Serialize(ar);
	m_TextArray.Serialize(ar);
	m_BlockArray.Serialize(ar);
	m_TagArray.Serialize(ar);
	if(!ar.IsStoring())	//如果是读取操作,设置图例指向的图形块
		SetBlockPoint();
	n_CurUnIndex=0;
//	SetModifiedFlag(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::AddLine(CLine* pLine)
{
	m_LineArray.Add(pLine);
	return pLine;
}


//增加一个连续直线对象
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::AddPLine(CPline* pPline)
{
	m_PLineArray.Add(pPline);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -