drawview.cpp
来自「VC做的矢量画图程序!」· C++ 代码 · 共 2,000 行 · 第 1/5 页
CPP
2,000 行
// DrawView.cpp : implementation of the CDrawView class
//
#include "stdafx.h"
#include "Draw.h"
#include <float.h>
#include <math.h>
#include "DrawDoc.h"
#include "CntrItem.h"
#include "DrawView.h"
#include "TextWDlg.h"
#include "mainfrm.h"
#include "browseDlg.h"
//#include "winresrc.h"
#include <afxwin.h>
#include "tag.h"
#include <windowsx.h>
#include "Tree.h"
#include "graphpa.h"
#include "bmapdlg.h"
#include "mmsystem.h"
#include "linedlg.h"
#include "LengthDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CBrowseDlg * pBrowseDlg;
extern CTree * pTree;
extern CPline* m_pPline;
extern CArc* m_pArc;
extern CGraphPara *p_GraphPara; //初试化一个公用的关于图形参数的实例
extern float xMinScreen,yMinScreen,xMaxScreen,yMaxScreen;
static MCI_GENERIC_PARMS MciGenParm;
WORD wDeviceID;
/////////////////////////////////////////////////////////////////////////////
// CDrawView
CStdioFile dxfFile;
int nCharHeight,nCharWidth;
CDrawDoc* p_Doc;
CDrawView *p_View;
BOOL b_Draw;
CWinThread *m_pDrawThread;
IMPLEMENT_DYNCREATE(CDrawView, CView)
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_SIZE() //视图大小变化时调用,OnSize函数的映射
ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
ON_COMMAND(ID_DRAW_ARC, OnDrawArc) //开始圆弧绘制
ON_COMMAND(ID_DRAW_CIRCLE, OnDrawCircle) //开始圆绘制
ON_COMMAND(ID_DRAW_CIRCLE1, OnDrawCircle1) //开始填充圆绘制
ON_COMMAND(ID_DRAW_LINE, OnDrawLine) //开始直线绘制
ON_COMMAND(ID_DRAW_PLINE, OnDrawPline) //开始连续直线绘制
ON_COMMAND(ID_DRAW_RGN, OnDrawRgn) //开始连续多边形绘制
ON_COMMAND(ID_DRAW_TEXT, OnDrawText) //开始文字标注
ON_COMMAND(ID_TEXT_MESSAGE,DrawText) //标注文字时被调用在屏幕上写文字
ON_COMMAND(ID_TEXT_ONOK,DrawTextOnOk) //按‘确定'退出标注文字框时被调用
ON_COMMAND(ID_TEXT_ONCANCEL,DrawTextOnCancel)//按‘放弃'退出标注文字框时调用
ON_WM_LBUTTONDOWN() //按下鼠标左键,OnlButtonDown函数顶消息映射
ON_WM_MOUSEMOVE() //移动鼠标,OnMouseMove函数顶消息映射
ON_WM_RBUTTONDOWN() //按下鼠标右键,OnRButtonDown函数顶消息映射
ON_COMMAND(ID_GRAPH_REDRAW, OnGraphRedraw) //图形重画
ON_COMMAND(ID_GRAPH_ZOOMOUT, OnGraphZoomOut)//图形放大
ON_COMMAND(ID_GRAPH_PAN, OnGraphPan) //图形摇动
ON_COMMAND(ID_GRAPH_UP, OnGraphUp) //重画上屏
ON_COMMAND(ID_GRAPH_FIRST, OnGraphFirst) //重画首屏
ON_COMMAND(ID_GRAPH_ALL, OnGraphAll) //重画全屏
ON_COMMAND(ID_SELECT_MOUSE, OnSelectMouse) //图形选中
ON_COMMAND(ID_SELECT_CLEAR, OnSelectClear) //放弃选中
ON_COMMAND(ID_SELECT_DELETE, OnSelectDelete)//删除选中图形
ON_COMMAND(ID_EDIT_CUT, OnEditCut) //裁剪选中图形进裁剪板
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) //从剪裁板粘贴图形
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) //逆向放弃操作
ON_COMMAND(ID_EDIT_COPY, OnEditCopy) //拷贝选中图形进裁剪板
ON_COMMAND(ID_EDIT_MOVE, OnEditMove)
ON_WM_HSCROLL() //横向滚动条的消息映射
ON_WM_VSCROLL() //纵向滚动条的消息映射
ON_WM_KEYDOWN() //按下键盘的消息映射
ON_COMMAND(ID_BITMAP_CUT, OnBitmapCut) //图象剪裁
ON_COMMAND(ID_BITMAP_PASTE, OnBitmapPaste) //图象粘贴
ON_EN_CHANGE(IDC_EDIT1, OnChangeDlgEdit) //改变对话条的编辑框的消息映射
ON_LBN_SELCHANGE(IDC_COMBO1,OnChangeDlgCom) //改变对话条的列表框的消息映射
ON_WM_LBUTTONDBLCLK() //双击鼠标左键的消息映射
ON_COMMAND(ID_GRAPHPARA_SET, OnGraphParaSET)//图形参数设置
ON_COMMAND(ID_LAYER_SET, OnLayerManage) //图层管理
ON_COMMAND(ID_BLOCK_ADD, OnBlockAdd) //选中的图形元素形成一个图形块
ON_COMMAND(ID_DRAW_TAG, OnDrawTag) //开始绘制图例
ON_COMMAND(ID_BLOCK_NEW, OnBlockNew) //新建一个图形块
ON_COMMAND(ID_BLOCK_OK, OnEditBlockOk) //保存编辑的图形块退出图形块编辑状态
ON_COMMAND(ID_BLOCK_CANCEL, OnEditBlockCancel) //放弃编辑的图形块退出图形块编辑状态
ON_COMMAND(ID_BLOCK_INSERT, OnBlockInsert) //绘制图形块的插入点
ON_COMMAND(ID_BLOCK_GL, OnBlockDialog) //图形块管理的消息映射
ON_COMMAND(ID_BASEMAP_MANAGE, OnBasemapManage)
ON_WM_SETCURSOR()
ON_COMMAND(ID_GRAPH_MODIFY, OnGreaphModify)
ON_COMMAND(ID_GRAPH_DATA, OnGraphData)
ON_COMMAND(ID_DXF_READ, OnDxfRead)
ON_COMMAND(ID_DXF_WRITE, OnDxfWrite)
ON_COMMAND(ID_SELECT_WINDOW_IN, OnSelectWindowIn)
ON_COMMAND(ID_SELECT_WINDOW_CROSS, OnSelectWindowCross)
ON_COMMAND(ID_SELECT_WINDOW_ALL, OnSelectWindowAll)
ON_COMMAND(ID_SELECT_CIRCLE_IN, OnSelectCircleIn)
ON_COMMAND(ID_SELECT_CIRCLE_CROSS, OnSelectCircleCross)
ON_COMMAND(ID_SELECT_CIRCLE_ALL, OnSelectCircleAll)
ON_COMMAND(ID_SELECT_PLINE_IN, OnSelectPlineIn)
ON_COMMAND(ID_SELECT_PLINE_CROSS, OnSelectPlineCross)
ON_COMMAND(ID_SELECT_PLINE_ALL, OnSelectPlineAll)
ON_COMMAND(ID_GRAPH_ZOOMIN, OnGraphZoomIn)
ON_WM_LBUTTONUP()
ON_WM_CREATE()
ON_WM_ERASEBKGND()
ON_COMMAND(ID_EDIT_PLENGTH, OnEditPlength)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
UINT DrawFunction(LPVOID PHWndView)
{
CClientDC ht(CWnd::FromHandle(*(HWND*)PHWndView));
p_Doc->Draw(&ht,0,0,1);
return(0);
}
//视图类的构造函数
CDrawView::CDrawView()
{
m_pSelection = NULL;
//以下设置首屏的参数并将目前屏幕设置为首屏
m_xStart=51508;
m_yStart=92800;
blc=1;
m_bColor=0; //当前底色的序号
m_pColor=1; //设置笔色
m_brColor=1; //画刷色
m_beColor=0;
m_LineWide=1; //设置线宽
m_LineType=0; //设置线型
m_Layer=0; //设置当前层
PointXyz=new PointStruct[3000];//存储连续直线点的数组
PointPL=new PointStruct[3000];//存储连续直线点的数组用于计算距离
PushNumb=0;
b_RunFirst=1;
pTextDlg=NULL;
//以下设置初始字体大小
m_FontHeight=20;
m_FontWide=10;
m_TextAngle=0;
m_FontAngle=0;
m_FontBetween=1;
m_TextString.Empty();
m_Text1=new CText();//实际初始化一个标注类
nScrollMin=50; //滚动条的最小滚动范围是在屏幕上滚动50个像素
nXLine=1; //横向滚动一个滚动范围
nYLine=1; //纵向滚动一个滚动范围(按中滚动条的按键时的滚动
m_MapMode=1;
}
//将实际坐标(x,y)转成逻辑坐标(*X,*Y)
void CDrawView::DPtoVP(float x,float y,int *X,int *Y)
{
*X=(int)((x-m_xStart)/blc);
if(m_MapMode==1)
*Y=m_hScreen-(int)((y-m_yStart)/blc);
else
*Y=(int)((y-m_yStart)/blc)-m_hScreen;
}
//将逻辑坐标(x,y)转成实际坐标(*X,*Y)
void CDrawView::VPtoDP(int x,int y,float *X,float *Y)
{
*X=m_xStart+x*blc;
if(m_MapMode==1)
*Y=m_yStart+blc*(m_hScreen-y);
else
*Y=m_yStart+blc*(y+m_hScreen);
}
//将实际距离转成逻辑距离返回
//参数:l-距离(逻辑单位)
float CDrawView::VLtoDL(int l)
{
return blc*l;
}
//将逻辑距离转成实际距离返回
//参数:l-距离(实际单位)
int CDrawView::DLtoVL(float l)
{
return (int)(l/blc);
}
//视图类的析构函数
CDrawView::~CDrawView()
{
// delete m_Screen;
delete PointXyz;
delete m_Text1;
delete PointPL;
}
//预定制窗口函数
BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{ m_hcurHand = (HCURSOR)::LoadImage(cs.hInstance,
MAKEINTRESOURCE(IDC_CURSOR_HAND), IMAGE_CURSOR,
32, 32, LR_DEFAULTCOLOR);
m_hcurZoomIn = (HCURSOR)::LoadImage(cs.hInstance,
MAKEINTRESOURCE(IDC_CURSOR_ZOOMIN), IMAGE_CURSOR,
32, 32, LR_DEFAULTCOLOR);
m_hcurZoomOut = (HCURSOR)::LoadImage(cs.hInstance,
MAKEINTRESOURCE(IDC_CURSOR_ZOOMOUT), IMAGE_CURSOR,
32, 32, LR_DEFAULTCOLOR);
//获得光标资源的另一种方法
m_hcurArrow = AfxGetApp()->LoadCursor(IDC_CURSOR_ARROW);
m_hcurCross = AfxGetApp()->LoadCursor(IDC_CURSOR_CROSS);
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDrawView drawing
//视图类中的绘制函数,通过窗口激发完成视图的自动绘制
void CDrawView::OnDraw(CDC* pDC)
{
CRect rr;
TEXTMETRIC tm;
CDrawDoc* pDoc = GetDocument();
p_GraphPara=&pDoc->m_GraphPara; //将公用的GraphPara类的指针指向当前文档的GraphPara对象
p_Doc=pDoc;
p_View=this;
ASSERT_VALID(pDoc);
xMinScreen=m_xStart;
yMinScreen=m_yStart;
xMaxScreen=xMinScreen+blc*m_wScreen;
yMaxScreen=yMinScreen+blc*m_hScreen;
pDC->GetTextMetrics(&tm);
nCharHeight=tm.tmHeight+tm.tmExternalLeading;//-nCharHeightVal;
nCharWidth=tm.tmAveCharWidth;
DrawBack(pDC); //以底色填充整个屏幕
/*if(pDC->GetDeviceCaps(TECHNOLOGY)==DT_RASDISPLAY)
{
if(m_pDrawThread)
{
b_Draw=FALSE;
m_pDrawThread->ResumeThread();
::WaitForSingleObject(m_pDrawThread->m_hThread,INFINITE);
delete m_pDrawThread;
}
b_Draw=TRUE;
m_PDrawThread=AfxBeginThread(DrawFunction,&m_hWnd,THREAD_PRIORITY_BELOW_NORMAL,0,CREATE_SUSPENDED);
m_PDrawThread->m_bAutoDelete=FALSE;
m_PDrawThread->ResumeThread();
}
else
{*/
b_Draw=TRUE;
for(int i=0;i<pDoc->m_BasemapNumb;i++)
pDoc->m_Basemap[i].Draw(this,pDC);
pDoc->Draw(pDC,0,0,m_bColor);
// }
POSITION pos=pDoc->GetStartPosition();
while(pos!=NULL)
{
CDrawCntrItem *pItem=(CDrawCntrItem *)pDoc->GetNextClientItem(pos);
if(pItem!=m_pSelection)
pItem->Draw(pDC);
}
if(m_pSelection!=NULL)
{
m_pSelection->Draw(pDC);
CRectTracker tracker;
PutTracker(m_pSelection,&tracker);
tracker.Draw(pDC);
}
}
//被函数OnDraw调用来以给定的屏幕底色填充屏幕
void CDrawView::DrawBack(CDC* pDC)
{
CBrush brush(p_GraphPara->GetColor(m_bColor)); //得到画刷
CBrush* pOldBrush=pDC->SelectObject(&brush); //选中画刷
pDC->PatBlt(0,0,m_wScreen,m_hScreen,PATCOPY); //填充屏幕
pDC->SelectObject(pOldBrush);
}
//函数Aarc::jsarc作用:计算通过屏幕的三个点的弧的图形要素
//参数:依次为三个点的屏幕坐标p1,p2,p3
//通过指针变量返回圆弧的特征参数
BOOL CDrawView::jsarc(CPoint p1,CPoint p2,CPoint p3,float *CircleX,float *CircleY,
float *CircleR,float *Angle1,float *Angle2)
{
float an1,an2,an3;
float x1,y1,x2,y2,x3,y3,xx1,xx2,yy1,yy2,xx,yy,rr;
float k1,k2;
//将三个点的坐标赋给浮点变量
x1=(float)p1.x;y1=(float)p1.y;x2=(float)p2.x;
y2=(float)p2.y;x3=(float)p3.x;y3=(float)p3.y;
if(x1==x2&&y1==y2||x1==x3&&y1==y3||x2==x3&&y2==y3) //如果有两个点是同一个点
return 0; //操作不成功,返回0
//得到顺三点方向的两条直线中点的坐标
xx1=(x1+x2)/2; yy1=(y1+y2)/2;
xx2=(x2+x3)/2; yy2=(y2+y3)/2;
if(fabs(y2-y1)>0.5) //如果第一条垂线不是垂直线
k1=-(x2-x1)/(y2-y1); //得到直线的垂线的斜率
//得到第二条直线垂线的斜率
if(fabs(y3-y2)>0.5)
k2=-(x3-x2)/(y3-y2);
if(k1==k2&&k1==0.0)
return 0;
if(fabs(y2-y1)<0.5) //如果第一条直线是平行线(即第一条垂线是垂直线)
{
xx=xx1;
if(fabs(y3-y2)<0.5) //如果第二条直线也是平行线
{
yy=y2+10000; //给定圆弧的半径为10000
rr=10000;
}
else // 如果第二条直线不是平行线(即第二条垂线不是垂直线)
{
yy=yy2+k2*(xx2-xx); //求得圆心的纵坐标
rr=yy-y2;
if(rr<0)rr=-rr; //得到半径
}
}
else if(fabs(y2-y3)<0.5) //如果第二条直线是平行线,而第一条直线不是平行线
{
xx=xx2;
yy=yy1+k1*(xx1-xx); //解得圆心的y坐标
rr=yy-y2;
if(rr<0)rr=-rr; //得到半径
}
else //如果两条直线的垂线都不是垂直线
{
if(k1==k2)//如果两条直线平行即三个点在一条直线上
{
//假定这个圆弧半径为10000个像素,求得圆心坐标
xx=x2+(float)(10000/sqrt(1+k1*k1));
yy=y2+(float)(10000/sqrt((1+k1*k1)/(k1*k1)));
rr=10000;
}
else //如果两条直线不平行
{
//解得两条直线的垂线的交点,即圆心的坐标
xx=(yy2-yy1+k1*xx1-k2*xx2)/(k1-k2);
yy=yy1+k1*(xx-xx1);
rr=(float)sqrt((xx-x1)*(xx-x1)+(yy-y1)*(yy-y1)); //得到半径
}
}
//将交点变成实际坐标,并存入结构arc1中
VPtoDP((int)xx,(int)yy,CircleX,CircleY);
*CircleR=VLtoDL((int)rr);
//得到第一个点相对于圆心的弧度
an1=(float)acos((x1-xx)/rr);
if(y1-yy>0) an1=(float)(pi*2-an1);
//得到第二个点相对于圆心的弧度
an2=(float)acos((x2-xx)/rr);
if(y2-yy>0) an2=(float)(pi*2-an2);
//得到第三个点相对于圆心的弧度
an3=(float)acos((x3-xx)/rr);
if(y3-yy>0) an3=(float)(pi*2-an3);
if(an2>an1&&an2<an1+pi||an2<an1&&an2+pi<an1) //如果弧是逆时针方向画的
{
*Angle1=an1;*Angle2=an3; //得到起终弧度
}
else //如果弧是顺时针画的
{
*Angle1=an3;*Angle2=an1; //得到起终弧度
}
return 1; //操作成功
}
//视图类的初始化函数
void CDrawView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CDrawDoc* pDoc=GetDocument();
m_pSelection = NULL; // initialize selection
p_View=this;
}
/////////////////////////////////////////////////////////////////////////////
// CDrawView printing
BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?