📄 drawshapeview.cpp
字号:
// DrawShapeView.cpp : implementation of the CDrawShapeView class
//
#include "stdafx.h"
#include "DrawShape.h"
#include "DrawShapeDoc.h"
#include "DrawShapeView.h"
#include "Draw.h"
#include "ReadShapefile.h"
/*
#include "Direct.h" 加入该头文件以调用_getcwd
该函数获得当前工作路径
*/
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CDrawShapeView* gpCDrawShapeView;
extern CGraphPara* gpCGraphPara;
int gHScreen,gWScreen; //当前视图的高度和宽度
float xMinScreen,yMinScreen,xMaxScreen,yMaxScreen;
//全局函数,判断一矩形与当前视图屏幕是否相交
BOOL IsRectCross(float minX, float minY, float maxX, float maxY)
{
if(minX > xMaxScreen || maxX < xMinScreen ||
minY > yMaxScreen || maxY < yMinScreen)
{
return FALSE;
}
else
{
return TRUE;
}
}
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView
IMPLEMENT_DYNCREATE(CDrawShapeView, CView)
BEGIN_MESSAGE_MAP(CDrawShapeView, CView)
//{{AFX_MSG_MAP(CDrawShapeView)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_X,OnUpdateIndicatorX)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_Y,OnUpdateIndicatorY)
ON_WM_SIZE()
ON_COMMAND(ID_TEST_DRAW, OnTestDraw)
ON_COMMAND(ID_DRAW_LINE, OnDrawLine)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_DRAW_POLYLINE, OnDrawPolyline)
ON_COMMAND(ID_DRAW_POLYGON, OnDrawPolygon)
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
ON_COMMAND(ID_VIEW_ZOOMRECT, OnViewZoomrect)
ON_COMMAND(ID_VIEW_MOVE, OnViewMove)
ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen)
ON_WM_SETCURSOR()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
ON_COMMAND(ID_DRAW_POINT, OnDrawPoint)
ON_WM_ERASEBKGND()
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView construction/destruction
CDrawShapeView::CDrawShapeView()
{
// TODO: add construction code here
//得到应用程序路径
GetAppPath();
m_xStart=0.0;
m_yStart=0.0;
blc=1.0;
m_MapMode=1; //设定MM_TEXT映射模式
m_PushNum=0;
m_LineType=0; //以下在View中设定的参数值将影响在画图中的颜色
m_LineWide=1;
m_ColorPen=3;
m_ColorBrush=2;
m_Color=1;
m_bDelete=0;
m_Layer=1;
m_DrawType=0;
//在画图过程中,存储按左键的坐标,因为不知道使用者
//到底画出多大顶点的图形,设置为最大3000
m_PointArray=new PointStruct[3000];//连续直线、多边形数组
IsFirst = true;
IsFirstFill = true;
iWScreen = GetSystemMetrics(SM_CXSCREEN);
iHScreen = GetSystemMetrics(SM_CYSCREEN);
// m_XminIntersect = 0;
// m_YminIntersect = 0;
// m_XmaxIntersect = 0;
// m_YmaxIntersect = 0;
}
CDrawShapeView::~CDrawShapeView()
{
delete[] m_PointArray;
}
BOOL CDrawShapeView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView drawing
void CDrawShapeView::OnDraw(CDC* pDC)
{
CDrawShapeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//全局变量初始化
xMinScreen = m_xStart;
yMinScreen = m_yStart;
xMaxScreen = xMinScreen + blc*m_wScreen;
yMaxScreen = yMinScreen + blc*m_hScreen;
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap; //定义一个位图对象
// static bool IsFirst = true;
// static bool IsFirstFill = true;
//随后建立与屏幕显示兼容的内存显示设备
//这里我们就在内存中虚拟建造了DC
MemDC.CreateCompatibleDC(NULL);
// MemDC.CreateCompatibleDC(pDC);
//这时还不能绘图,因为没有地方画
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
//依附DC创建bitmap
if(IsFirst == true)
{
m_MemBitmap.CreateCompatibleBitmap(pDC,iWScreen,iHScreen);
IsFirst = false;
}
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&m_MemBitmap);
//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
if(IsFirstFill = true)
{
MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
IsFirstFill = false;
}
//以下在MemDC中的位图上绘图
//遍历所有图形元素并绘制
// 1-直线 2-连续直线或多边形区域 3-点
for(int i=1; i<4; i++)
{
for(int j=0; j <= pDoc->GetGraphUpperBound(i); j++)
{
pDoc->GetGraph(i,j)->Draw(&MemDC,0,0,m_Color);
}
}
//MemDC中绘图结束
//将内存(MemDC)中的图拷贝到屏幕上(pDC)进行显示
pDC->BitBlt(0,0,iWScreen,iHScreen,&MemDC,0,0,SRCCOPY);
//绘图完成后的清理
MemDC.SelectObject(pOldBit);
// MemBitmap.DeleteObject(); //清除位图
MemDC.DeleteDC(); //清除DC
}
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView printing
BOOL CDrawShapeView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDrawShapeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDrawShapeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView diagnostics
#ifdef _DEBUG
void CDrawShapeView::AssertValid() const
{
CView::AssertValid();
}
void CDrawShapeView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CDrawShapeDoc* CDrawShapeView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawShapeDoc)));
return (CDrawShapeDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDrawShapeView message handlers
//(Logical to Actual)
//逻辑坐标为int,实际坐标为float
void CDrawShapeView::LPtoAP(int x,int y,float* X,float* Y)
{
*X=m_xStart+x*blc;
if(m_MapMode==1)//MM_TEXT模式
*Y=m_yStart+blc*(m_hScreen-y);
else//其它模式
*Y=m_yStart+blc*(m_hScreen+y);
}
//实际坐标到逻辑坐标转换
void CDrawShapeView::APtoLP(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;
}
//逻辑数值到实际数值 (logicla value to actual value)
float CDrawShapeView::LVtoAV(int a_iInputval)
{
return blc * a_iInputval;
}
//实际数值到逻辑数值
int CDrawShapeView::AVtoLV(float a_fInputval)
{
return (int)(a_fInputval / blc);
}
//
//void CDrawShapeView::OutPutX(int x)
//{
//CString mystr;
//mystr.Format("%d",x);
// AfxMessageBox(mystr);
//}
void CDrawShapeView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
{
// TODO: Add your specialized code here and/or call the base class
gpCDrawShapeView=this;
CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}
void CDrawShapeView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
m_wScreen=cx;
m_hScreen=cy;
gHScreen = cx;
gWScreen = cy;
}
void CDrawShapeView::OnTestDraw()
{
// CPen pen(2,1,RGB(128,128,0));
// CPen* pOldPen=clientDC.SelectObject(&pen);
//
// clientDC.MoveTo(point_array[0]);
// for(int i=1;i<3;i++)
// clientDC.LineTo(point_array[i]);
//
//
// clientDC.SelectObject(pOldPen);
//
// CDrawShapeDoc* pDoc = GetDocument();
//
// int i=pDoc->GetGraphUpperBound(2);
// CReadShapefile clsShapefile;
// clsShapefile.OpenShapefile();
// int n=clsShapefile.GetShapeType();
// double x1,y1,x2,y2;
// double dXcoord1;
// double dYcoord1;
// double dXcoord2;
// double dYcoord2;
//
// PointStruct mypoint;
// clsShapefile.GetMapBound(x1,y1,x2,y2);
// clsShapefile.GetLine(&mypoint);
// CString str;
// str.Format("%f",mypoint.x);
// AfxMessageBox(str);
//
//
// AfxGetMainWnd() ->ShowWindow(SW_MAXIMIZE);
//使程序最大化.
}
void CDrawShapeView::OnDrawLine()
{
// TODO: Add your command handler code here
m_PushNum=0;
m_DrawType=1;//绘制直线
}
void CDrawShapeView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDrawShapeDoc* pDoc=GetDocument();
CClientDC clientDC(this);
// int iWScreen,iHScreen; //屏幕宽度、高度
// iWScreen = GetSystemMetrics(SM_CXSCREEN);
// iHScreen = GetSystemMetrics(SM_CYSCREEN);
if(m_DrawType==1)//如果是绘制直线
{
float x1,y1,x2,y2;
// static bool IsFirst = true;
// static bool IsFirstFill = true;
CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
/*
//新建文档时,此时应该进入
if(IsFirst == true) //只能创建兼容DC一次,否则程序终止
{
m_MemBitmap.CreateCompatibleBitmap(&clientDC,iWScreen,iHScreen);
IsFirst = false;
}
*/
CBitmap* pOldBitmap = MemDC.SelectObject(&m_MemBitmap);
/*
if(IsFirstFill == true) //只填充空白位图一次
{
MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
IsFirstFill = false;
}
*/
//
// CBitmap* pOldBitmap = MemDC.SelectObject(&m_MemBitmap);
// if(IsFirst == true) //只创建兼容DC一次
// {
// //填充白色背景
// MemDC.FillSolidRect(0,0,iWScreen,iHScreen,RGB(255,255,255));
// }
if(m_PushNum==0)
{
m_PushNum++;
m_PointOrg=point;
m_PointOld=point;
// m_PointOrg.x =50;
// m_PointOrg.y =50;
// m_PointOld.x=0;
// m_PointOld.y=0;
SetCapture();
}
else
{
LPtoAP(m_PointOrg.x,m_PointOrg.y,&x1,&y1);
LPtoAP(point.x,point.y,&x2,&y2);
//增加到m_LineArray中并绘制该直线
CLine* myline=pDoc->AddLine(m_ColorPen,m_ColorBrush,m_LineWide,m_LineType,
m_Layer,gpCGraphPara->GetIdOnly(),m_bDelete,x1,y1,
x2,y2);
//以MemDC取代clientDC
//不必遍历所有图形并绘制,因为每次只需绘制当前的图形
//而且每次绘的都会保存在位图中,
//在位图上绘制
myline->Draw(&MemDC,0,0,m_Color);
/*
//遍历所有图形元素并绘制
// 1-直线 2-连续直线或多边形区域 3-点
for(int i=1; i<4; i++)
{
for(int j=0; j <= pDoc->GetGraphUpperBound(i); j++)
{
pDoc->GetGraph(i,j)->Draw(&MemDC,0,0,m_Color);
}
}
*/
clientDC.BitBlt(0,0,iWScreen,iHScreen,&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBitmap);
MemDC.DeleteDC();
m_PushNum=0;
ReleaseCapture();
}
}
else if(m_DrawType==2 || m_DrawType==3)//绘制连续直线或多边形区域,它们同是按下左键时记录各个点坐标
{
float x,y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -