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;i SelectObject(&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;i SelectObject(&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;i SelectObject(&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;i SelectObject(&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); } }