📄 drawview.cpp
字号:
// 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 "TextWriteDlg.h"
#include "mainfrm.h"
#include "winresrc.h"
#include <afxwin.h>
#include "datalinkdlg.h"
#include <windowsx.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CGraphPara *p_GraphPara; //初试化一个公用的关于图形参数的实例
extern float xMinScreen,yMinScreen,xMaxScreen,yMaxScreen;
/////////////////////////////////////////////////////////////////////////////
// CDrawView
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_OLE_INSERT_NEW, OnInsertObject)
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_ZOOM, OnGraphZoom) //图形放大
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_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_KEYDOWN()
ON_COMMAND(ID_BITMAP_CUT, OnBitmapCut)
ON_COMMAND(ID_BITMAP_PASTE, OnBitmapPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
ON_COMMAND(ID_GRAPH_DRAW, OnGraphDraw)
ON_EN_CHANGE(IDC_EDIT1, OnChangeDlgEdit)
ON_LBN_SELCHANGE(IDC_COMBO1,OnChangeDlgCom)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_DATA_SEACHER, OnDataSeacher)
//}}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=0;
m_yStart=0;
blc=1.0;
m_bColor=0; //当前底色的序号
m_pColor=1; //设置笔色
m_brColor=1; //画刷色
m_LineWide=1; //设置线宽
m_LineType=0; //设置线型
m_Layer=1; //设置当前层
PointXyz=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();//实际初始化一个标注类
m_bColor=7; //屏幕底色设置为0颜色号
nScrollMin=50; //滚动条的最小滚动范围是在屏幕上滚动50个像素
nXLine=1; //横向滚动一个滚动范围
nYLine=1; //纵向滚动一个滚动范围(按中滚动条的按键时的滚动
m_MapMode=1;
// TODO: add construction code here
}
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;
}
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);
}
float CDrawView::VLtoDL(int l)
{
return blc*l;
}
int CDrawView::DLtoVL(float l)
{
return (int)(l/blc);
}
//视图类的析构函数
CDrawView::~CDrawView()
{
delete PointXyz;
delete m_Text1;
}
//预定制窗口函数
BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style=cs.style|WS_HSCROLL|WS_VSCROLL;
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDrawView drawing
//视图类中的绘制函数,通过窗口激发完成视图的自动绘制
void CDrawView::OnDraw(CDC* pDC)
{
CRect rr;
CDrawDoc* pDoc = GetDocument();
p_Doc=pDoc;
ASSERT_VALID(pDoc);
xMinScreen=m_xStart;
yMinScreen=m_yStart;
xMaxScreen=xMinScreen+blc*m_wScreen;
yMaxScreen=yMinScreen+blc*m_hScreen;
// 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
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;
m_pLinkSet=&pDoc->m_linkdata1;
}
/////////////////////////////////////////////////////////////////////////////
// CDrawView printing
BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDrawView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
int mPageHeight,mPageWidth,nPage;
m_MapMode=2;
pDC->SetMapMode(m_MapMode);
//整个图形左下角的坐标
xLeft=p_Screen[0].sx;
yBottom=p_Screen[0].sy;
//整个图形右上角的坐标为
xRight=xLeft+p_Screen[0].blc*m_wScreen;
yTop=yBottom+p_Screen[0].blc*m_hScreen;
//图形的横向和纵向的幅度为
xWide=xRight-xLeft;
yHigh=yTop-yBottom;
//point.y=pDC->GetDeviceCaps(VERTRES); //得到设备竖直方向的像素数
//point.x=pDC->GetDeviceCaps(HORZRES); //得到设备水平方向的像素数
//pDC->DPtoLP(&point);
pDC->DPtoLP(&(pInfo->m_rectDraw));
mPageHeight=abs(pInfo->m_rectDraw.top-pInfo->m_rectDraw.bottom);
mPageWidth=pInfo->m_rectDraw.right-pInfo->m_rectDraw.left;
//每页的横向和纵向大小
xPage=blc*mPageWidth; //每页的实际宽度
yPage=blc*mPageHeight; //每页的实际高度
nPageX=(int)(xWide/xPage)+(xWide>xPage*(int)(xWide/xPage));//横向页数
nPageY=(int)(yHigh/yPage)+(yHigh>yPage*(int)(yHigh/yPage));//纵向页数
nPage=nPageX*nPageY; //总页数
pInfo->SetMinPage(1); //设置最小页号
pInfo->SetMaxPage(nPage); //设置最大页号
m_hScreen1=m_hScreen;
m_wScreen1=m_wScreen;
m_hScreen=mPageHeight; //显示窗口的高度
m_wScreen=mPageWidth; //显示窗口的宽度
// TODO: add extra initialization before printing
}
void CDrawView::OnEndPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)
{
CDrawDoc *pDoc=(CDrawDoc *)GetDocument();
//恢复屏幕显示的参数
m_xStart=p_Screen[pDoc->m_CurrentScreen].sx;
m_yStart=p_Screen[pDoc->m_CurrentScreen].sy;
// TODO: add cleanup after printing
m_hScreen=m_hScreen1;
m_wScreen=m_wScreen1;
m_MapMode=1;
}
void CDrawView::OnDestroy()
{
CView::OnDestroy();
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
{
pActiveItem->Deactivate();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
}
/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands
BOOL CDrawView::IsSelected(const CObject* pDocItem) const
{
// The implementation below is adequate if your selection consists of
// only CDrawCntrItem objects. To handle different selection
// mechanisms, the implementation here should be replaced.
// TODO: implement this function that tests for a selected OLE client item
return pDocItem == m_pSelection;
}
void CDrawView::OnInsertObject()
{
m_DrawCurrent=50; //进行插入OLE对象操作
PushNumb=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -