#include "StdAfx.h"
#include "DrawDoc.h"
#include "CommUtils.h"
IMPLEMENT_DYNCREATE(CDrawDoc, CDocument)
CDrawDoc::CDrawDoc():
m_ShapeList(),
m_Color(RGB(0xFF, 0xFF, 0xFF)),
m_ActiveShape(NULL)
{
m_Size.cx = 600;
m_Size.cy = 400;
}
CDrawDoc::~CDrawDoc()
{
ClearShape();
}
void CDrawDoc::Serialize( CArchive& ar )
{
CObject::Serialize(ar);
if (ar.IsStoring())
{
// 标识与版本
ar<<MND_FLAG;
ar<<MND_VER;
// 属性
ar<<m_Size.cx;
ar<<m_Size.cy;
ar<<m_Color;
// 序列化图形列表
m_ShapeList.Serialize(ar);
}
else
{
WORD wFlag;
ar>>wFlag;
if (wFlag != MND_FLAG)
{
MessageBox(AfxGetMainWnd()->GetSafeHwnd(), "打开的文件格式不对", "错误", MB_OK|MB_ICONERROR);
return;
}
BYTE bVer;
ar>>bVer;
ar>>m_Size.cx;
ar>>m_Size.cy;
ar>>m_Color;
m_ShapeList.Serialize(ar);
// 挂接文档类
CShape* pShape;
for (int i = 0; i < m_ShapeList.GetSize(); i++)
{
pShape = (CShape*)m_ShapeList[i];
pShape->InitData(this);
}
}
}
void CDrawDoc::SetSize( const SIZE& sz )
{
if ((sz.cx != m_Size.cx) || (sz.cy != m_Size.cy))
{
m_Size = sz;
UpdateAllViews(NULL);
SetModifiedFlag(TRUE);
}
}
const SIZE& CDrawDoc::GetSize()
{
return m_Size;
}
void CDrawDoc::SetColor( const COLORREF nColor )
{
if (nColor != m_Color)
{
m_Color = nColor;
UpdateAllViews(NULL);
SetModifiedFlag(TRUE);
}
}
COLORREF CDrawDoc::GetColor()
{
return m_Color;
}
int CDrawDoc::GetShapeCount()
{
return m_ShapeList.GetSize();
}
BOOL CDrawDoc::AddShape( CShape* pShape )
{
if (IndexOf(pShape) < 0)
{
m_ShapeList.Add(pShape);
RECT rcShape;
pShape->InitData(this);
pShape->GetShapeRect(rcShape);
UpdateAllViews(NULL, (long)&rcShape, 0);
SetModifiedFlag(TRUE);
return TRUE;
}
else
return FALSE;
}
BOOL CDrawDoc::RemoveShape( CShape* pShape )
{
int Idx = IndexOf(pShape);
if ( Idx >= 0 )
{
m_ShapeList.RemoveAt(Idx);
// 重新选定活动图形
if (m_ActiveShape == pShape)
{
if (m_ShapeList.GetSize() == 0)
SetActiveShape(NULL);
else if (Idx < m_ShapeList.GetSize())
SetActiveShape(GetShape(Idx));
else
SetActiveShape(GetShape(--Idx));
}
RECT rcShape;
pShape->GetShapeRect(rcShape);
delete pShape;
UpdateAllViews(NULL, (long)&rcShape, 0);
SetModifiedFlag(TRUE);
return TRUE;
}
else
return FALSE;
}
CShape* CDrawDoc::GetShape( int idx )
{
if ((idx < 0) || (idx >= m_ShapeList.GetSize()))
return NULL;
else
return (CShape*)m_ShapeList[idx];
}
int CDrawDoc::IndexOf( CShape* pShape )
{
for(int i = 0; i < m_ShapeList.GetSize(); i++)
if (pShape == m_ShapeList[i])
return i;
return -1;
}
BOOL CDrawDoc::MoveShape( CShape* pShape, int nNewPos )
{
int idx = IndexOf(pShape);
if ((idx < 0) || (idx == nNewPos) || (nNewPos < 0) || (nNewPos >= m_ShapeList.GetSize()))
return FALSE;
else
{
m_ShapeList.RemoveAt(idx);
m_ShapeList.InsertAt(nNewPos, pShape);
RECT rcShape;
pShape->GetShapeRect(rcShape);
UpdateAllViews(NULL, (long)&rcShape, 0);
SetModifiedFlag(TRUE);
return TRUE;
}
}
void CDrawDoc::SetActiveShape( CShape* pShape )
{
if (m_ActiveShape != pShape)
{
RECT rcOld, rcUpdate;
if (m_ActiveShape != NULL)
m_ActiveShape->GetShapeRect(rcOld);
else
memset(&rcOld, 0, sizeof(rcOld));
m_ActiveShape = pShape;
if (m_ActiveShape != NULL)
m_ActiveShape->GetShapeRect(rcUpdate);
else
memset(&rcUpdate, 0, sizeof(rcUpdate));
UnionRect(&rcUpdate, &rcUpdate, &rcOld);
if (!IsRectEmpty(&rcUpdate))
{
UpdateAllViews(NULL, (long)&rcUpdate, 0);
SetModifiedFlag(TRUE);
}
}
}
CShape* CDrawDoc::GetActiveShape()
{
return m_ActiveShape;
}
void CDrawDoc::ClearShape()
{
for (int i = 0; i < m_ShapeList.GetSize(); i++)
{
delete m_ShapeList[i];
}
m_ShapeList.RemoveAll();
}
CShape* CDrawDoc::GetShapeFromPoint( POINT& pt )
{
// 优先考虑在活动图形的拖动点上的情况
if ((m_ActiveShape != NULL) && (m_ActiveShape->HitTest(pt) == HT_DRAGPOINT))
return m_ActiveShape;
CShape* pShape;
for (int i = m_ShapeList.GetSize() - 1; i >= 0 ; i--)
{
pShape = GetShape(i);
int nTest = pShape->HitTest(pt);
if ((nTest == HT_INSHAPE) || (nTest == HT_DRAGPOINT))
return pShape;
}
return NULL;
}
//------------------------------------------------------------------------
//Shape
IMPLEMENT_DYNAMIC(CShape, CObject)
void CShape::InitData( CDrawDoc* pDrawDoc )
{
m_OwnerDoc = pDrawDoc;
}
CShape::CShape():
m_LineWidth(1),
m_LineColor(0),
m_FillColor(RGB(0xFF, 0xFF, 0xFF)),
m_Draging(FALSE),
m_OwnerDoc(NULL)
{
}
void CShape::SetLineWidth( const int nWidth )
{
if (m_LineWidth != nWidth)
{
RECT rcBefore;
GetShapeRect(rcBefore);
m_LineWidth = nWidth;
RECT rcAfter;
GetShapeRect(rcAfter);
UnionRect(&rcAfter, &rcAfter, &rcBefore);
UpdateView(rcAfter);
}
}
int CShape::GetLineWidth()
{
return m_LineWidth;
}
void CShape::SetLineColor( const COLORREF nColor )
{
if (m_LineColor != nColor)
{
m_LineColor = nColor;
RECT rcUpdate;
GetShapeRect(rcUpdate);
UpdateView(rcUpdate);
}
}
COLORREF CShape::GetLineColor()
{
return m_LineColor;
}
void CShape::SetFillColor( const COLORREF nColor )
{
if (m_FillColor != nColor)
{
m_FillColor = nColor;
RECT rcUpdate;
GetShapeRect(rcUpdate);
UpdateView(rcUpdate);
}
}
COLORREF CShape::GetFillColor()
{
return m_FillColor;;
}
void CShape::BeginDrag( POINT& pt )
{
m_Draging = TRUE;
DoBeginDrag(pt);
}
void CShape::EndDrag( POINT& pt )
{
m_Draging = FALSE;
DoEndDrag(pt);
}
void CShape::Draging( POINT& pt )
{
DoDraging(pt);
}
struct MY_DATA_TYPE
{
int msgtype;
RECT rect;
};
void CShape::UpdateView(RECT& rcUpdate)
{
MY_DATA_TYPE data;
data.msgtype = 1;
data.rect = rcUpdate;
LPARAM* lparam = (LPARAM*)&data;
if (m_OwnerDoc != NULL)
{
m_OwnerDoc->UpdateAllViews(NULL, (long)&rcUpdate, 0);
m_OwnerDoc->SetModifiedFlag(TRUE);
}
}
void CShape::Serialize( CArchive& ar )
{
CObject::Serialize(ar);
if (ar.IsStoring())
{
ar<<m_LineWidth;
ar<<m_LineWidth;
ar<<m_FillColor;
}
else
{
ar>>m_LineWidth;
ar>>m_LineColor;
ar>>m_FillColor;
}
}
void CShape::GetDragPoint( RECT& rcDP, POINT& pt )
{
rcDP.left = pt.x - DPRADII;
rcDP.top = pt.y - DPRADII;
rcDP.right = pt.x + DPRADII;
rcDP.bottom = pt.y + DPRADII;
}
void CShape::DrawDragPoint( CDC* pDC, RECT& rcDP )
{
CBrush Brsh;
Brsh.CreateStockObject(BLACK_BRUSH);
pDC->FillRect(&rcDP, &Brsh);
}
BOOL CShape::IsDraging()
{
return m_Draging;
}
//------------------------------------------------------------------------
//MiniRect
IMPLEMENT_SERIAL(CShapeRect, CShape, 1)
void CShapeRect::SetRect( const RECT& rcBound )
{
if (!EqualRect(&rcBound, &m_rcBound))
{
RECT rcOld;
GetShapeRect(rcOld);
m_rcBound = rcBound;
RECT rcUpdate;
GetShapeRect(rcUpdate);
UnionRect(&rcUpdate, &rcUpdate, &rcOld);
UpdateView(rcUpdate);
}
}
const RECT& CShapeRect::GetRect()
{
return m_rcBound;
}
int CShapeRect::HitTest( POINT& pt )
{
if ((m_OwnerDoc != NULL) && (m_OwnerDoc->GetActiveShape() == this) && PtInDragPoint(pt))
return HT_DRAGPOINT;
if (PtInRect(&m_rcBound, pt))
return HT_INSHAPE;
else
return HT_OUTSHAPE;
}
void CShapeRect::DrawShape( CDC* pDC )
{
CBrush brsh(m_FillColor);
pDC->SelectObject(brsh);
CPen pen(PS_SOLID, m_LineWidth, m_LineColor);
pDC->SelectObject(pen);
pDC->Rectangle(&m_rcBound);
}
void CShapeRect::DrawDragPoints( CDC* pDC )
{
RECT rcDP;
POINT ptAngle;
//left top
ptAngle.x = m_rcBound.left;
ptAngle.y = m_rcBound.top;
GetDragPoint(rcDP, ptAngle);
DrawDragPoint(pDC, rcDP);
//left bottom
ptAngle.x = m_rcBound.left;
ptAngle.y = m_rcBound.bottom;
评论0