www.pudn.com > RMS2000_C.rar > DrawObj.cpp


// DrawObj.cpp: implementation of the CDrawObj class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "DrawCli.h" 
#include "DrawObj.h" 
 
#include "drawdoc.h" 
#include "drawvw.h" 
#include "cntritem.h" 
#include "rectdlg.h" 
#include "mainfrm.h" 
 
#include "textdlg.h" 
#include  
 
#define PADDING 2 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
IMPLEMENT_SERIAL(CDrawObj, CObject, 0) 
  
CDrawObj::CDrawObj() 
{ 
	m_nSW=0.0; 
	m_nSWval=0.0; 
} 
 
CDrawObj::~CDrawObj() 
{ 
} 
 
CDrawObj::CDrawObj(const CRect& position) 
{ 
	m_position = position; 
	m_pDocument = NULL; 
	m_nSW=0.0; 
	m_nSWval=0.0; 
 
	m_bPen = TRUE; 
	m_logpen.lopnStyle = PS_INSIDEFRAME; 
	m_logpen.lopnWidth.x = 2; 
	m_logpen.lopnWidth.y = 2; 
	m_logpen.lopnColor = RGB(0, 0, 0); 
 
	m_bBrush = TRUE; 
	mv_bLock = FALSE; 
 
	mv_nRtu=0; 
	mv_nPar=0; 
	mv_nType=0; 
	mv_nInt=0; 
	mv_nDec=0; 
	mv_nWard=0; 
	mv_bInvalid=FALSE; 
 
	m_logbrush.lbStyle = BS_SOLID; 
	m_logbrush.lbColor = RGB(192, 192, 192); 
	m_logbrush.lbHatch = HS_HORIZONTAL; 
} 
 
void CDrawObj::Serialize(CArchive& ar) 
{ 
	CObject::Serialize(ar); 
	if (ar.IsStoring()) 
	{ 
		ar << m_position; 
		ar << (WORD)m_bPen; 
		ar.Write(&m_logpen, sizeof(LOGPEN)); 
		ar << (WORD)m_bBrush; 
		ar.Write(&m_logbrush, sizeof(LOGBRUSH)); 
		ar << (WORD)mv_bLock; 
		ar << (WORD)mv_nRtu; 
		ar << (WORD)mv_nPar; 
		ar << (WORD)mv_nType; 
		ar << (WORD)mv_nInt; 
		ar << (WORD)mv_nDec; 
		ar << (WORD)mv_nWard; 
		ar << (WORD)mv_bInvalid; 
	} 
	else 
	{ 
		// get the document back pointer from the archive 
		m_pDocument = (CDrawDoc*)ar.m_pDocument; 
		ASSERT_VALID(m_pDocument); 
		ASSERT_KINDOF(CDrawDoc, m_pDocument); 
 
		WORD wTemp; 
		ar >> m_position; 
		ar >> wTemp; m_bPen = (BOOL)wTemp; 
		ar.Read(&m_logpen,sizeof(LOGPEN)); 
		ar >> wTemp; m_bBrush = (BOOL)wTemp; 
		ar.Read(&m_logbrush, sizeof(LOGBRUSH)); 
		ar >> wTemp; mv_bLock = (BOOL)wTemp; 
 
		ar >> wTemp; mv_nRtu = (int)wTemp; 
		ar >> wTemp; mv_nPar = (int)wTemp; 
		ar >> wTemp; mv_nType = (int)wTemp; 
		ar >> wTemp; mv_nInt = (int)wTemp; 
		ar >> wTemp; mv_nDec = (int)wTemp; 
		ar >> wTemp; mv_nWard = (int)wTemp; 
		ar >> wTemp; mv_bInvalid = (BOOL)wTemp; 
	} 
} 
 
void CDrawObj::Remove() 
{ 
	delete this; 
} 
 
void CDrawObj::Draw(CDC*) 
{ 
} 
 
void CDrawObj::DrawTracker(CDC* pDC, TrackerState state) 
{ 
	ASSERT_VALID(this); 
 
	switch (state) 
	{ 
	case normal: 
		break; 
 
	case selected: 
	case active: 
		{ 
			int nHandleCount = GetHandleCount(); 
			for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1) 
			{ 
				CPoint handle = GetHandle(nHandle); 
				pDC->PatBlt(handle.x - 2, handle.y - 2, 5, 5, PATINVERT);//DSTINVERT); 
			} 
		} 
		break; 
	} 
} 
 
// position is in logical 
void CDrawObj::MoveTo(const CRect& position, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
  
	if (mv_bLock)  //www 
		return; 
	if (position == m_position) 
		return; 
 
	if (pView == NULL) 
	{ 
		Invalidate(); 
		m_position = position; 
		Invalidate(); 
	} 
	else 
	{ 
		pView->InvalObj(this); 
		m_position = position; 
		pView->InvalObj(this); 
	} 
	m_pDocument->SetModifiedFlag(); 
} 
 
// Note: if bSelected, hit-codes start at one for the top-left 
// and increment clockwise, 0 means no hit. 
// If !bSelected, 0 = no hit, 1 = hit (anywhere) 
 
// point is in logical coordinates 
int CDrawObj::HitTest(CPoint point, CDrawView* pView, BOOL bSelected) 
{ 
	ASSERT_VALID(this); 
	ASSERT(pView != NULL); 
 
	if (bSelected) 
	{ 
		int nHandleCount = GetHandleCount(); 
		for (int nHandle = 1; nHandle <= nHandleCount; nHandle += 1) 
		{ 
			// GetHandleRect returns in logical coords 
			CRect rc = GetHandleRect(nHandle,pView); 
			if (point.x >= rc.left && point.x < rc.right && 
				point.y <= rc.top && point.y > rc.bottom) 
				return nHandle; 
		} 
	} 
	else 
	{ 
		if (point.x >= m_position.left && point.x < m_position.right && 
			point.y <= m_position.top && point.y > m_position.bottom) 
			return 1; 
	} 
	return 0; 
} 
 
// rect must be in logical coordinates 
BOOL CDrawObj::Intersects(const CRect& rect) 
{ 
	ASSERT_VALID(this); 
 
	CRect fixed = m_position; 
	fixed.NormalizeRect(); 
	CRect rectT = rect; 
	rectT.NormalizeRect(); 
	return !(rectT & fixed).IsRectEmpty(); 
} 
 
int CDrawObj::GetHandleCount() 
{ 
	ASSERT_VALID(this); 
	return 8; 
} 
 
// returns logical coords of center of handle 
CPoint CDrawObj::GetHandle(int nHandle) 
{ 
	ASSERT_VALID(this); 
	int x, y, xCenter, yCenter; 
 
	// this gets the center regardless of left/right and top/bottom ordering 
	xCenter = m_position.left + m_position.Width() / 2; 
	yCenter = m_position.top + m_position.Height() / 2; 
 
	switch (nHandle) 
	{ 
	default: 
		ASSERT(FALSE); 
 
	case 1: 
		x = m_position.left; 
		y = m_position.top; 
		break; 
 
	case 2: 
		x = xCenter; 
		y = m_position.top; 
		break; 
 
	case 3: 
		x = m_position.right; 
		y = m_position.top; 
		break; 
 
	case 4: 
		x = m_position.right; 
		y = yCenter; 
		break; 
 
	case 5: 
		x = m_position.right; 
		y = m_position.bottom; 
		break; 
 
	case 6: 
		x = xCenter; 
		y = m_position.bottom; 
		break; 
 
	case 7: 
		x = m_position.left; 
		y = m_position.bottom; 
		break; 
 
	case 8: 
		x = m_position.left; 
		y = yCenter; 
		break; 
	} 
 
	return CPoint(x, y); 
} 
 
// return rectange of handle in logical coords 
CRect CDrawObj::GetHandleRect(int nHandleID, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
	ASSERT(pView != NULL); 
 
	CRect rect; 
	// get the center of the handle in logical coords 
	CPoint point = GetHandle(nHandleID); 
	// convert to client/device coords 
	pView->DocToClient(point); 
	// return CRect of handle in device coords 
	rect.SetRect(point.x-3, point.y-3, point.x+3, point.y+3); 
	pView->ClientToDoc(rect); 
 
	return rect; 
} 
 
HCURSOR CDrawObj::GetHandleCursor(int nHandle) 
{ 
	ASSERT_VALID(this); 
 
	LPCTSTR id; 
	switch (nHandle) 
	{ 
	default: 
		ASSERT(FALSE); 
 
	case 1: 
	case 5: 
		id = IDC_SIZENWSE; 
		break; 
 
	case 2: 
	case 6: 
		id = IDC_SIZENS; 
		break; 
 
	case 3: 
	case 7: 
		id = IDC_SIZENESW; 
		break; 
 
	case 4: 
	case 8: 
		id = IDC_SIZEWE; 
		break; 
	} 
 
	return AfxGetApp()->LoadStandardCursor(id); 
} 
 
// point must be in logical 
void CDrawObj::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
 
	CRect position = m_position; 
	switch (nHandle) 
	{ 
	default: 
		ASSERT(FALSE); 
 
	case 1: 
		position.left = point.x; 
		position.top = point.y; 
		break; 
 
	case 2: 
		position.top = point.y; 
		break; 
 
	case 3: 
		position.right = point.x; 
		position.top = point.y; 
		break; 
 
	case 4: 
		position.right = point.x; 
		break; 
 
	case 5: 
		position.right = point.x; 
		position.bottom = point.y; 
		break; 
 
	case 6: 
		position.bottom = point.y; 
		break; 
 
	case 7: 
		position.left = point.x; 
		position.bottom = point.y; 
		break; 
 
	case 8: 
		position.left = point.x; 
		break; 
	} 
 
	MoveTo(position, pView); 
} 
 
void CDrawObj::Invalidate() 
{ 
	ASSERT_VALID(this); 
	m_pDocument->UpdateAllViews(NULL, HINT_UPDATE_DRAWOBJ, this); 
} 
 
CDrawObj* CDrawObj::Clone(CDrawDoc* pDoc) 
{ 
	ASSERT_VALID(this); 
  
	CDrawObj* pClone = new CDrawObj(m_position); 
 
	pClone->m_bPen = m_bPen; 
	pClone->m_logpen = m_logpen; 
	pClone->m_bBrush = m_bBrush; 
	pClone->m_logbrush = m_logbrush; 
	pClone->mv_bLock = mv_bLock; 
 
	pClone->mv_nRtu = mv_nRtu; 
	pClone->mv_nPar = mv_nPar; 
	pClone->mv_nType = mv_nType; 
	pClone->mv_nInt = mv_nInt; 
	pClone->mv_nDec = mv_nDec; 
	pClone->mv_nWard = mv_nWard; 
	pClone->mv_bInvalid = mv_bInvalid; 
 
	ASSERT_VALID(pClone); 
 
	if (pDoc != NULL) 
		pDoc->Add(pClone); 
 
	return pClone; 
 
} 
 
void CDrawObj::OnEditProperties() 
{ 
	ASSERT_VALID(this); 
    
	CPropertySheet sheet( _T("对象显示属性") ); 
	CRectDlg dlg; 
	dlg.m_bNoFill = !m_bBrush; 
	dlg.m_bLock = mv_bLock; 
 
	dlg.m_nRtu = mv_nRtu; 
	dlg.m_nPar = mv_nPar; 
	dlg.m_nType = mv_nType; 
	dlg.m_nInt = mv_nInt; 
	dlg.m_nDec = mv_nDec; 
	dlg.m_nWard = mv_nWard; 
	dlg.m_bInvalid = mv_bInvalid; 
 
	dlg.m_penSize = m_bPen ? m_logpen.lopnWidth.x : 0; 
	dlg.m_LineColor = m_logpen.lopnColor;	  /*xxx*/ 
    dlg.m_FillColor = m_logbrush.lbColor;	  /*xxx*/ 
	sheet.AddPage( &dlg ); 
 
	if (sheet.DoModal() != IDOK) 
		return; 
 
	m_bBrush = !dlg.m_bNoFill; 
	mv_bLock = dlg.m_bLock; 
 
	mv_nRtu=dlg.m_nRtu; 
	mv_nPar=dlg.m_nPar; 
	mv_nType=dlg.m_nType; 
	mv_nInt=dlg.m_nInt; 
	mv_nDec=dlg.m_nDec; 
	mv_nWard=dlg.m_nWard; 
	mv_bInvalid=dlg.m_bInvalid; 
 
	m_bPen = dlg.m_penSize > 0; 
	m_logbrush.lbColor = dlg.m_FillColor;   /*xxx*/ 
	if (m_bPen) 
	{ 
	    m_logpen.lopnWidth.x = dlg.m_penSize; 
		m_logpen.lopnWidth.y = dlg.m_penSize; 
		m_logpen.lopnColor = dlg.m_LineColor;   /*xxx*/ 
 	} 
 
	Invalidate(); 
	m_pDocument->SetModifiedFlag();  
} 
 
void CDrawObj::OnOpen(CDrawView* /*pView*/ ) 
{ 
	OnEditProperties(); 
} 
 
void CDrawObj::SetLineColor(COLORREF color) 
{ 
	ASSERT_VALID(this); 
 
	m_logpen.lopnColor = color; 
	Invalidate(); 
	m_pDocument->SetModifiedFlag(); 
} 
 
void CDrawObj::SetTextColor(COLORREF color) 
{ 
} 
void CDrawObj::SetText(CString text) 
{ 
} 
 
void CDrawObj::GetText(CString& text) 
{ 
} 
void CDrawObj::GetGS(CString& GS) 
{ 
} 
 
COLORREF CDrawObj::GetFillColor() 
{ 
	return m_logbrush.lbColor; 
} 
 
void CDrawObj::SetFillColor(COLORREF color) 
{ 
	ASSERT_VALID(this); 
 
	m_logbrush.lbColor = color; 
	Invalidate(); 
	m_pDocument->SetModifiedFlag(); 
} 
 
void CDrawObj::SetSW(float sw) 
{ 
	ASSERT_VALID(this); 
 
	m_nSW = sw; 
	Invalidate(); 
	m_pDocument->SetModifiedFlag(); 
} 
 
#ifdef _DEBUG 
void CDrawObj::AssertValid() 
{ 
	ASSERT(m_position.left <= m_position.right); 
	ASSERT(m_position.bottom <= m_position.top); 
} 
#endif 
 
//////////////////////////////////////////////////////////////////////////// 
// CDrawRect 
 
IMPLEMENT_SERIAL(CDrawRect, CDrawObj, 0) 
 
CDrawRect::CDrawRect() 
{ 
} 
 
CDrawRect::CDrawRect(const CRect& position) 
	: CDrawObj(position) 
{ 
	ASSERT_VALID(this); 
 
	m_nShape = rectangle; 
	m_roundness.x = 16; 
	m_roundness.y = 16; 
	m_count=0; 
	m_piecount=0; 
} 
 
void CDrawRect::Serialize(CArchive& ar) 
{ 
	ASSERT_VALID(this); 
 
	CDrawObj::Serialize(ar); 
	if (ar.IsStoring()) 
	{ 
		ar << (WORD) m_nShape; 
		ar << m_roundness; 
	} 
	else 
	{ 
		WORD wTemp; 
		ar >> wTemp; m_nShape = (Shape)wTemp; 
		ar >> m_roundness; 
	} 
} 
 
/**/ 
void CDrawRect::DrawCircle(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
 
	int cx,cy; 
	if (rect.right < rect.left) 
		{ 
			cx = rect.left; 
			rect.left = rect.right; 
			rect.right = cx; 
		} 
	if (rect.bottom < rect.top) 
		{ 
			cy = rect.top; 
			rect.top = rect.bottom; 
			rect.bottom = cy; 
		} 
	cx = rect.right - rect.left; 
    cy = rect.bottom - rect.top; 
	if (cx > cy) 
		{ 
			rect.left += (cx-cy) / 2; 
			rect.right = rect.left + cy; 
		} 
	else 
		{ 
            rect.top += (cy-cx) / 2; 
			rect.bottom = rect.top + cx; 
		} 
	//pDC->TextOut(rect.left,rect.bottom,"123",3); 
	pDC->Ellipse(rect); 
} 
 
void CDrawRect::DrawHpipe(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
	int cx,cy; 
	if (rect.right < rect.left) 
		{ 
			cx = rect.left; 
			rect.left = rect.right; 
			rect.right = cx; 
		} 
	if (rect.bottom < rect.top) 
		{ 
			cy = rect.top; 
			rect.top = rect.bottom; 
			rect.bottom = cy; 
		} 
	cx = rect.right - rect.left; 
    cy = rect.bottom - rect.top; 
  
	m_bBrush=0; 
	int lineNum=(cy+1)/2; 
	LOGPEN logpen=m_logpen; 
	logpen.lopnWidth.x=1; 
	logpen.lopnWidth.y=1; 
	COLORREF color=logpen.lopnColor; 
	BYTE red=(BYTE)(color & 0xFF); 
	BYTE green=(BYTE)(color>>8) & 0xFF; 
	BYTE blue=(BYTE)(color>>16) & 0xFF; 
 
	if ((green==255)&&(red==255)&&(blue==255)) 
	{ 
		red=0; 
		green=0; 
		blue=0; 
	} 
  
	if ((lineNum<1)||(lineNum>255)) return; 
	BYTE Rratio=(255-red)/(BYTE)lineNum;  
	BYTE Gratio=(255-green)/(BYTE)lineNum;  
	BYTE Bratio=(255-blue)/(BYTE)lineNum;  
	for (int i=0;iSelectObject(&pen); 
		else 
			pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
 
		pDC->MoveTo(rect.left,rect.top+i); 
		pDC->LineTo(rect.right,rect.top+i); 
 
		pDC->SelectObject(pOldPen); 
		pen.DeleteObject(); 
	} 
 
	for (i=0;iSelectObject(&pen); 
		else 
			pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
		pDC->MoveTo(rect.left,rect.top+i+lineNum); 
		pDC->LineTo(rect.right,rect.top+i+lineNum); 
		pDC->SelectObject(pOldPen); 
		pen.DeleteObject(); 
	} 
 
} 
void CDrawRect::DrawVpipe(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
	int cx,cy; 
	if (rect.right < rect.left) 
		{ 
			cx = rect.left; 
			rect.left = rect.right; 
			rect.right = cx; 
		} 
	if (rect.bottom < rect.top) 
		{ 
			cy = rect.top; 
			rect.top = rect.bottom; 
			rect.bottom = cy; 
		} 
	cx = rect.right - rect.left; 
    cy = rect.bottom - rect.top; 
  
	m_bBrush=0; 
	int lineNum=(cx+1)/2; 
	LOGPEN logpen=m_logpen; 
	logpen.lopnWidth.x=1; 
	logpen.lopnWidth.y=1; 
	COLORREF color=logpen.lopnColor; 
	BYTE red=(BYTE)(color & 0xFF); 
	BYTE green=(BYTE)(color>>8) & 0xFF; 
	BYTE blue=(BYTE)(color>>16) & 0xFF; 
 
	if ((green==255)&&(red==255)&&(blue==255)) 
	{ 
		red=0; 
		green=0; 
		blue=0; 
	} 
  
	if ((lineNum<1)||(lineNum>255)) return; 
	BYTE Rratio=(255-red)/(BYTE)lineNum;  
	BYTE Gratio=(255-green)/(BYTE)lineNum;  
	BYTE Bratio=(255-blue)/(BYTE)lineNum;  
	for (int i=0;iSelectObject(&pen); 
		else 
			pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
 
		pDC->MoveTo(rect.left+i,rect.top); 
		pDC->LineTo(rect.left+i,rect.bottom); 
 
		pDC->SelectObject(pOldPen); 
		pen.DeleteObject(); 
	} 
 
	for (i=0;iSelectObject(&pen); 
		else 
			pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
		pDC->MoveTo(rect.left+i+lineNum,rect.top); 
		pDC->LineTo(rect.left+i+lineNum,rect.bottom); 
		pDC->SelectObject(pOldPen); 
		pen.DeleteObject(); 
	} 
 
} 
 
void CDrawRect::DrawWarnbmp(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
	CMainFrame* pMW=(CMainFrame*)AfxGetApp()->m_pMainWnd; 
	m_bBrush=0; 
// 	pDC->Rectangle(rect); 
 
	if (pMW->pDib!=NULL) 
		pMW->pDib->Show(pDC,&rect); 
} 
 
/**/ 
 
void CDrawRect::Draw(CDC* pDC) 
{ 
	ASSERT_VALID(this); 
  
	CBrush brush; 
	if (!brush.CreateBrushIndirect(&m_logbrush)) 
		return; 
	CPen pen; 
	if (!pen.CreatePenIndirect(&m_logpen)) 
		return; 
 
	CBrush* pOldBrush; 
	CPen* pOldPen; 
 
	if (m_bBrush) 
		pOldBrush = pDC->SelectObject(&brush); 
	else 
		pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH); 
 
	if (m_bPen) 
		pOldPen = pDC->SelectObject(&pen); 
	else 
		pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
 
	CRect rect = m_position; 
		 
	switch (m_nShape) 
	{ 
	case rectangle: 
		pDC->Rectangle(rect); 
		break; 
 
	case roundRectangle: 
		pDC->RoundRect(rect, m_roundness); 
		break; 
 
	case ellipse: 
		pDC->Ellipse(rect); 
		break; 
 
	case circle: 
		DrawCircle(pDC,rect); 
		break; 
	case hpipe: 
		DrawHpipe(pDC,rect); 
		break; 
	case vpipe: 
		DrawVpipe(pDC,rect); 
		break; 
	case warnbmp: 
		DrawWarnbmp(pDC,rect); 
		break; 
 
	case liquid: 
		DrawLiquid(pDC,rect); 
		break; 
 
	case pump: 
		DrawPump(pDC,rect); 
		break; 
	case spos: 
		{ 
			int cx,cy; 
			if (rect.right < rect.left) 
			{ 
				cx = rect.left; 
				rect.left = rect.right; 
				rect.right = cx; 
			} 
			if (rect.bottom < rect.top) 
			{ 
				cy = rect.top; 
				rect.top = rect.bottom; 
				rect.bottom = cy; 
			} 
			double sw=(float)(abs(rect.bottom-rect.top))/255.0*(float)m_nSW; 
			/* 
			CString Sval; 
			Sval.Format("%.1f",m_nSWval); 
			pDC->ExtTextOut(rect.right,rect.bottom,ETO_OPAQUE,rect,Sval,NULL); 
			*/ 
			CBrush brsh((COLORREF)m_logpen.lopnColor); 
			 
 			CBrush* pOldBr; 
			pOldBr=pDC->SelectObject(&brsh); 
			pDC->Rectangle(rect); 
			pDC->SelectObject(pOldBr); 
 
			rect.bottom=rect.top+(int)sw; 
			pDC->Rectangle(rect); 
		break; 
		} 
	case ladder: 
		{ 
			int len=m_roundness.x; 
			int cx,cy; 
			if (rect.right < rect.left) 
			{ 
				cx = rect.left; 
				rect.left = rect.right; 
				rect.right = cx; 
			} 
			if (rect.bottom < rect.top) 
			{ 
				cy = rect.top; 
				rect.top = rect.bottom; 
				rect.bottom = cy; 
			} 
			CPoint p[4]; 
			p[0].x=rect.left+len;	  
			p[0].y=rect.bottom; 
			p[1].x=rect.right-len;  
			p[1].y=rect.bottom; 
			p[2].x=rect.right;                
			p[2].y=rect.top; 
			p[3].x=rect.left;                 
			p[3].y=rect.top; 
			pDC->SetPolyFillMode(WINDING); 
			pDC->Polygon(p,4); 
			break; 
		} 
	case line: 
		if (rect.top > rect.bottom) 
		{ 
			rect.top -= m_logpen.lopnWidth.y / 2; 
			rect.bottom += (m_logpen.lopnWidth.y + 1) / 2; 
		} 
		else 
		{ 
			rect.top += (m_logpen.lopnWidth.y + 1) / 2; 
			rect.bottom -= m_logpen.lopnWidth.y / 2; 
		} 
 
		if (rect.left > rect.right) 
		{ 
			rect.left -= m_logpen.lopnWidth.x / 2; 
			rect.right += (m_logpen.lopnWidth.x + 1) / 2; 
		} 
		else 
		{ 
			rect.left += (m_logpen.lopnWidth.x + 1) / 2; 
			rect.right -= m_logpen.lopnWidth.x / 2; 
		} 
 
		pDC->MoveTo(rect.TopLeft()); 
		pDC->LineTo(rect.BottomRight()); 
		break; 
	} 
 
	pDC->SelectObject(pOldBrush); 
	pDC->SelectObject(pOldPen); 
} 
 
 
int CDrawRect::GetHandleCount() 
{ 
	ASSERT_VALID(this); 
	if (m_nShape == line) return 2; 
	if (m_nShape == ladder) return CDrawObj::GetHandleCount()+2; 
	return CDrawObj::GetHandleCount() + (m_nShape == roundRectangle); 
} 
 
// returns center of handle in logical coordinates 
CPoint CDrawRect::GetHandle(int nHandle) 
{ 
	ASSERT_VALID(this); 
 
	if (m_nShape == line && nHandle == 2) 
		nHandle = 5; 
 
	if (m_nShape == roundRectangle && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point = rect.BottomRight(); 
		point.x -= m_roundness.x / 2; 
		point.y -= m_roundness.y / 2; 
		return point; 
	} 
 
	if (m_nShape == ladder && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point = rect.BottomRight(); 
		point.x = rect.right-m_roundness.x; 
		return point; 
	} 
 
	if (m_nShape == ladder && nHandle == 10) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point; 
		point.x= rect.left; 
		point.y= rect.bottom; 
		point.x = rect.left+m_roundness.x; 
 		return point; 
	} 
 
	return CDrawObj::GetHandle(nHandle); 
} 
 
HCURSOR CDrawRect::GetHandleCursor(int nHandle) 
{ 
	ASSERT_VALID(this); 
 
	if (m_nShape == line && nHandle == 2) 
		nHandle = 5; 
	if (m_nShape == roundRectangle && nHandle == 9) 
		return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); 
 
	if (m_nShape == ladder && nHandle == 9) 
		return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); 
	if (m_nShape == ladder && nHandle == 10) 
		return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); 
 
	return CDrawObj::GetHandleCursor(nHandle); 
} 
 
// point is in logical coordinates 
void CDrawRect::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
 
	if (m_nShape == line && nHandle == 2) 
		nHandle = 5; 
 
	if (m_nShape == roundRectangle && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		if (point.x > rect.right - 1) 
			point.x = rect.right - 1; 
		else if (point.x < rect.left + rect.Width() / 2) 
			point.x = rect.left + rect.Width() / 2; 
		if (point.y > rect.bottom - 1) 
			point.y = rect.bottom - 1; 
		else if (point.y < rect.top + rect.Height() / 2) 
			point.y = rect.top + rect.Height() / 2; 
		m_roundness.x = 2 * (rect.right - point.x); 
		m_roundness.y = 2 * (rect.bottom - point.y); 
		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else 
			pView->InvalObj(this); 
		return; 
	} 
 
	if (m_nShape == ladder && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
 
		int x= rect.right - point.x; 
		if ((x<0) || (x>rect.Width())) 
			return; 
		m_roundness.x=x; 
 
		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else 
			pView->InvalObj(this); 
 
		return; 
	} 
 
	if (m_nShape == ladder && nHandle == 10) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
 
		int x = point.x - rect.left; 
		if ((x<0) || (x>rect.Width())) 
			return; 
		m_roundness.x=x; 
 
 		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else 
			pView->InvalObj(this); 
		return; 
	} 
 
	CDrawObj::MoveHandleTo(nHandle, point, pView); 
} 
 
// rect must be in logical coordinates 
BOOL CDrawRect::Intersects(const CRect& rect) 
{ 
	ASSERT_VALID(this); 
 
	CRect rectT = rect; 
	rectT.NormalizeRect(); 
 
	CRect fixed = m_position; 
	fixed.NormalizeRect(); 
	if ((rectT & fixed).IsRectEmpty()) 
		return FALSE; 
 
	CRgn rgn; 
	switch (m_nShape) 
	{ 
	case rectangle: 
		return TRUE; 
 
	case roundRectangle: 
		rgn.CreateRoundRectRgn(fixed.left, fixed.top, fixed.right, fixed.bottom, 
			m_roundness.x, m_roundness.y); 
		break; 
 
	case ellipse: 
		rgn.CreateEllipticRgnIndirect(fixed); 
		break; 
 
	case line: 
		{ 
			int x = (m_logpen.lopnWidth.x + 5) / 2; 
			int y = (m_logpen.lopnWidth.y + 5) / 2; 
			POINT points[4]; 
			points[0].x = fixed.left; 
			points[0].y = fixed.top; 
			points[1].x = fixed.left; 
			points[1].y = fixed.top; 
			points[2].x = fixed.right; 
			points[2].y = fixed.bottom; 
			points[3].x = fixed.right; 
			points[3].y = fixed.bottom; 
 
			if (fixed.left < fixed.right) 
			{ 
				points[0].x -= x; 
				points[1].x += x; 
				points[2].x += x; 
				points[3].x -= x; 
			} 
			else 
			{ 
				points[0].x += x; 
				points[1].x -= x; 
				points[2].x -= x; 
				points[3].x += x; 
			} 
 
			if (fixed.top < fixed.bottom) 
			{ 
				points[0].y -= y; 
				points[1].y += y; 
				points[2].y += y; 
				points[3].y -= y; 
			} 
			else 
			{ 
				points[0].y += y; 
				points[1].y -= y; 
				points[2].y -= y; 
				points[3].y += y; 
			} 
			rgn.CreatePolygonRgn(points, 4, ALTERNATE); 
		} 
		break; 
	case circle: 
		rgn.CreateEllipticRgnIndirect(fixed); 
		break; 
	case hpipe: 
		return TRUE; 
	case vpipe: 
		return TRUE; 
	case warnbmp: 
		return TRUE; 
	case liquid: 
		return TRUE; 
	case pump: 
		return TRUE; 
	case spos: 
		return TRUE; 
 
	case ladder: 
		//rgn.CreateRoundRectRgn(fixed.left, fixed.top, fixed.right, fixed.bottom, 
		//						 m_roundness.x, m_roundness.y); 
		//break; 
		return TRUE; 
	} 
	return rgn.RectInRegion(fixed); 
} 
 
CDrawObj* CDrawRect::Clone(CDrawDoc* pDoc) 
{ 
	ASSERT_VALID(this); 
 
	CDrawRect* pClone = new CDrawRect(m_position); 
 
	pClone->m_bPen = m_bPen; 
	pClone->m_logpen = m_logpen; 
	pClone->m_bBrush = m_bBrush; 
	pClone->m_logbrush = m_logbrush; 
	pClone->m_nShape = m_nShape; 
	pClone->m_roundness = m_roundness; 
	pClone->mv_bLock = mv_bLock; 
	pClone->mv_nRtu = mv_nRtu; 
	pClone->mv_nPar = mv_nPar; 
	pClone->mv_nType = mv_nType; 
	pClone->mv_nInt = mv_nInt; 
	pClone->mv_nDec = mv_nDec; 
	pClone->mv_nWard = mv_nWard; 
	pClone->mv_bInvalid = mv_bInvalid; 
 
	ASSERT_VALID(pClone); 
 
	if (pDoc != NULL) 
		pDoc->Add(pClone); 
 
	ASSERT_VALID(pClone); 
 
	return pClone; 
} 
//////////////////////////////////////////////////////////////////////////// 
 
IMPLEMENT_SERIAL(CDrawOleObj, CDrawObj, 0) 
 
BOOL CDrawOleObj::c_bShowItems = FALSE; //TRUE; 
 
CDrawOleObj::CDrawOleObj() : m_extent(0,0) 
{ 
	m_pClientItem = NULL; 
} 
 
CDrawOleObj::CDrawOleObj(const CRect& position) 
	: CDrawObj(position), m_extent(0, 0) 
{ 
	m_pClientItem = NULL; 
} 
 
CDrawOleObj::~CDrawOleObj() 
{ 
	if (m_pClientItem != NULL) 
	{ 
		m_pClientItem->Release(); 
		m_pClientItem = NULL; 
	} 
} 
 
void CDrawOleObj::Remove() 
{ 
	if (m_pClientItem != NULL) 
	{ 
		m_pClientItem->Delete(); 
		m_pClientItem = NULL; 
	} 
	CDrawObj::Remove(); 
} 
 
void CDrawOleObj::Serialize( CArchive& ar ) 
{ 
	ASSERT_VALID(this); 
 
	CDrawObj::Serialize(ar); 
 
	if (ar.IsStoring()) 
	{ 
		ar << m_extent; 
		ar << m_pClientItem; 
	} 
	else 
	{ 
		ar >> m_extent; 
		ar >> m_pClientItem; 
		m_pClientItem->m_pDrawObj = this; 
	} 
 } 
 
CDrawObj* CDrawOleObj::Clone(CDrawDoc* pDoc) 
{ 
	ASSERT_VALID(this); 
  
	AfxGetApp()->BeginWaitCursor(); 
 
	CDrawOleObj* pClone = NULL; 
	CDrawItem* pItem = NULL; 
  
	TRY 
	{ 
		// perform a "deep copy" -- need to copy CDrawOleObj and the CDrawItem 
		//  that it points to. 
		CDrawOleObj* pClone = new CDrawOleObj(m_position); 
		CDrawItem* pItem = new CDrawItem(m_pDocument, pClone); 
		if (!pItem->CreateCloneFrom(m_pClientItem)) 
			AfxThrowMemoryException(); 
 
		pClone->m_pClientItem = pItem; 
		pClone->m_bPen = m_bPen; 
		pClone->m_logpen = m_logpen; 
		pClone->m_bBrush = m_bBrush; 
		pClone->m_logbrush = m_logbrush; 
		pClone->mv_bLock = mv_bLock; 
		pClone->mv_nRtu = mv_nRtu; 
		pClone->mv_nPar = mv_nPar; 
		pClone->mv_nType = mv_nType; 
		pClone->mv_nInt = mv_nInt; 
		pClone->mv_nDec = mv_nDec; 
		pClone->mv_nWard = mv_nWard; 
		pClone->mv_bInvalid = mv_bInvalid; 
		ASSERT_VALID(pClone); 
 
		if (pDoc != NULL) 
			pDoc->Add(pClone); 
	} 
	CATCH_ALL(e) 
	{ 
		pItem->Delete(); 
		pClone->m_pClientItem = NULL; 
		pClone->Remove(); 
		AfxGetApp()->EndWaitCursor(); 
 
		THROW_LAST(); 
	} 
	END_CATCH_ALL 
 
	AfxGetApp()->EndWaitCursor(); 
 
	return pClone; 
} 
 
void CDrawOleObj::Draw(CDC* pDC) 
{ 
	ASSERT_VALID(this); 
 
	CDrawItem* pItem = m_pClientItem; 
	if (pItem != NULL) 
	{ 
		// draw the OLE item itself 
		pItem->Draw(pDC, m_position); 
 
		// don't draw tracker in print preview or on printer 
		if (!pDC->IsPrinting()) 
		{ 
			// use a CRectTracker to draw the standard effects 
			CRectTracker tracker; 
			tracker.m_rect = m_position; 
			pDC->LPtoDP(tracker.m_rect); 
 
			if (c_bShowItems) 
			{ 
				// put correct border depending on item type 
				if (pItem->GetType() == OT_LINK) 
					tracker.m_nStyle |= CRectTracker::dottedLine; 
				else 
					tracker.m_nStyle |= CRectTracker::solidLine; 
			} 
 
			// put hatching over the item if it is currently open 
			if (pItem->GetItemState() == COleClientItem::openState || 
				pItem->GetItemState() == COleClientItem::activeUIState) 
			{ 
				tracker.m_nStyle |= CRectTracker::hatchInside; 
			} 
			tracker.Draw(pDC); 
		} 
	} 
} 
 
void CDrawOleObj::OnOpen(CDrawView* pView) 
{ 
	AfxGetApp()->BeginWaitCursor(); 
	m_pClientItem->DoVerb( 
#ifndef _MAC		 
		GetKeyState(VK_CONTROL) < 0 ? OLEIVERB_OPEN : OLEIVERB_PRIMARY, 
#else		 
		GetKeyState(VK_OPTION) < 0 ? OLEIVERB_OPEN : OLEIVERB_PRIMARY, 
#endif		 
		pView); 
	AfxGetApp()->EndWaitCursor(); 
} 
 
void CDrawOleObj::OnEditProperties() 
{ 
//	COlePropertiesDialog dlg(m_pClientItem, 100, 100, NULL); 
//	dlg.DoModal(); 
	CDrawObj::OnEditProperties(); 
} 
 
// position is in logical 
void CDrawOleObj::MoveTo(const CRect& position, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
 
	if (position == m_position) 
		return; 
 
	// call base class to update position 
	CDrawObj::MoveTo(position, pView); 
 
	// update position of in-place editing session on position change 
	if (m_pClientItem->IsInPlaceActive()) 
		m_pClientItem->SetItemRects(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////// 
// CDrawText 
 
IMPLEMENT_SERIAL(CDrawText, CDrawObj, 0) 
 
CDrawText::CDrawText() 
{ 
 
} 
 
CDrawText::CDrawText(const CRect& position) 
	: CDrawRect(position) 
{ 
	ASSERT_VALID(this); 
	m_text="1234567890"; 
	m_GS=""; 
	m_bBorder=TRUE; 
    m_nShape=rectangle; 
	strcpy(m_logfont.lfFaceName, "Times"); 
	m_logfont.lfWeight=FW_REGULAR; 
	m_logfont.lfWidth=0; 
	m_logfont.lfHeight=0; 
	m_logfont.lfItalic=FALSE; 
	m_logfont.lfOrientation=0; 
	m_logfont.lfEscapement=0; 
	m_logfont.lfUnderline=FALSE; 
	m_logfont.lfStrikeOut=FALSE; 
	m_logfont.lfOutPrecision=OUT_OUTLINE_PRECIS; 
	m_logfont.lfCharSet=ANSI_CHARSET; 
	m_logfont.lfOutPrecision=OUT_DEFAULT_PRECIS;  
	m_logfont.lfPitchAndFamily=FF_MODERN|DEFAULT_PITCH; 
	m_color=RGB(0,0,0); 
} 
void CDrawText::Serialize(CArchive& ar) 
{ 
	ASSERT_VALID(this); 
 
	CDrawRect::Serialize(ar); 
	if (ar.IsStoring()) 
	{ 
		ar << m_bBorder; 
		ar << m_text; 
		ar << m_GS; 
		ar.Write(&m_logfont, sizeof(LOGFONT)); 
		ar <> m_bBorder; 
		ar >> m_text; 
		ar >> m_GS; 
		ar.Read(&m_logfont, sizeof(LOGFONT)); 
		ar >>m_color; 
		ar >> wTemp; m_allignment = (int)wTemp; 
	} 
} 
 
void CDrawText::Draw(CDC* pDC) 
{ 
	ASSERT_VALID(this); 
 
    if (m_bBorder>=0 && m_bBorder<3 ){ //if have border 
		CDrawRect::Draw(pDC); 
	} 
    //drawthe text here; 
	CFont font; 
	if (!font.CreateFontIndirect(&m_logfont)) 
		return; 
    CFont *pOldFont=(CFont *)pDC->SelectObject(&font); 
	int x=(m_position.left < m_position.right)? m_position.left: m_position.right; 
	int y=(m_position.top > m_position.bottom)? m_position.top:m_position.bottom; 
    COLORREF oldColor2=pDC->SetTextColor(m_color); 
	//calculate the x, y 
	int dy=abs(m_position.top - m_position.bottom); 
	int dx=abs(m_position.left -m_position.right); 
	int lx= TextLen(pDC);//length of your string; 
    int ly= MaxHeight(pDC);//hight of the string; 
//www 
    Resize(lx+2*m_logpen.lopnWidth.x+2*PADDING, 
		ly+m_logpen.lopnWidth.x*2+2*PADDING); //resize the m_position, by the new lenght and height of string 
 
    switch(m_allignment){ 
	case 0: //left 
		x+=m_logpen.lopnWidth.x + PADDING; 
		y-=(dy-ly)/2; 
		//y-=m_logpen.lopnWidth.x + PADDING; 
		break; 
	case 1: //middle 
		x+=(dx-lx)/2; 
		y-=(dy-ly)/2; 
		break; 
	case 2: //right 
		x+=dx-lx-PADDING-m_logpen.lopnWidth.x; 
		y-=(dy-ly)/2; 
		//y-=(dy-ly+PADDING+m_logpen.lopnWidth.x); 
		break; 
	default: //middle 
		x+=(dx-lx)/2; 
		y-=(dy-ly)/2; 
		break; 
	} 
 
	int oldMode; 
	oldMode=pDC->SetBkMode(TRANSPARENT); 
	pDC->ExtTextOut(x,y,ETO_OPAQUE,NULL,m_text,NULL); 
//    pDC->SetBkColor(oldColor); 
    pDC->SetTextColor(oldColor2); 
    pDC->SelectObject(pOldFont); 
	pDC->SetBkMode(oldMode); 
} 
 
 
int CDrawText::GetHandleCount() 
{ 
	ASSERT_VALID(this); 
	if (m_nShape == ladder) return CDrawObj::GetHandleCount() + 2; 
	return CDrawObj::GetHandleCount() + (m_nShape == roundRectangle); 
} 
 
// returns center of handle in logical coordinates 
CPoint CDrawText::GetHandle(int nHandle) 
{ 
	ASSERT_VALID(this); 
    if (m_nShape == roundRectangle && nHandle == 9) 
		{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point = rect.BottomRight(); 
		point.x -= m_roundness.x / 2; 
		point.y -= m_roundness.y / 2; 
		return point; 
		} 
    if (m_nShape == ladder && nHandle == 9) 
		{ 
 		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point = rect.BottomRight(); 
 		point.x = rect.right-m_roundness.x; 
		return point; 
		} 
    if (m_nShape == ladder && nHandle == 10) 
		{ 
 		CRect rect = m_position; 
		rect.NormalizeRect(); 
		CPoint point = rect.TopLeft(); 
 		point.x = rect.left+m_roundness.x; 
		return point; 
		} 
	return CDrawObj::GetHandle(nHandle); 
} 
 
HCURSOR CDrawText::GetHandleCursor(int nHandle) 
{ 
	ASSERT_VALID(this); 
	if (m_nShape == roundRectangle && nHandle == 9) 
		return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); 
	if (m_nShape == ladder && nHandle == 10) 
		return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); 
	return CDrawObj::GetHandleCursor(nHandle); 
} 
 
// point is in logical coordinates 
void CDrawText::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
	if (m_nShape == roundRectangle && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
		if (point.x > rect.right - 1) 
			point.x = rect.right - 1; 
		else if (point.x < rect.left + rect.Width() / 2) 
			point.x = rect.left + rect.Width() / 2; 
		if (point.y > rect.bottom - 1) 
			point.y = rect.bottom - 1; 
		else if (point.y < rect.top + rect.Height() / 2) 
			point.y = rect.top + rect.Height() / 2; 
		m_roundness.x = 2 * (rect.right - point.x); 
		m_roundness.y = 2 * (rect.bottom - point.y); 
		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else{ 
			pView->InvalObj(this); 
			Resize(pView); 
		} 
		return; 
	} 
 
	if (m_nShape == ladder && nHandle == 9) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
 
		int x= rect.right - point.x; 
		if ((x<0) || (x>rect.Width())) 
			return; 
		m_roundness.x=x; 
 
		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else{ 
			pView->InvalObj(this); 
			Resize(pView); 
		} 
		return; 
	} 
	if (m_nShape == ladder && nHandle == 10) 
	{ 
		CRect rect = m_position; 
		rect.NormalizeRect(); 
 
		int x = point.x - rect.left; 
		if ((x<0) || (x>rect.Width())) 
			return; 
		m_roundness.x=x; 
 
		m_pDocument->SetModifiedFlag(); 
		if (pView == NULL) 
			Invalidate(); 
		else{ 
			pView->InvalObj(this); 
			Resize(pView); 
		} 
		return; 
	} 
 
    //nHandle dicide with point is moved 
	CDrawObj::MoveHandleTo(nHandle, point, pView);    //make sure the movement is good 
	Resize(pView); 
    //must resize 
} 
 
// rect must be in logical coordinates 
BOOL CDrawText::Intersects(const CRect& rect) 
{ 
	ASSERT_VALID(this); 
    CRect rectT = rect; 
	rectT.NormalizeRect(); 
 
	CRect fixed = m_position; 
	fixed.NormalizeRect(); 
 
	//sometimes vertical line  
	if ((rectT & fixed).IsRectEmpty()) 
			return FALSE; 
 
	CRgn rgn; 
	switch (m_nShape) 
	{ 
	case rectangle: 
		return TRUE; 
 
	case roundRectangle: 
		rgn.CreateRoundRectRgn(fixed.left, fixed.top, fixed.right, fixed.bottom, 
			m_roundness.x, m_roundness.y); 
		break; 
 
	case ladder: 
		//rgn.CreateRoundRectRgn(fixed.left, fixed.top, fixed.right, fixed.bottom, 
		//						 m_roundness.x, m_roundness.y); 
		//break; 
		return TRUE; 
 
	case ellipse: 
		rgn.CreateEllipticRgnIndirect(fixed); 
		break; 
 
	case line: 
//	case arrow: 
		return TRUE; 
		break; 
	} 
	//return rgn.RectInRegion(fixed); error! 
	return rgn.RectInRegion(rectT); 
} 
 
CDrawObj* CDrawText::Clone(CDrawDoc* pDoc) 
{ 
	ASSERT_VALID(this); 
 
	CDrawText* pClone = new CDrawText(m_position); 
	pClone->m_bPen = m_bPen; 
	pClone->m_logpen = m_logpen; 
	pClone->m_bBrush = m_bBrush; 
	pClone->m_logbrush = m_logbrush; 
	pClone->m_nShape = m_nShape; 
	pClone->m_roundness = m_roundness; 
    pClone->m_text=m_text; 
    pClone->m_GS=m_GS; 
	pClone->m_allignment=m_allignment; 
	pClone->m_bBorder=m_bBorder; 
	ASSERT_VALID(pClone); 
 
	if (pDoc != NULL) 
		pDoc->Add(pClone); 
 
	ASSERT_VALID(pClone); 
	return pClone; 
} 
 
void CDrawText::OnEditProperties() 
{ 
	ASSERT_VALID(this); 
 
	CPropertySheet sheet( _T("对象显示属性") ); 
	CRectDlg dlg; 
	dlg.m_bNoFill = !m_bBrush; 
	dlg.m_bLock = mv_bLock; 
	dlg.m_nRtu = mv_nRtu; 
	dlg.m_nPar = mv_nPar; 
	dlg.m_nType = mv_nType; 
	dlg.m_nInt = mv_nInt; 
	dlg.m_nDec = mv_nDec; 
	dlg.m_nWard = mv_nWard; 
	dlg.m_bInvalid = mv_bInvalid; 
 
	dlg.m_penSize = m_bPen ? m_logpen.lopnWidth.x : 0; 
	dlg.m_LineColor = m_logpen.lopnColor;	  /*xxx*/ 
    dlg.m_FillColor = m_logbrush.lbColor;	  /*xxx*/ 
	 
	CTextDlg textPage; 
	textPage.m_text=m_text; 
	textPage.m_GS=m_GS; 
	textPage.m_allignment=m_allignment; 
    textPage.m_font.DeleteObject(); 
	textPage.m_font.CreateFontIndirect(&m_logfont); 
	 
	textPage.m_borderType=(int)m_nShape; // 
	textPage.m_allignment=m_allignment; 
 
	sheet.AddPage( &textPage ); 
	sheet.AddPage( &dlg ); 
  
	if (sheet.DoModal() != IDOK) 
		return; 
 
	m_bBrush = !dlg.m_bNoFill; 
	mv_bLock = dlg.m_bLock ; 
	mv_nRtu=dlg.m_nRtu; 
	mv_nPar=dlg.m_nPar; 
	mv_nType=dlg.m_nType; 
	mv_nInt=dlg.m_nInt; 
	mv_nDec=dlg.m_nDec; 
	mv_nWard=dlg.m_nWard; 
	mv_bInvalid=dlg.m_bInvalid; 
 
	m_bPen = dlg.m_penSize > 0; 
	m_logbrush.lbColor = dlg.m_FillColor;   /*xxx*/ 
	if (m_bPen) 
	{ 
	    m_logpen.lopnWidth.x = dlg.m_penSize; 
		m_logpen.lopnWidth.y = dlg.m_penSize; 
		m_logpen.lopnColor = dlg.m_LineColor;   /*xxx*/ 
 
 	} 
 
	m_text=textPage.m_text; 
	m_GS=textPage.m_GS; 
	if(textPage.m_bFont) 
		textPage.m_font.GetLogFont(&m_logfont); 
	m_nShape=(CDrawRect::Shape)textPage.m_borderType; // 
	m_bBorder=textPage.m_borderType; 
	m_allignment=textPage.m_allignment; 
 
    //must resize 
	POSITION ps=m_pDocument->GetFirstViewPosition(); 
	CDrawView* pView=(CDrawView*)m_pDocument->GetNextView(ps); 
    Resize(pView); 
	 
 	Invalidate(); 
	m_pDocument->SetModifiedFlag();  
 
} 
 
void CDrawText::Resize(int x, int y) 
{ 
	if(abs(m_position.left-m_position.right)SelectObject(&font); 
	pDC->GetTextMetrics(&TM); 
    int x=TM.tmHeight+TM.tmExternalLeading;	 
    pDC->SelectObject(pOldFont); 
    return x; 
} 
 
void CDrawText::SetTextColor(COLORREF color) 
{ 
	ASSERT_VALID(this); 
	m_color = color; 
	Invalidate(); 
	m_pDocument->SetModifiedFlag(); 
} 
 
void CDrawText::SetText(CString text) 
{ 
	ASSERT_VALID(this); 
	m_text = text; 
	Invalidate(); 
	m_pDocument->SetModifiedFlag(); 
} 
 
void CDrawText::GetText(CString& text) 
{ 
	text=m_text;  
} 
 
void CDrawText::GetGS(CString& GS) 
{ 
	GS=m_GS;  
} 
 
int CDrawText::TextLen(CDC *pDC) 
{ 
	CFont font; 
	if (!font.CreateFontIndirect(&m_logfont)) 
		return 0; 
    CFont *pOldFont=(CFont *)pDC->SelectObject(&font); 
	CSize sz=pDC->GetTextExtent(m_text); 
    pDC->SelectObject(pOldFont); 
	return sz.cx; 
} 
 
void CDrawText::Resize(CDrawView* pView) 
{ 
	CClientDC CDC(pView); 
	CFont font; 
	if (!font.CreateFontIndirect(&m_logfont)) 
		return; 
    CFont *pOldFont=(CFont *)CDC.SelectObject(&font); 
	int lx= TextLen(&CDC);//length of your string; 
    int ly= MaxHeight(&CDC);//hight of the string; 
    Resize(lx+2*m_logpen.lopnWidth.x+2*PADDING, 
		ly+m_logpen.lopnWidth.x*2+2*PADDING); //resize the m_position, by the new lenght and height of string 
 
    CDC.SelectObject(pOldFont); 
} 
 
//www 
///////////////////////////////////////////////////////////////////////////// 
// CDrawPencil 
 
IMPLEMENT_SERIAL(CDrawPencil, CDrawObj, 0) 
CDrawPencil::CDrawPencil() 
{ 
	// This empty constructor should be used by serialization only 
} 
 
CDrawPencil::CDrawPencil(const CRect& position) 
	: CDrawObj(position) 
{ 
 	m_bPen = TRUE; 
	m_bBrush = FALSE; 
} 
 
void CDrawPencil::Serialize(CArchive& ar) 
{ 
	CDrawObj::Serialize( ar ); 
	if (ar.IsStoring()) 
	{ 
		m_pointArray.Serialize(ar); 
	} 
	else 
	{ 
		m_pointArray.Serialize(ar); 
	} 
} 
  
void CDrawPencil::Draw(CDC* pDC) 
{ 
	CPen pen; 
	if (!pen.CreatePenIndirect(&m_logpen)) 
		return; 
 	CPen* pOldPen; 
	if (m_bPen) 
		pOldPen = pDC->SelectObject(&pen); 
	else 
		pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN); 
	pDC->MoveTo(m_pointArray[0]); 
	for (int i=1; i < m_pointArray.GetSize(); i++) 
	{ 
		pDC->LineTo(m_pointArray[i]); 
		CPoint p=m_pointArray[i]; 
	} 
 
	pDC->SelectObject(pOldPen); 
	return ; 
} 
  
BOOL CDrawPencil::RecalcBounds(CDrawView* pView) 
{ 
	ASSERT_VALID(this); 
 
	if (m_pointArray.GetSize() == 0) 
		return FALSE; 
 
	CRect bounds(m_pointArray[0], CSize(0, 0)); 
	for (int i = 1; i < m_pointArray.GetSize(); ++i) 
	{ 
		if (m_pointArray[i].x < bounds.left) 
			bounds.left = m_pointArray[i].x; 
		if (m_pointArray[i].x > bounds.right) 
			bounds.right = m_pointArray[i].x; 
		if (m_pointArray[i].y < bounds.top) 
			bounds.top = m_pointArray[i].y; 
		if (m_pointArray[i].y > bounds.bottom) 
			bounds.bottom = m_pointArray[i].y; 
	} 
 
	if (bounds == m_position) 
		return FALSE; 
 
	if (pView == NULL) 
		Invalidate(); 
	else 
		pView->InvalObj(this); 
 
	m_position = bounds; 
 
	if (pView == NULL) 
		Invalidate(); 
	else 
		pView->InvalObj(this); 
 
	return TRUE; 
} 
 
CDrawObj* CDrawPencil::Clone(CDrawDoc* pDoc) 
{ 
	ASSERT_VALID(this); 
 
	CDrawPencil* pClone = new CDrawPencil(m_position); 
 
	pClone->m_bPen = m_bPen; 
	pClone->m_logpen = m_logpen; 
	pClone->m_bBrush = m_bBrush; 
	pClone->m_logbrush = m_logbrush; 
	pClone->mv_bLock = mv_bLock; 
 
	for (int i=0; i < m_pointArray.GetSize(); i++) 
	{ 
		pClone->m_pointArray.Add(m_pointArray[i]); 
	} 
  
	ASSERT_VALID(pClone); 
 
	if (pDoc != NULL) 
		pDoc->Add(pClone); 
 
	ASSERT_VALID(pClone); 
	 
	return pClone; 
} 
  
 
CDrawPencil::~CDrawPencil() 
{ 
} 
 
void CDrawPencil::MoveTo(const CRect& position, CDrawView* pView) 
{ 
 
	ASSERT_VALID(this); 
 
	if (mv_bLock)  //www 
		return; 
 
	if (position == m_position) 
		return; 
 
	if (pView == NULL) 
		Invalidate(); 
	else 
		pView->InvalObj(this); 
 
	for (int i = 0; i < m_pointArray.GetSize(); i += 1) 
	{ 
		m_pointArray[i].x += position.left - m_position.left; 
		m_pointArray[i].y += position.top - m_position.top; 
	} 
 
	m_position = position; 
 
	if (pView == NULL) 
		Invalidate(); 
	else 
		pView->InvalObj(this); 
	m_pDocument->SetModifiedFlag(); 
} 
 
int CDrawPencil::GetHandleCount() 
{ 
	ASSERT_VALID(this); 
	return CDrawObj::GetHandleCount() ; 
} 
 
CPoint CDrawPencil::GetHandle(int nHandle) 
{ 
 	ASSERT_VALID(this); 
  
	return CDrawObj::GetHandle(nHandle); 
} 
 
HCURSOR CDrawPencil::GetHandleCursor(int  nHandle) 
{ 
	ASSERT_VALID(this); 
 	return CDrawObj::GetHandleCursor(nHandle); 
} 
 
// point is in logical coordinates 
void CDrawPencil::MoveHandleTo(int nHandle, CPoint point, CDrawView* pView) 
{ 
 
	ASSERT_VALID(this); 
	ASSERT(nHandle >= 1 && nHandle <= 8); 
  
	if (m_pointArray.GetSize() > 0) 
	{ 
//		m_pointArray[m_pointArray.GetSize()-1]=point;  //wym 
	} 
	RecalcBounds(pView); 
 
	if (pView == NULL) 
		Invalidate(); 
	else 
		pView->InvalObj(this); 
	m_pDocument->SetModifiedFlag(); 
 
} 
 
// rect must be in logical coordinates 
BOOL CDrawPencil::Intersects(const CRect& rect) 
{ 
	ASSERT_VALID(this); 
	CRgn rgn; 
	if (m_pointArray.GetSize() > 0) 
    { 
		CRect bounds(m_pointArray[0], CSize(0, 0)); 
		for (int i = 1; i < m_pointArray.GetSize(); ++i) 
		{ 
			if (m_pointArray[i].x < bounds.left) 
				bounds.left = m_pointArray[i].x; 
			if (m_pointArray[i].x > bounds.right) 
				bounds.right = m_pointArray[i].x; 
			if (m_pointArray[i].y < bounds.top) 
				bounds.top = m_pointArray[i].y; 
			if (m_pointArray[i].y > bounds.bottom) 
				bounds.bottom = m_pointArray[i].y; 
		} 
		m_position = bounds; 
	} 
 	rgn.CreateRectRgnIndirect((LPCRECT)&m_position); 
	return rgn.RectInRegion(rect); 
} 
 
void CDrawRect::DrawLiquid(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
	int cx,cy; 
	if (rect.right < rect.left) 
		{ 
			cx = rect.left; 
			rect.left = rect.right; 
			rect.right = cx; 
		} 
	if (rect.bottom < rect.top) 
		{ 
			cy = rect.top; 
			rect.top = rect.bottom; 
			rect.bottom = cy; 
		} 
	cx = abs(rect.right - rect.left); 
    cy = abs(rect.bottom - rect.top); 
 
    CBrush bbrush(RGB(255,255,255)); 
 
	CBrush brush; 
	CBrush* pOldBrush; 
	CRect rt; 
	int n; 
	m_count=(m_count+1)%2; 
	if (cx>cy) 
	{ 
        n=cx/6; 
		rt.top=rect.top; 
		rt.bottom=rect.bottom; 
		for (int i=0;i<6;i++) 
		{ 
			rt.left=rect.left+i*n; 
			if (rt.left+(i+1)*n>rect.right) 
				rt.right=rect.right; 
			else 
				rt.right=rect.left+(i+1)*n; 
			if ((m_count+i)%2==0) 
				pOldBrush = pDC->SelectObject(&bbrush); 
 
 			pDC->Rectangle(rt); 
 
			if ((m_count+i)%2==0) 
 			    pDC->SelectObject(pOldBrush); 
		} 
	} 
	else 
	{ 
		n=cy/6; 
		rt.left=rect.left; 
		rt.right=rect.right; 
 
		for (int i=0;i<6;i++) 
		{ 
			rt.top=rect.top+i*n; 
			if (rt.top+(i+1)*n>rect.bottom) 
				rt.bottom=rect.bottom; 
			else 
				rt.bottom=rect.top+(i+1)*n; 
			if ((m_count+i)%2==0) 
				pOldBrush = pDC->SelectObject(&bbrush); 
 
			pDC->Rectangle(rt); 
 
			if ((m_count+i)%2==0) 
 				pDC->SelectObject(pOldBrush); 
		} 
 
	} 
} 
 
void CDrawRect::DrawPump(CDC* pDC,CRect rect) 
{ 
	ASSERT_VALID(this); 
 
	int cx,cy; 
	if (rect.right < rect.left) 
		{ 
			cx = rect.left; 
			rect.left = rect.right; 
			rect.right = cx; 
		} 
	if (rect.bottom < rect.top) 
		{ 
			cy = rect.top; 
			rect.top = rect.bottom; 
			rect.bottom = cy; 
		} 
	cx = rect.right - rect.left; 
    cy = rect.bottom - rect.top; 
	if (cx > cy) 
		{ 
			rect.left += (cx-cy) / 2; 
			rect.right = rect.left + cy; 
		} 
	else 
		{ 
            rect.top += (cy-cx) / 2; 
			rect.bottom = rect.top + cx; 
		} 
	cx = abs(cx); 
    cy = abs(cy); 
	int r=cx/2; 
 
	pDC->Ellipse(rect); 
 
	CBrush bbrush(RGB(255,255,255)); 
 
	CBrush brush; 
	CBrush* pOldBrush; 
 
	m_piecount=(m_piecount+1)%2; 
  
	int x1,y1,x2,y2; 
  
 	for (int i=0;i<8;i++) 
	{ 
 
		switch (i) 
		{ 
 
		case 0: 
			x1=rect.left; 
			y1=rect.top+r; 
			x2=rect.left; 
			y2=rect.top; 
			break; 
 
		case 1: 
			x1=rect.left; 
			y1=rect.top; 
			x2=rect.left+r; 
			y2=rect.top;  
			break; 
 
		case 2: 
			x1=rect.left+r; 
			y1=rect.top;  
			x2=rect.right; 
			y2=rect.top; 
			break; 
 
		case 3: 
			x1=rect.right; 
			y1=rect.top; 
			x2=rect.right; 
			y2=rect.top+r; 
			break; 
 
		case 4: 
			x1=rect.right; 
			y1=rect.top+r; 
			x2=rect.right; 
			y2=rect.bottom; 
			break; 
		case 5: 
			x1=rect.right; 
			y1=rect.bottom; 
			x2=rect.left+r; 
			y2=rect.bottom; 
			break; 
 
		case 6: 
			x1=rect.left+r; 
			y1=rect.bottom; 
			x2=rect.left; 
			y2=rect.bottom; 
			break; 
 
		case 7: 
			x1=rect.left; 
			y1=rect.bottom; 
			x2=rect.left; 
			y2=rect.top+r; 
			break; 
 
		} 
  
		if ((m_piecount+i)%2==0) 
		{ 
			pOldBrush = pDC->SelectObject(&bbrush); 
		} 
	 	pDC->Pie(rect,CPoint(x1,y1),CPoint(x2,y2)); 
 
		if ((m_piecount+i)%2==0) 
			pDC->SelectObject(pOldBrush); 
	} 
}