?? 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; //初試化一個公用的關于圖形參數(shù)的實例
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函數(shù)的映射
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) //開始連續(xù)直線繪制
ON_COMMAND(ID_DRAW_RGN, OnDrawRgn) //開始連續(xù)多邊形繪制
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函數(shù)頂消息映射
ON_WM_MOUSEMOVE() //移動鼠標,OnMouseMove函數(shù)頂消息映射
ON_WM_RBUTTONDOWN() //按下鼠標右鍵,OnRButtonDown函數(shù)頂消息映射
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);
}
//視圖類的構造函數(shù)
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];//存儲連續(xù)直線點的數(shù)組
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);
}
//視圖類的析構函數(shù)
CDrawView::~CDrawView()
{
delete PointXyz;
delete m_Text1;
}
//預定制窗口函數(shù)
BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style=cs.style|WS_HSCROLL|WS_VSCROLL;
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDrawView drawing
//視圖類中的繪制函數(shù),通過窗口激發(fā)完成視圖的自動繪制
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);
}
}
//被函數(shù)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);
}
//函數(shù)Aarc::jsarc作用:計算通過屏幕的三個點的弧的圖形要素
//參數(shù):依次為三個點的屏幕坐標p1,p2,p3
//通過指針變量返回圓弧的特征參數(shù)
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); //得到設備豎直方向的像素數(shù)
//point.x=pDC->GetDeviceCaps(HORZRES); //得到設備水平方向的像素數(shù)
//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));//橫向頁數(shù)
nPageY=(int)(yHigh/yPage)+(yHigh>yPage*(int)(yHigh/yPage));//縱向頁數(shù)
nPage=nPageX*nPageY; //總頁數(shù)
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();
//恢復屏幕顯示的參數(shù)
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 + -