Solved

error LNK2001: unresolved external symbol

Posted on 1998-08-08
18
2,399 Views
Last Modified: 2012-06-27
DrawObj.obj : error LNK2001: unresolved external symbol "public: virtual struct CRuntimeClass * __thiscall CDrawRect::GetRuntimeClass(void)const " (?GetRuntimeClass@CDrawRect@@UBEPAUCRuntimeClass@@XZ)
0
Comment
Question by:k1024
  • 7
  • 7
  • 2
  • +2
18 Comments
 

Author Comment

by:k1024
ID: 1169747
CDrawObj is a draw class in user defined class
and CDrawObj class is derived CObject class and have a serialize
function, and for a serialization, make a dynamic macro(DECLARE_SERIAL,IMPLEMENT_SERIAL) , but above error occor?
what can I do?, I don't know well
0
 
LVL 3

Expert Comment

by:xyu
ID: 1169748
Send more details please about Your project settings and Your source code
0
 
LVL 22

Expert Comment

by:nietod
ID: 1169749
>> CDrawObj is a draw class in user defined class
By "in" do you mean it is a class defined inside a class?

Is CDrawObj part fo the MFC class heirarchy?  That is, is it ultimately derived from CObj?  I suspect it is not, but you've used it as if it is.
0
 

Author Comment

by:k1024
ID: 1169750
this comment is not support file upload, and I write  detail below...
my project name: draw
project setting:MDI, database not support, CDrawView is derived CScrollView

files-1)DrawObj.h,DrawObj.cpp
2)DrawTool.h,DrawTool.cpp
3)Toolbar.h,Toolbar.cpp
4)draw.h,draw.cpp
5)drawDoc.h,drawDoc.cpp
6)drawView.h,drawView.cpp
7)MainFrm.h,MainFrm.cpp
8)ChildFrm.h,ChildFrm.cpp
9)StdAfx.cpp,StdAfx.h,resource.h

1)------DrawObj.h
//DrawObj.h

#ifndef  __DRAWOBJ_H__
#define  __DRAWOBJ_H__

#include <afxtempl.h>

class CDrawView;
class CDrawDoc;

enum SelectState {none,move,size,range,draw};
enum ToolShape {select,line,rectangle,ellipse,roundRect,arc};

class CDrawObj : public CObject
{
protected:
      //serialize
      DECLARE_SERIAL(CDrawObj);
      CDrawObj();

public:
      CDrawObj(const CRect& rect);

//data member
      CRect m_prev;  
      CRect m_rect;  
      CDrawDoc * m_pDocument;            
      ToolShape m_nShape;                  
//overrides
      virtual void Draw(CDC * pDC, BOOL bMouseDrag);
      virtual void Serialize(CArchive & ar);
      virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

      /////control point
      virtual CPoint GetCtrPointPosition(int nCtrID);
      virtual HCURSOR GetCtrPointCursor(int nCtrID);
      
      virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);

//operations
      void Remove();
      void Invalidate();

      CRect GetCtrPointRect(int nCtrID,CDrawView * pView);
      void DrawCtrPoints(CDC* pDC, SelectState state);
      
      int HitTest(CPoint point,CDrawView* pView,BOOL bSelected);
      BOOL IsCross(const CRect& rect);
      void MoveTo(const CRect& position,CDrawView* pView=NULL);

//implementation
public:
      virtual ~CDrawObj();

      
#ifdef  _DEBUG
      void AssertValid();
#endif

//implementating data
protected:
      LOGPEN      m_logPen;  
      LOGBRUSH m_logBrush;
      int m_nCtrCount;  
public:
      static       int c_nPenColor;  //pen color
      static      int c_nBrushColor; //brush color
      static      LOGPEN c_logPen ; //={PS_INSIDEFRAME,1L,RGB(0,0,0)};
      static      LOGBRUSH c_logBrush ; //={BS_SOLID,RGB(0,255,0),NULL};
};

//CDrawObj
//typedef CTypedPtrList<CObList, CDrawObj*> CDrawObjList;

typedef CTypedPtrList<CObList, CDrawObj*> CDrawObjList;

/////////////////////////

class CDrawLine : public CDrawObj
{
protected:
      DECLARE_SERIAL(CDrawLine);
      CDrawLine();
public:
      CDrawLine(const CRect& position);

//implementation
public:
      virtual void Serialize(CArchive & ar);
      virtual void Draw(CDC * pDC, BOOL bMouseDrag);
      virtual CDrawObj* Clone(CDrawDoc* pDoc,BOOL bAdd=TRUE);

      virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);
      
      /////control point
      virtual CPoint GetCtrPointPosition(int nCtrID);
      virtual HCURSOR GetCtrPointCursor(int nCtrID);

protected:
      friend class CDrawTools;
};

/////////////////////////


class CDrawRect : public CDrawObj
{
protected:
      DECLARE_SERIAL(CDrawRect);
      CDrawRect();
public:
      CDrawRect(const CRect& position);

//implementation
public:
      virtual void Serialize(CArchive & ar);
      virtual void Draw(CDC * pDC, BOOL bMouseDrag);
      virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

protected:
      friend class CDrawTools;
};

/////////////////////////


class CDrawRound : public CDrawObj
{
protected:
      DECLARE_SERIAL(CDrawRound);
      CDrawRound();
public:
      CDrawRound(const CRect& position);

//implementation
public:
      virtual void Serialize(CArchive & ar);
      virtual void Draw(CDC * pDC, BOOL bMouseDrag);
      virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

      /////control point
      virtual CPoint GetCtrPointPosition(int nCtrID);
      virtual HCURSOR GetCtrPointCursor(int nCtrID);
      
      virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);

protected:
      CPoint m_round;  
      CPoint m_startArc;
      friend class CDrawTools;
};

#endif

-------------------DrawObj.cpp
//DrawObj.cpp

#include "stdafx.h"
#include "draw.h"
#include "DrawObj.h"
#include "drawDoc.h"
#include "drawView.h"
#include "drawtool.h"


int CDrawObj::c_nPenColor=0;  //static
int CDrawObj::c_nBrushColor=13;  //static

LOGPEN CDrawObj::c_logPen={PS_INSIDEFRAME,1L,RGB(0,0,0)};  //default logPen,static
LOGBRUSH CDrawObj::c_logBrush={BS_SOLID,RGB(0,255,0),NULL};//default logbrush, static

IMPLEMENT_SERIAL(CDrawObj, CObject,0)

CDrawObj::CDrawObj()
{
}

CDrawObj::~CDrawObj()
{
}

CDrawObj::CDrawObj(const CRect& rect)
{
      m_rect=rect;
      m_pDocument=NULL;
      m_logPen=c_logPen;
      m_logBrush=c_logBrush;
}

void CDrawObj::Serialize(CArchive& ar)
{
      CObject::Serialize(ar);
      if(ar.IsStoring())
      {
            ar << m_rect;
            ar.Write(&m_logPen,sizeof(LOGPEN));
            ar.Write(&m_logBrush,sizeof(LOGBRUSH));
      }
      else
      {
            m_pDocument=(CDrawDoc*)ar.m_pDocument;
            ASSERT_VALID(m_pDocument);
            ASSERT_KINDOF(CDrawDoc,m_pDocument);

            ar >> m_rect;
            m_prev=m_rect;  
            ar.Read(&m_logPen,sizeof(LOGPEN));
            ar.Read(&m_logBrush,sizeof(LOGBRUSH));
      }

}//

void CDrawObj::Remove()
{
      delete this;
}//

void CDrawObj::Draw(CDC* pDC,BOOL bMouseDrag)
{
}//OK!

CDrawObj* CDrawObj::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
      ASSERT_VALID(this);
      
      CDrawObj* pClone=new CDrawObj(m_rect);
      pClone->m_logPen=m_logPen;
      pClone->m_logBrush=m_logBrush;
      
      ASSERT_VALID(pClone);
      
      
      if(pDoc!=NULL && bAdd)
            pDoc->Add(pClone);  
      return pClone;
}


void CDrawObj::Invalidate()
{
      ASSERT_VALID(this);
      m_pDocument->UpdateAllViews(NULL, HINT_UPDATE_SELECTION,this);
}


void CDrawObj::DrawCtrPoints(CDC* pDC, SelectState state)
{
      ASSERT_VALID(this);

      switch(state)
      {
      case none: break;
      case size:
      case range:
      case move:
      case draw:
            {
                  for(int nCtrID=1;nCtrID<=m_nCtrCount;nCtrID++)
                  {
                        CPoint point=GetCtrPointPosition(nCtrID);
                        //pDC->PatBlt(point.x-4,point.y-4,8,8,PATCOPY);
                        
                        pDC->Rectangle(point.x-4,point.y-4,point.x+4,point.y+4);
                  }
            }
            break;
      }
}


CRect CDrawObj::GetCtrPointRect(int nCtrID,CDrawView * pView)
{
      ASSERT_VALID(this);
      ASSERT(pView!=NULL);

      CRect rect;
      CPoint point=GetCtrPointPosition(nCtrID);
      pView->DocToClient(point);  
      rect.SetRect(point.x-4, point.y-4, point.x+4, point.y+4);
      pView->ClientToDoc(rect);  

      return rect;
}

CPoint CDrawObj::GetCtrPointPosition(int nCtrID)
{
      ASSERT_VALID(this);
      int x,y,xCenter,yCenter;

      xCenter=m_rect.left+m_rect.Width()/2;
      yCenter=m_rect.top+m_rect.Height()/2;
      
      switch(nCtrID)
      {
      case 1:
            x=m_rect.left;
            y=m_rect.top;
            break;
      case 2:
            x=xCenter;
            y=m_rect.top;
            break;
      case 3:
            x=m_rect.right;
            y=m_rect.top;
            break;
      case 4:
            x=m_rect.right;
            y=yCenter;
            break;
      case 5:
            x=m_rect.right;
            y=m_rect.bottom;
            break;
      case 6:
            x=xCenter;
            y=m_rect.bottom;
            break;
      case 7:
            x=m_rect.left;
            y=m_rect.bottom;
            break;
      case 8:
            x=m_rect.left;
            y=yCenter;
            break;
      default:
            
            ASSERT(FALSE);
      }
      return CPoint(x,y);
}


HCURSOR CDrawObj::GetCtrPointCursor(int nCtrID)
{
      ASSERT_VALID(this);

      
      LPCTSTR curname;
      switch(nCtrID)
      {
      case 1:
      case 5:
            curname=IDC_SIZENWSE;
            break;
      case 2:
      case 6:
            curname=IDC_SIZENS;
            break;
      case 3:
      case 7:
            curname=IDC_SIZENESW;
            break;
      case 4:
      case 8:
            curname=IDC_SIZEWE;
            break;
      default:
            ASSERT(FALSE);

      }
      //CWinApp::LoadStandardCursor
      //HCURSOR LoadStandardCursor( LPCTSTR lpszCursorName ) const;
      return AfxGetApp()->LoadStandardCursor(curname);
}



void CDrawObj::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
      ASSERT_VALID(this);
      CRect rect=m_rect;
      switch(nCtrID)
      {
      default:
            ASSERT(FALSE);

      case 1:
            rect.left=point.x;
            rect.top=point.y;
            break;
      case 2:
            rect.top=point.y;
            break;
      case 3:
            rect.right=point.x;
            rect.top=point.y;
            break;
      case 4:
            rect.right=point.x;
            break;
      case 5:
            rect.right=point.x;
            rect.bottom=point.y;
            break;
      case 6:
            rect.bottom=point.y;
            break;

      case 7:
            rect.left=point.x;
            rect.bottom=point.y;
            break;
      case 8:
            rect.left=point.x;
            break;
      }
      MoveTo(rect,pView);  //
}


int CDrawObj::HitTest(CPoint point,CDrawView* pView,BOOL bSelected)
{
      ASSERT_VALID(this);
      ASSERT(pView!=NULL);

      if(bSelected)
      {
            for(int nCtrID=1;nCtrID <= m_nCtrCount;nCtrID++)
            {
                  CRect rect=GetCtrPointRect(nCtrID,pView);
                  rect.NormalizeRect();
                  //BOOL PtInRect( POINT point ) const;
                  
                  if(rect.PtInRect(point)) return nCtrID;
            }
      }
      else
      {
            CRect rect(point,point);
            if(IsCross(rect)) return 1;  //
      }
      return 0;
}


BOOL CDrawObj::IsCross(const CRect& rect)
{
      ASSERT_VALID(this);

      CRect rectT=m_rect;
      rectT.NormalizeRect();
      CRect rc=rect;
      rc.NormalizeRect();
      //CRect operator &( const RECT& rect2 ) const;
      //BOOL IsRectEmpty( ) const;
      return !(rectT & rc).IsRectEmpty();
}



void CDrawObj::MoveTo(const CRect& position,CDrawView* pView)
{
      ASSERT_VALID(this);
      if(position == m_rect)
            return;
      if(pView==NULL)
      {
            Invalidate();
            m_rect=position;
            Invalidate();
      }
      else
      {
            CClientDC* pDC=new CClientDC(pView);
            pView->OnPrepareDC(pDC,NULL);
            Draw(pDC,TRUE);
            m_rect=position;
            Draw(pDC,TRUE);
            m_pDocument->SetModifiedFlag();
            delete pDC;
      }

}


#ifdef _DEBUG
void CDrawObj::AssertValid()
{
      ASSERT(m_rect.left <= m_rect.right);
      ASSERT(m_rect.bottom <= m_rect.top);
}
#endif

/////////////CDrawLine

IMPLEMENT_SERIAL(CDrawLine, CDrawObj, 0)

CDrawLine::CDrawLine()
{
      m_nCtrCount=2;  
}

CDrawLine::CDrawLine(const CRect& position)
            : CDrawObj(position)
{
      ASSERT_VALID(this);
      m_nCtrCount=2;
}

void CDrawLine::Serialize(CArchive& ar)
{
      ASSERT_VALID(this);
      CDrawObj::Serialize(ar);
}

void CDrawLine::Draw(CDC* pDC, BOOL bMouseDrag)
{
      ASSERT_VALID(this);  

      CPen pen;
      CBrush brush;
      //if(!pen.CreatePenIndirect(&m_logPen)) return;
      //brush object
      if(!brush.CreateBrushIndirect(&m_logBrush)) return;

      CPen* pOldPen;
      CBrush* pOldBrush;

      if(!bMouseDrag)
      {
            
            if(!pen.CreatePenIndirect(&m_logPen)) return;
            pOldBrush=pDC->SelectObject(&brush);
            pOldPen=pDC->SelectObject(&pen);
      }
      else
      {
            
            LOGPEN logPen;
            logPen.lopnStyle = PS_DOT;
            logPen.lopnWidth = CPoint(1,1);
            logPen.lopnColor = RGB(0,0,0);
            if (!pen.CreatePenIndirect(&logPen))            return;
            pOldBrush      = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
            pOldPen            = pDC->SelectObject(&pen);
            //pDC->SetROP2(R2_NOTXORPEN);
      }

      //CRect rect=m_rect;

      pDC->MoveTo(m_rect.TopLeft());
      pDC->LineTo(m_rect.BottomRight());

      pDC->SelectObject(pOldPen);
      pDC->SelectObject(pOldBrush);      


} //OK

CDrawObj* CDrawLine::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
      ASSERT_VALID(this);
      CDrawLine* pClone=new CDrawLine(m_rect);
      ASSERT_VALID(pClone);
      pClone->m_rect=m_rect;
      pClone->m_logPen=m_logPen;
      pClone->m_logBrush=m_logBrush;
      if(pDoc!=NULL && bAdd)
            pDoc->Add(pClone);
      
      return pClone;

}


void CDrawLine::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
      ASSERT_VALID(this);

      if(nCtrID==2) nCtrID=5;
      CDrawObj::MouseMove(nCtrID,point,pView);
}


CPoint CDrawLine::GetCtrPointPosition(int nCtrID)
{
      ASSERT_VALID(this);

      if(nCtrID==2) nCtrID=5;
      return CDrawObj::GetCtrPointPosition(nCtrID);
}

HCURSOR CDrawLine::GetCtrPointCursor(int nCtrID)
{
      ASSERT_VALID(this);

      if(nCtrID==2) nCtrID=5;
      return CDrawObj::GetCtrPointCursor(nCtrID);
}

///////////////////////
//CDrawRect

//IMPLEMENT_SREIAL( CDrawRect, CDrawObj, 0)

CDrawRect::CDrawRect()
{
      m_nCtrCount=8;
}
 
CDrawRect::CDrawRect(const CRect& position) : CDrawObj(position)
{
      ASSERT_VALID(this);
      //m_nShape=rectangle;
    m_nCtrCount=8;
}

void CDrawRect::Serialize(CArchive& ar)
{
      ASSERT_VALID(this);

      CDrawObj::Serialize(ar);
      if(ar.IsStoring())
      {
            ar << (WORD) m_nShape;  //ToolShape
            
      }
      else
      {
            WORD wTemp;
            ar >> wTemp;
            m_nShape=(ToolShape)wTemp;
            
      }
}//OK!

void CDrawRect::Draw(CDC* pDC,BOOL bMouseDrag)
{
      ASSERT_VALID(this);
      CPen pen;
      CBrush brush;
      CBrush * pOldBrush;
      CPen* pOldPen;

      if (!brush.CreateBrushIndirect(&m_logBrush))      return;

      if(!bMouseDrag)
      {
            if (!pen.CreatePenIndirect(&m_logPen))            return;
            pOldBrush      = pDC->SelectObject(&brush);
            pOldPen            = pDC->SelectObject(&pen);
      }
      else
      {
            LOGPEN logPen;
            logPen.lopnStyle = PS_DOT;
            logPen.lopnWidth = CPoint(1,1);
            logPen.lopnColor = RGB(0,0,0);

            if (!pen.CreatePenIndirect(&logPen))            return;
            pOldBrush      = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
            pOldPen            = pDC->SelectObject(&pen);
            //pDC->SetROP2(R2_NOTXORPEN);
      }
      CRect rect=m_rect;
      switch(m_nShape)
      {
      case rectangle:
            pDC->Rectangle(rect);
            break;
      case ellipse:
            pDC->Ellipse(rect);
            break;
      }
      pDC->SelectObject(pOldPen);
      pDC->SelectObject(pOldBrush);
}//OK!

CDrawObj* CDrawRect::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
      ASSERT_VALID(this);
      
      CDrawRect* pClone=new CDrawRect(m_rect);
      pClone->m_rect=m_rect;
      pClone->m_logPen=m_logPen;
      pClone->m_logBrush=m_logBrush;
      pClone->m_nShape=m_nShape;
      ASSERT_VALID(pClone);
      
      if(pDoc!=NULL && bAdd)
            pDoc->Add(pClone);  
      return pClone;
}

//////////////////////
////CDrawRound

IMPLEMENT_SERIAL( CDrawRound, CDrawObj, 0)

CDrawRound::CDrawRound()
{
      m_nCtrCount=9;
      m_round.y=m_round.x=16;  //CPoint m_round
      m_startArc.x=m_startArc.y=16;  //CPoint
}//OK!

CDrawRound::CDrawRound(const CRect & position) : CDrawObj(position)
{
      ASSERT_VALID(this);
      m_nCtrCount=9;
      m_round.y=m_round.x=16;  //CPoint m_round
      m_startArc.x=m_startArc.y=16;
}//OK!

void CDrawRound::Serialize(CArchive& ar)
{
      ASSERT_VALID(this);
      CDrawObj::Serialize(ar);
      if(ar.IsStoring())
      {
            ar << (WORD) m_nShape;  //ToolShape
            ar << m_round;
      }
      else
      {
            WORD wTemp;
            ar >> wTemp;
            m_nShape=(ToolShape)wTemp;
            ar >> m_round;
      }
}//OK!

void CDrawRound::Draw(CDC* pDC, BOOL bMouseDrag)
{
      ASSERT_VALID(this);
      CPen pen;
      CBrush brush;
      CBrush* pOldBrush;
      CPen*      pOldPen;      

      if (!brush.CreateBrushIndirect(&m_logBrush))      return;

      if (!bMouseDrag)      
      {
            if (!pen.CreatePenIndirect(&m_logPen))            return;
            pOldBrush      = pDC->SelectObject(&brush);
            pOldPen            = pDC->SelectObject(&pen);
      }
      else
      {
            LOGPEN logPen;
            logPen.lopnStyle = PS_DOT;
            logPen.lopnWidth = CPoint(1,1);
            logPen.lopnColor = RGB(0,0,0);

            if (!pen.CreatePenIndirect(&logPen))            return;
            pOldBrush= (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
            pOldPen      = pDC->SelectObject(&pen);
      //      pDC->SetROP2(R2_NOTXORPEN);
      }
      
      CRect rect=m_rect;
      switch(m_nShape)
      {
      case roundRect:
            pDC->RoundRect(rect, m_round);
            break;
      case arc:
            //BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd );
            pDC->Arc(rect,CPoint(rect.TopLeft()+m_startArc),CPoint(rect.BottomRight()-m_startArc));
            break;
      }
      pDC->SelectObject(pOldPen);
      pDC->SelectObject(pOldBrush);
}//OK!


CDrawObj* CDrawRound::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
      ASSERT_VALID(this);

      CDrawRound* pClone = new CDrawRound(m_rect);
      pClone->m_rect=m_rect;
      pClone->m_logPen=m_logPen;
      pClone->m_logBrush=m_logBrush;
      pClone->m_nShape=m_nShape;
      pClone->m_round=m_round;
      
      ASSERT_VALID(pClone);

      if (pDoc != NULL && bAdd)      pDoc->Add(pClone);

      return pClone;
}



CPoint CDrawRound::GetCtrPointPosition(int nCtrID)
{
      ASSERT_VALID(this);
      switch(m_nShape)
      {
      case arc:
            if(nCtrID==9)
            {
                  CRect rect=m_rect;
                  rect.NormalizeRect();
                  CPoint point;
                  point=rect.BottomRight();
                  point.x-=m_startArc.x/2;
                  point.y-=m_startArc.y/2;
                  return point;
            }
            break;
      case roundRect:
            if(nCtrID==9)
            {
                  CRect rect=m_rect;
                  rect.NormalizeRect();
                  CPoint point;
                  point=rect.BottomRight();
                  point.x-=m_round.x/2;  
                  point.y-=m_round.y/2;      
                  return point;
            }
            break;
      default:
            ASSERT(FALSE);

      }
      return CDrawObj::GetCtrPointPosition(nCtrID);
}


HCURSOR CDrawRound::GetCtrPointCursor(int nCtrID)
{
      ASSERT_VALID(this);
      if(nCtrID==9)
      {
            return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
      }
      return CDrawObj::GetCtrPointCursor(nCtrID);
}


void CDrawRound::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
      ASSERT_VALID(this);
      if(nCtrID==9)
      {
            CRect rect=m_rect;
            rect.NormalizeRect();
            
            
            if (point.x > rect.right)      point.x = rect.right;
            
            
            else if (point.x < rect.left + rect.Width() / 2)
                        point.x = rect.left + rect.Width() / 2;
            
            if (point.y > rect.bottom )      point.y = rect.bottom;
            
            
            else if (point.y < rect.top + rect.Height() / 2)
                        point.y = rect.top + rect.Height() / 2;

            if(m_nShape==roundRect)
            {
                  m_round.x = 2 * (rect.right - point.x);
                  m_round.y = 2 * (rect.bottom - point.y);
            }
            else
            {
                  m_startArc.x=2*(rect.right-point.x);
                  m_startArc.y=2*(rect.bottom-point.y);
            }
            m_pDocument->SetModifiedFlag();
            //if(pView==NULL)
            //      Invalidate();
            //else
                  pView->InvalDrawObj(this);
            return;
      }
      //baseclass@G mousemove H#Cb
      CDrawObj::MouseMove(nCtrID,point,pView);
}

2)------DrawTool.h
///////DrawTool.h
#include "DrawObj.h"

class CDrawView;

class CDrawTool
{
public:
//constructor
      CDrawTool(ToolShape shape);
      
//overridable operations
      virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);
//operation
      static CDrawTool* GetDrawTool(ToolShape shape);

//attributes
      ToolShape m_toolShape;
      
      static CPtrList            c_drawTools;
      static CPoint            c_startPoint;
      static CPoint            c_endPoint;
      static CPoint            c_tempPoint;
      static SelectState      c_selectState;
      static ToolShape      c_toolShape;

//destructor
      ~CDrawTool();
};

///////////////////////////////
//CSelectTool class

class CSelectTool : public CDrawTool
{
public:
//constructor
      CSelectTool();

//attributes
      int m_dragPointID; //?

//operations
      virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
      //virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);

protected:
      //CRect m_ctrRect;
};


////////////////////
//CDrawTools class

class CDrawTools : public CDrawTool
{
public:
//constructors
      CDrawTools(ToolShape shape);

//operations
      virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
      //virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
      virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);
      
};

----------DrawTool.cpp

/////DrawTool.cpp
#include "stdafx.h"

#include "DrawTool.h"
#include "DrawObj.h"
#include "DrawDoc.h"
#include "DrawView.h"
#include "mainfrm.h"

//CDrawTool* GetDrawTool(ToolShape shape);
CPtrList      CDrawTool::c_drawTools;
CPoint      CDrawTool::c_startPoint;
CPoint      CDrawTool::c_endPoint;
CPoint      CDrawTool::c_tempPoint;
SelectState      CDrawTool::c_selectState=none;
ToolShape      CDrawTool::c_toolShape=select;

static CSelectTool selectTool;
static CDrawTools lineTool(line);
static CDrawTools rectTool(rectangle);
static CDrawTools ellipseTool(ellipse);
static CDrawTools roundRectTool(roundRect);
static CDrawTools arcTool(arc);
 

CDrawTool::CDrawTool(ToolShape shape)
{
      m_toolShape=shape;
      c_drawTools.AddTail(this);
}

CDrawTool::~CDrawTool()
{
}

CDrawTool* CDrawTool::GetDrawTool(ToolShape shape)
{
      POSITION pos=c_drawTools.GetHeadPosition();
      while(pos!=NULL)
      {
            CDrawTool* pTool=(CDrawTool*)c_drawTools.GetNext(pos);
            if(pTool->m_toolShape==shape)
                  return pTool;
      }
      return NULL;
}

void CDrawTool::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      //CWnd* SetCapture( );
      pView->SetCapture();
      c_startPoint=point;
      c_endPoint=point;
}

void CDrawTool::OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      //int GetCount( ) const;
      

}

void CDrawTool::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      //BOOL ReleaseCapture(VOID)
      ReleaseCapture();

}

void CDrawTool::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      c_endPoint=point;
      //SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
      //if (pView->m_selectList.GetCount() == 1)
      //{
      //      CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
      //      pMainFrame->m_wndStatusBar.DrawCoordinate(2,CPoint(c_endPoint - c_startPoint));
      //}
}

/////////////////CSelectTool implementation
CSelectTool::CSelectTool():CDrawTool(select)
{
      c_selectState=none;  //static member
}

void CSelectTool::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      
      CDrawObj* pObj;
      CPoint logicalpoint=point;
      pView->ClientToDoc(logicalpoint);//?
      
      c_selectState=none;
      
      if(pView->m_selectList.GetCount()==1)
      {
            pObj=pView->m_selectList.GetHead();
            m_dragPointID=pObj->HitTest(logicalpoint,pView,TRUE);//HitTest controlID return
            if(m_dragPointID!=0)
            {
                  c_selectState=size;
                  //HCURSOR SetCursor( HCURSOR hCursor);
                  SetCursor(pObj->GetCtrPointCursor(m_dragPointID));
            }
       }
      
      if (c_selectState == none)
      {
            pObj = pView->GetDocument()->GetObjectAt(logicalpoint);//DrawDoc?!<- A$@G
            if (pObj != NULL)
            {
                  c_selectState = move;
                  pView->Select(pObj, (nFlags & MK_SHIFT) != 0);
             
                  if ((nFlags & MK_CONTROL) != 0)
                        pView->CloneSelect();
            }
      
            else
            {
                  c_selectState = range;
                  //      if ((nFlags & MK_SHIFT) == 0)
            //            pView->Select(NULL);
                  CClientDC dc(pView);
                  CRect rect(point.x, point.y, point.x, point.y);
                  rect.NormalizeRect();
                  dc.DrawFocusRect(rect);
            }
      }
      
      c_tempPoint = logicalpoint;
      CDrawTool::OnLButtonDown(pView, nFlags, point);

}

void CSelectTool::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      if (pView->GetCapture() == pView)
      {
            if (c_selectState == range)
            {
                  CClientDC dc(pView);
                  CRect rect(c_startPoint.x, c_startPoint.y, c_endPoint.x, c_endPoint.y);
                  rect.NormalizeRect();
                  dc.DrawFocusRect(rect);
                  pView->SelectWithinRect(rect, TRUE);
            }
            else if (c_selectState != none)
            {
                  POSITION pos = pView->m_selectList.GetHeadPosition();
                  while (pos != NULL)
                  {
                        CDrawObj* pObj = pView->m_selectList.GetNext(pos);

                        CRect tempRect = pObj->m_rect;
                        pObj->m_rect = pObj->m_prev;
                        pView->InvalDrawObj(pObj);      
                        pObj->m_prev = pObj->m_rect = tempRect;
                        pView->InvalDrawObj(pObj);      
                  }
                  pView->GetDocument()->UpdateAllViews(pView);
            }
      }
      CDrawTool::OnLButtonUp(pView, nFlags, point);
}

void CSelectTool::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      if (pView->GetCapture() != pView)
      {
            //AfxMessageBox("pView->GetCapture() != pView");
            if ( pView->m_selectList.GetCount() == 1)
            {
                  CDrawObj* pObj = pView->m_selectList.GetHead();
                  CPoint logical = point;
                  pView->ClientToDoc(logical);
                  int nHandle = pObj->HitTest(logical, pView, TRUE);
                  if (nHandle != 0)
                  {
                        SetCursor(pObj->GetCtrPointCursor(nHandle));
                        return;
                  }
            }
                  CDrawTool::OnMouseMove(pView, nFlags, point);
            return;
      }

      if (c_selectState == range)
      {
            CClientDC dc(pView);
            CRect rect(c_startPoint.x, c_startPoint.y, c_endPoint.x, c_endPoint.y);
            rect.NormalizeRect();
            dc.DrawFocusRect(rect);
            rect.SetRect(c_startPoint.x, c_startPoint.y, point.x, point.y);
            rect.NormalizeRect();
            dc.DrawFocusRect(rect);

            CDrawTool::OnMouseMove(pView, nFlags, point);
            return;
      }
      
      CPoint logical = point;
      pView->ClientToDoc(logical);
      CPoint delta = (CPoint)(logical - c_tempPoint);
      POSITION pos = pView->m_selectList.GetHeadPosition();
      while (pos != NULL)
      {
            CDrawObj* pObj = pView->m_selectList.GetNext(pos);
            CRect position = pObj->m_rect;
            if (c_selectState == move)
            {
                  position += delta;
                  pObj->MoveTo(position, pView);
            }
            else if (m_dragPointID != 0)
                  pObj->MouseMove( m_dragPointID, logical, pView);
      }
      c_tempPoint = logical;
      c_endPoint = point;
      if (c_selectState == size)
      {
            SetCursor(pView->m_selectList.GetHead()->GetCtrPointCursor(m_dragPointID));
            return;
      }
      CDrawTool::OnMouseMove(pView, nFlags, point);
}


////////////////CDrawTools implementation


CDrawTools::CDrawTools(ToolShape shape):CDrawTool(shape)
{
}

void CDrawTools::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      CDrawTool::OnLButtonDown(pView,nFlags,point);

      CPoint logical=point;
      pView->ClientToDoc(logical);
      c_tempPoint=logical;
      CDrawObj * pObj;

      switch(c_toolShape)
      {
      case line:
            {
                  pObj= new CDrawLine(CRect(logical,CSize(0,0)));
            }
            break;
      case rectangle:
            {
                  pObj=new CDrawRect(CRect(logical,CSize(0,0)));
                  pObj->m_nShape=rectangle;
            }
            break;
      case ellipse:
            {
                  pObj=new CDrawRect(CRect(logical,CSize(0,0)));
                  pObj->m_nShape=ellipse;
            }
            break;
      case roundRect:
            {
                  pObj=new CDrawRound(CRect(logical,CSize(0,0)));
                  pObj->m_nShape=roundRect;
            }
            break;
      case arc:
            {
                  pObj=new CDrawRound(CRect(logical,CSize(0,0)));
                  pObj->m_nShape=arc;
            }
            break;
      default:
            pObj=new CDrawLine(CRect(logical,CSize(0,0)));
            break;

      }

      pView->GetDocument()->Add(pObj);
      c_selectState=none;
      pView->OnUpdate(NULL,HINT_UPDATE_SELECTION,NULL);
      pView->m_selectList.RemoveAll();
      pView->m_selectList.AddTail(pObj);
}

void CDrawTools::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      if(point==c_startPoint)
      {
            CDrawObj* pObj=pView->m_selectList.GetTail();
            pView->GetDocument()->Remove(pObj);
            pObj->Remove();
            selectTool.OnLButtonDown(pView,nFlags,point);
      }
      
      else if(pView->m_selectList.GetCount()==1)
      {
            CDrawObj* pObj=pView->m_selectList.GetHead();
            c_selectState=draw;
            pView->InvalDrawObj(pObj);
            pObj->m_prev=pObj->m_rect;
      }
      CDrawTool::OnLButtonUp(pView,nFlags,point);
}

void CDrawTools::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
      if(pView->GetCapture() ==pView)
      {
            CPoint logicalpoint=point;
            pView->ClientToDoc(logicalpoint);
            CDrawObj* pObj=pView->m_selectList.GetHead();
            CRect rect=pObj->m_rect;
            rect.left=logicalpoint.x;
            rect.top=logicalpoint.y;
            pObj->MoveTo(rect,pView);
            c_tempPoint=logicalpoint;
      }

      CDrawTool::OnMouseMove(pView,nFlags,point);
}
--------------3)toolbar.h
/////toolbar.h
#ifndef __TOOLBAR_H__
#define __TOOLBAR_H__


class CPaletteBar : public CToolBar
{
// Construction
public:
      void SetColumns(UINT nColumns);
      UINT GetColumns();
      CPaletteBar();

// Attributes
public:

// Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CPaletteBar)
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CPaletteBar();

      // Generated message map functions
protected:
      UINT m_nColumns;
      //{{AFX_MSG(CPaletteBar)
            // NOTE - the ClassWizard will add and remove member functions here.
      //}}AFX_MSG

      DECLARE_MESSAGE_MAP()
};

#endif
-------3)toolbar.cpp
////toolbar.cpp


#include "stdafx.h"
#include "draw.h"
#include "toolbar.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CPaletteBar::CPaletteBar()
{
}
CPaletteBar::~CPaletteBar()
{
}
BEGIN_MESSAGE_MAP(CPaletteBar, CToolBar)
      //{{AFX_MSG_MAP(CPaletteBar)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()


UINT CPaletteBar::GetColumns()
{
      return m_nColumns;
}

void CPaletteBar::SetColumns(UINT nColumns)
{
      m_nColumns = nColumns;
      int nCount = GetToolBarCtrl().GetButtonCount();
      
      for(int i=0; i<nCount; i++){
            
            UINT nStyle = GetButtonStyle(i);
            BOOL bWrap = (((i+1) % nColumns) == 0);
            
            if(bWrap)      nStyle |= TBBS_WRAPPED;
            else             nStyle &= ~TBBS_WRAPPED;
            
            SetButtonStyle(i, nStyle);
      }

      Invalidate();
      GetParentFrame()->RecalcLayout();
}
--------4)draw.h
// draw.h : main header file for the DRAW application
//

#if !defined(AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#ifndef __AFXWIN_H__
      #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"       // main symbols
#include "afxtempl.h"

/////////////////////////////////////////////////////////////////////////////
// CDrawApp:
// See draw.cpp for the implementation of this class
//

class CDrawApp : public CWinApp
{
public:
      CDrawApp();

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CDrawApp)
      public:
      virtual BOOL InitInstance();
      //}}AFX_VIRTUAL

// Implementation

      //{{AFX_MSG(CDrawApp)
      afx_msg void OnAppAbout();
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
---------4)draw.cpp

// draw.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "draw.h"

#include "MainFrm.h"
#include "ChildFrm.h"
#include "drawDoc.h"
#include "drawView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawApp

BEGIN_MESSAGE_MAP(CDrawApp, CWinApp)
      //{{AFX_MSG_MAP(CDrawApp)
      ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG_MAP
      // Standard file based document commands
      ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
      ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
      // Standard print setup command
      ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawApp construction

CDrawApp::CDrawApp()
{
      // TODO: add construction code here,
      // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDrawApp object

CDrawApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CDrawApp initialization

BOOL CDrawApp::InitInstance()
{
      AfxEnableControlContainer();

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      //  of your final executable, you should remove from the following
      //  the specific initialization routines you do not need.

#ifdef _AFXDLL
      Enable3dControls();                  // Call this when using MFC in a shared DLL
#else
      Enable3dControlsStatic();      // Call this when linking to MFC statically
#endif

      // Change the registry key under which our settings are stored.
      // You should modify this string to be something appropriate
      // such as the name of your company or organization.
      SetRegistryKey(_T("Local AppWizard-Generated Applications"));

      LoadStdProfileSettings();  // Load standard INI file options (including MRU)

      // Register the application's document templates.  Document templates
      //  serve as the connection between documents, frame windows and views.

      CMultiDocTemplate* pDocTemplate;
      pDocTemplate = new CMultiDocTemplate(
            IDR_DRAWTYPE,
            RUNTIME_CLASS(CDrawDoc),
            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
            RUNTIME_CLASS(CDrawView));
      AddDocTemplate(pDocTemplate);

      // create main MDI Frame window
      CMainFrame* pMainFrame = new CMainFrame;
      if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
            return FALSE;
      m_pMainWnd = pMainFrame;

      // Enable drag/drop open
      m_pMainWnd->DragAcceptFiles();

      // Enable DDE Execute open
      EnableShellOpen();
      RegisterShellFileTypes(TRUE);

      // Parse command line for standard shell commands, DDE, file open
      CCommandLineInfo cmdInfo;
      ParseCommandLine(cmdInfo);

      // Dispatch commands specified on the command line
      if (!ProcessShellCommand(cmdInfo))
            return FALSE;

      // The main window has been initialized, so show and update it.
      pMainFrame->ShowWindow(m_nCmdShow);
      pMainFrame->UpdateWindow();

      return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
      CAboutDlg();

// Dialog Data
      //{{AFX_DATA(CAboutDlg)
      enum { IDD = IDD_ABOUTBOX };
      //}}AFX_DATA

      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CAboutDlg)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      //}}AFX_VIRTUAL

// Implementation
protected:
      //{{AFX_MSG(CAboutDlg)
            // No message handlers
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
      //{{AFX_DATA_INIT(CAboutDlg)
      //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CAboutDlg)
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
      //{{AFX_MSG_MAP(CAboutDlg)
            // No message handlers
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CDrawApp::OnAppAbout()
{
      CAboutDlg aboutDlg;
      aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CDrawApp commands
----------5)drawDoc.h

// drawDoc.h : interface of the CDrawDoc class
//
/////////////////////////////////////////////////////////////////////////////
#include "drawobj.h"

#if !defined(AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class CDrawView;

class CDrawDoc : public CDocument
{
protected: // create from serialization only
      CDrawDoc();
      DECLARE_DYNCREATE(CDrawDoc)

// Attributes
public:
      CDrawObjList m_objects;
      int m_nMapMode;

// Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CDrawDoc)
      public:
      virtual BOOL OnNewDocument();
      virtual void Serialize(CArchive& ar);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CDrawDoc();
      CDrawObj* GetObjectAt(const CPoint&  point);
      CDrawObjList * GetObjects() {return &m_objects;}

      void Add(CDrawObj* pObj);
      void Remove(CDrawObj* pObj);
      void Draw(CDC* pDC,CDrawView * pView );
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
      //{{AFX_MSG(CDrawDoc)
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
--------5)drawDoc.cpp

// drawDoc.cpp : implementation of the CDrawDoc class
//

#include "stdafx.h"
#include "draw.h"

#include "drawDoc.h"
#include "drawview.h"
#include "drawtool.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc

IMPLEMENT_DYNCREATE(CDrawDoc, CDocument)

BEGIN_MESSAGE_MAP(CDrawDoc, CDocument)
      //{{AFX_MSG_MAP(CDrawDoc)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc construction/destruction

CDrawDoc::CDrawDoc()
{
      // TODO: add one-time construction code here
      m_nMapMode=MM_TEXT;  //-MM_TEXT
}

CDrawDoc::~CDrawDoc()
{
      POSITION pos=m_objects.GetHeadPosition();
      while(pos !=NULL)
            delete m_objects.GetNext(pos);
}

BOOL CDrawDoc::OnNewDocument()
{
      if (!CDocument::OnNewDocument())
            return FALSE;

      // TODO: add reinitialization code here
      // (SDI documents will reuse this document)

      return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CDrawDoc serialization

void CDrawDoc::Serialize(CArchive& ar)
{
      if (ar.IsStoring())
      {
            // TODO: add storing code here
            m_objects.Serialize(ar);
      }
      else
      {
            // TODO: add loading code here
            m_objects.Serialize(ar);
      }
      CDocument::Serialize(ar);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc diagnostics

#ifdef _DEBUG
void CDrawDoc::AssertValid() const
{
      CDocument::AssertValid();
}

void CDrawDoc::Dump(CDumpContext& dc) const
{
      CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc commands

CDrawObj* CDrawDoc::GetObjectAt(const CPoint&  point)
{
    CRect rect(point, CSize(1, 1));
      POSITION pos = m_objects.GetTailPosition();
      while (pos != NULL)
      {
            CDrawObj* pObj = m_objects.GetPrev(pos);
            if (pObj->IsCross(rect))      return pObj;
      }
      return NULL;      
}

void CDrawDoc::Add(CDrawObj* pObj)
{
      m_objects.AddTail(pObj);
      pObj->m_pDocument=this;
      SetModifiedFlag();
}

void CDrawDoc::Remove(CDrawObj* pObj)
{
      POSITION pos = m_objects.Find(pObj);
      if(pos != NULL)
            m_objects.RemoveAt(pos);
      SetModifiedFlag();
      pos=GetFirstViewPosition();
      while(pos!=NULL)
            ((CDrawView*)GetNextView(pos))->Remove(pObj);
}

void CDrawDoc::Draw(CDC* pDC,CDrawView * pView )
{
      POSITION pos = m_objects.GetHeadPosition();
      while (pos != NULL)
      {
            CDrawObj* pObj = m_objects.GetNext(pos);
            pObj->Draw(pDC, FALSE);
            if(!pDC->IsPrinting() && pView->IsSelected(pObj))
                  pObj->DrawCtrPoints(pDC, CDrawTool::c_selectState);
      }

}

-------6)drawView.h
// drawView.h : interface of the CDrawView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define HINT_UPDATE_SELECTION  0
#define HINT_DELETE_SELECTION  1

class CDrawObj;

class CDrawView : public CScrollView
{
protected: // create from serialization only
      CDrawView();
      DECLARE_DYNCREATE(CDrawView)

// Attributes
public:
      CDrawObj* m_selectObj;
      CDrawObjList m_selectList;
      CDrawObjList m_selectEdit;
      BOOL m_bDragging;

      
      
// Operations
public:
      CDrawDoc* GetDocument();
      virtual void OnUpdate(CScrollView* pSender,LPARAM lHint, CObject* pHint);

      void Remove(CDrawObj* pObj);
      BOOL IsSelected(CDrawObj* pObj) const ;
      void InvalDrawObj(CDrawObj* pObj);
      void Select(CDrawObj* pObj,BOOL bAdd=FALSE);
      void SelectWithinRect(CRect rect,BOOL bAdd);
      void CloneSelect();

      void ClientToDoc(CPoint & point);
      void ClientToDoc(CRect& rect);
      void DocToClient(CPoint& point);
      void DocToClient(CRect& rect);

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CDrawView)
      public:
      virtual void OnDraw(CDC* pDC);  // overridden to draw this view
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
      protected:
      virtual void OnInitialUpdate(); // called first time after construct
      virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
      virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CDrawView();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
      //{{AFX_MSG(CDrawView)
      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
      afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
      afx_msg void OnMouseMove(UINT nFlags, CPoint point);
      //}}AFX_MSG
      afx_msg void OnToolSelection(UINT ID);
      afx_msg void OnUpdateToolSelection(CCmdUI* pCmdUI);
      DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in drawView.cpp
inline CDrawDoc* CDrawView::GetDocument()
   { return (CDrawDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
--------6)DrawView.cpp
// drawView.cpp : implementation of the CDrawView class
//

#include "stdafx.h"
#include "draw.h"
#include "drawobj.h"
#include "drawtool.h"
#include "drawDoc.h"
#include "drawView.h"
#include "mainfrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawView

IMPLEMENT_DYNCREATE(CDrawView, CScrollView)

BEGIN_MESSAGE_MAP(CDrawView, CScrollView)
      //{{AFX_MSG_MAP(CDrawView)
      ON_WM_LBUTTONDOWN()
      ON_WM_LBUTTONUP()
      ON_WM_MOUSEMOVE()
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND_RANGE(ID_TOOL_SELECT, ID_TOOL_ARC,                  OnToolSelection)
      ON_UPDATE_COMMAND_UI_RANGE(ID_TOOL_SELECT, ID_TOOL_ARC,      OnUpdateToolSelection)
      ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawView construction/destruction

CDrawView::CDrawView()
{
      // TODO: add construction code here
      CDrawTool::c_toolShape=select;

}

CDrawView::~CDrawView()
{
}

BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      //  the CREATESTRUCT cs

      return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView drawing
void CDrawView::OnDraw(CDC* pDC)
{
      CDrawDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);

      // TODO: add draw code for native data here
      ASSERT_VALID(this);
      CDC dc;
      CDC* pMemDC=pDC;
      CBitmap bitmap;
      CBitmap* pOldBitmap;

      CRect client;
      pDC->GetClipBox(client);
      CRect rect=client;
      DocToClient(rect);

      
      if (dc.CreateCompatibleDC(pDC))
      {
            if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
            {
                        //TCHAR str[50];
                        //wsprintf(str,"rect.width() is %d,rect.height() is %d",rect.Width(),rect.Height());
                        //AfxMessageBox(str);
                        OnPrepareDC(&dc, NULL);
                        pMemDC = &dc;
                        dc.OffsetViewportOrg(-rect.left, -rect.top);
                        pOldBitmap = dc.SelectObject(&bitmap);
                        //dc.IntersectClipRect(client);
            }
      }

      CBrush brush;
      if (!brush.CreateSolidBrush(RGB(255,255,255)))
            return;  
      
      pMemDC->FillRect(client, &brush);

      
      pDoc->Draw(pMemDC, this);
          
      if (pMemDC != pDC)
      {
            pDC->SetViewportOrg(0, 0);
            pDC->SetWindowOrg(0,0);
            pDC->SetMapMode(MM_TEXT);
            dc.SetViewportOrg(0, 0);
            dc.SetWindowOrg(0,0);
            dc.SetMapMode(MM_TEXT);
            pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
                  &dc, 0, 0, SRCCOPY);
            dc.SelectObject(pOldBitmap);
      }
}

void CDrawView::OnInitialUpdate()
{
      CScrollView::OnInitialUpdate();
      CSize sizeTotal;
      // TODO: calculate the total size of this view
      sizeTotal.cx = sizeTotal.cy = 100;
      SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView printing


BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
      // default preparation
      return DoPreparePrinting(pInfo);
}

void CDrawView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
      // TODO: add extra initialization before printing
}

void CDrawView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
      // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView diagnostics

#ifdef _DEBUG
void CDrawView::AssertValid() const
{
      CScrollView::AssertValid();
}

void CDrawView::Dump(CDumpContext& dc) const
{
      CScrollView::Dump(dc);
}

CDrawDoc* CDrawView::GetDocument() // non-debug version is inline
{
      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawDoc)));
      return (CDrawDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDrawView message handlers

void CDrawView::OnToolSelection(UINT ID)
{
      switch(ID)
      {
      case ID_TOOL_SELECT:      CDrawTool::c_toolShape = select;      break;
      case ID_TOOL_LINE:            CDrawTool::c_toolShape = line;            break;
      case ID_TOOL_RECT:            CDrawTool::c_toolShape = rectangle;      break;
      case ID_TOOL_ROUNDRECT:      CDrawTool::c_toolShape = roundRect;      break;
      case ID_TOOL_ELLIPSE:      CDrawTool::c_toolShape = ellipse;      break;
      case ID_TOOL_ARC:            CDrawTool::c_toolShape = arc;            break;
      }
}

void CDrawView::OnUpdateToolSelection(CCmdUI* pCmdUI)
{
      switch(pCmdUI->m_nID){
      case ID_TOOL_SELECT:      
            pCmdUI->SetRadio(CDrawTool::c_toolShape == select );
            break;
      case ID_TOOL_LINE:      
            pCmdUI->SetRadio(CDrawTool::c_toolShape == line );
            break;
      case ID_TOOL_RECT:      
            pCmdUI->SetRadio(CDrawTool::c_toolShape == rectangle );
            break;
      case ID_TOOL_ROUNDRECT:
            pCmdUI->SetRadio(CDrawTool::c_toolShape == roundRect );
            break;
      case ID_TOOL_ELLIPSE:
            pCmdUI->SetRadio(CDrawTool::c_toolShape == ellipse );
            break;
      case ID_TOOL_ARC:      
            pCmdUI->SetRadio(CDrawTool::c_toolShape == arc );
            break;
      }
}


void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
      // TODO: Add your message handler code here and/or call default
      CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
      if(pTool!=NULL)
            pTool->OnLButtonDown(this,nFlags,point);

      //CScrollView::OnLButtonDown(nFlags, point);
}

void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
      // TODO: Add your message handler code here and/or call default
      CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
      if(pTool!=NULL)
            pTool->OnLButtonUp(this,nFlags,point);
      //CScrollView::OnLButtonUp(nFlags, point);
}

void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
      // TODO: Add your message handler code here and/or call default
      CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
      if(pTool!=NULL)
            pTool->OnMouseMove(this,nFlags,point);
      //CScrollView::OnMouseMove(nFlags, point);
}

void CDrawView::OnUpdate(CScrollView* pSender,LPARAM lHint, CObject* pHint)
{
      switch(lHint)
      {
      case HINT_UPDATE_SELECTION:
            {
             
                  CDrawObjList* pList = pHint != NULL ?
                        (CDrawObjList*)pHint : &m_selectList;
                  POSITION pos = pList->GetHeadPosition();
                  while (pos != NULL)
                        InvalDrawObj(pList->GetNext(pos));
            }
            break;
      case HINT_DELETE_SELECTION:
            {
                  CDrawObjList* pList =  &m_selectList;
                  POSITION pos = pList->GetHeadPosition();
                  while (pos != NULL)
                  {
                        CDrawObj* pObj = pList->GetNext(pos);
                        InvalDrawObj(pObj);
                        Remove(pObj);  
                        GetDocument()->Remove(pObj);
                        pObj->Remove();
                  }
                  m_selectList.RemoveAll();
            }
            break;
      default:
            ASSERT(FALSE);
            break;
      }

}

void CDrawView::Remove(CDrawObj* pObj)
{
      POSITION pos=m_selectList.Find(pObj);
      if(pos!=NULL)
            m_selectList.RemoveAt(pos);
}

BOOL CDrawView::IsSelected(CDrawObj* pObj) const
{
      return m_selectList.Find(pObj)!=NULL;
}

void CDrawView::InvalDrawObj(CDrawObj* pObj)
{
      CRect rect=pObj->m_rect;
      DocToClient(rect);
      if(IsSelected(pObj))
      {
            rect.left -=4;
            rect.top -=4;
            rect.right +=4;
            rect.bottom +=4;
      }
      //rect.InflateRect(1,1);
      InvalidateRect(rect,FALSE);
}

void CDrawView::Select(CDrawObj* pObj,BOOL bAdd)
{
      if(!bAdd)
      {
            OnUpdate(NULL,HINT_UPDATE_SELECTION,NULL);
            m_selectList.RemoveAll();
      }
      
      if(pObj==NULL || IsSelected(pObj))
            return;
      m_selectList.AddTail(pObj);
      InvalDrawObj(pObj);
}

void CDrawView::SelectWithinRect(CRect rect,BOOL bAdd)
{
      if (!bAdd)      Select(NULL);
      
      ClientToDoc(rect);
      OnUpdate(NULL, HINT_UPDATE_SELECTION, NULL);
      m_selectList.RemoveAll();
      CDrawObjList* pObList = GetDocument()->GetObjects();
      POSITION posObj = pObList->GetHeadPosition();
      while (posObj != NULL)
      {
            CDrawObj* pObj = pObList->GetNext(posObj);
            if (pObj->IsCross(rect)){
                  Select(pObj,TRUE);
                  InvalDrawObj(pObj);
            }
      }
      
}

void CDrawView::CloneSelect()
{
      POSITION pos = m_selectList.GetHeadPosition();
      while (pos != NULL)
      {
            CDrawObj* pObj = m_selectList.GetNext(pos);
            pObj->Clone(pObj->m_pDocument);
      }
}

void CDrawView::ClientToDoc(CPoint & point)
{
      CClientDC dc(this);
      OnPrepareDC(&dc,NULL);
      dc.DPtoLP(&point);
}

void CDrawView::ClientToDoc(CRect& rect)
{
      ASSERT_VALID(this);
      CClientDC dc(this);
      OnPrepareDC(&dc,NULL);
      dc.DPtoLP(rect);
}

void CDrawView::DocToClient(CPoint& point)
{
      CClientDC dc(this);
      OnPrepareDC(&dc,NULL);
      dc.LPtoDP(&point);
}

void CDrawView::DocToClient(CRect& rect)
{
      CClientDC dc(this);
      OnPrepareDC(&dc,NULL);
      dc.LPtoDP(rect);
      rect.NormalizeRect();
}

------------7)MainFrm.h
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "toolbar.h"
//class CPaletteBar;

class CMainFrame : public CMDIFrameWnd
{
      DECLARE_DYNAMIC(CMainFrame)
public:
      CMainFrame();
             

// Attributes
public:
      
      CPaletteBar      m_wndPaletteBar;

// Operations
public:
      
      BOOL CreatePaletteBar();
      
      

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CMainFrame)
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CMainFrame();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // control bar embedded members
      CStatusBar  m_wndStatusBar;
      CToolBar    m_wndToolBar;


// Generated message map functions
protected:
      //{{AFX_MSG(CMainFrame)
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI);
      //}}AFX_MSG
      afx_msg BOOL OnBarCheck(UINT nID);
      DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

--------7)MainFrm.cpp
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "draw.h"
#include "toolbar.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
      //{{AFX_MSG_MAP(CMainFrame)
      ON_WM_CREATE()
      ON_UPDATE_COMMAND_UI(IDW_PALETTE_BAR, OnUpdateControlBarMenu)
      //}}AFX_MSG_MAP
      ON_COMMAND_EX(IDW_PALETTE_BAR,OnBarCheck)
END_MESSAGE_MAP()

static UINT indicators[] =
{
      ID_SEPARATOR,           // status line indicator
      ID_INDICATOR_CAPS,
      ID_INDICATOR_NUM,
      ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
      // TODO: add member initialization code here
      
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
      if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
      
      if (!m_wndToolBar.Create(this) ||
            !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
      {
            TRACE0("Failed to create toolbar\n");
            return -1;      // fail to create
      }

      if (!m_wndStatusBar.Create(this) ||
            !m_wndStatusBar.SetIndicators(indicators,
              sizeof(indicators)/sizeof(UINT)))
      {
            TRACE0("Failed to create status bar\n");
            return -1;      // fail to create
      }

      // TODO: Remove this if you don't want tool tips or a resizeable toolbar
      m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
            CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

      // TODO: Delete these three lines if you don't want the toolbar to
      //  be dockable
      m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
      EnableDocking(CBRS_ALIGN_ANY);
      DockControlBar(&m_wndToolBar);
      
      
      if(! CreatePaletteBar())
      {
            TRACE0("Failed to create Palette bar\n");
            return -1;      // fail to create
      }

      return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      //  the CREATESTRUCT cs

      return CMDIFrameWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
      CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
      CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
BOOL CMainFrame::CreatePaletteBar()
{
      static UINT BASED_CODE PaletteButtons[] =
      {
            ID_TOOL_SELECT,
            ID_TOOL_LINE,  
            ID_TOOL_RECT,  
            ID_TOOL_ROUNDRECT,  
            ID_TOOL_ELLIPSE,
            ID_TOOL_ARC,
             
      };

      if (!m_wndPaletteBar.Create(this,  WS_VISIBLE | WS_CHILD |
            CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS |CBRS_TOP|
            CBRS_FLYBY , IDW_PALETTE_BAR) ||
            !m_wndPaletteBar.LoadBitmap(IDR_PALETTE_BAR) ||
            !m_wndPaletteBar.SetButtons(PaletteButtons,
             sizeof(PaletteButtons)/sizeof(UINT)))
      {
            TRACE0("Failed to create Palettebar\n");
            return -1;      // fail to create
      }
      m_wndPaletteBar.SetWindowText(_T("Palette"));
      m_wndPaletteBar.EnableDocking(CBRS_ALIGN_ANY);

      CPoint pt(GetSystemMetrics(SM_CXSCREEN)/ 3,
            GetSystemMetrics(SM_CYSCREEN) / 5);

      m_wndPaletteBar.SetColumns(2);
      FloatControlBar(&m_wndPaletteBar, pt);
            
      return TRUE;
}


void CMainFrame::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
      // TODO: Add your command update UI handler code here
      CControlBar* pBar = GetControlBar(pCmdUI->m_nID);
      if (pBar != NULL)
      {
            pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);
            return;
      }
      pCmdUI->ContinueRouting();
}

BOOL CMainFrame::OnBarCheck(UINT nID)
{
      CControlBar* pBar = GetControlBar(nID);
      if (pBar != NULL)
      {
            ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);
            return TRUE;
      }
      return FALSE;
}
--------8)ChildFrm.h
// ChildFrm.h : interface of the CChildFrame class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class CChildFrame : public CMDIChildWnd
{
      DECLARE_DYNCREATE(CChildFrame)
public:
      CChildFrame();

// Attributes
public:

// Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CChildFrame)
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CChildFrame();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

// Generated message map functions
protected:
      //{{AFX_MSG(CChildFrame)
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

-------8)ChildFrm.cpp
// ChildFrm.cpp : implementation of the CChildFrame class
//

#include "stdafx.h"
#include "draw.h"

#include "ChildFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CChildFrame

IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
      //{{AFX_MSG_MAP(CChildFrame)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChildFrame construction/destruction

CChildFrame::CChildFrame()
{
      // TODO: add member initialization code here
      
}

CChildFrame::~CChildFrame()
{
}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      //  the CREATESTRUCT cs

      return CMDIChildWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CChildFrame diagnostics

#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
      CMDIChildWnd::AssertValid();
}

void CChildFrame::Dump(CDumpContext& dc) const
{
      CMDIChildWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChildFrame message handlers
----------9)stdafx.h
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC OLE automation classes
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>                  // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT


//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

-----9)stdafx.cpp
// stdafx.cpp : source file that includes just the standard includes
//      draw.pch will be the pre-compiled header
//      stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

---------10)resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by draw.rc
//
#define IDD_ABOUTBOX                    100
#define IDR_MAINFRAME                   128
#define IDR_DRAWTYPE                    129
#define IDR_PALETTE_BAR                 130
#define ID_TOOL_SELECT                  32771
#define ID_MENUITEM32772                32772
#define ID_TOOL_LINE                    32773
#define ID_TOOL_RECT                    32774
#define ID_TOOL_ROUNDRECT               32775
#define ID_TOOL_ELLIPSE                 32776
#define ID_TOOL_ARC                     32777
#define IDW_PALETTE_BAR                 32778
#define IDW_COLOR_BAR                   32779

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS                     1
#define _APS_NEXT_RESOURCE_VALUE        131
#define _APS_NEXT_COMMAND_VALUE         32780
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
---------end of file
0
 
LVL 22

Expert Comment

by:nietod
ID: 1169751
IMPLIMENT_SERIAL for CDrawRect is commented out for some reason.
0
 

Author Comment

by:k1024
ID: 1169752

but,if not this comment out ,token error and many of error!!!!
how can I solve the problem?      
 
 
 
this comment is not support file upload, and I write  detail below...
my project name: draw
project setting:MDI, database not support, CDrawView is derived CScrollView

files-1)DrawObj.h,DrawObj.cpp
2)DrawTool.h,DrawTool.cpp
3)Toolbar.h,Toolbar.cpp
4)draw.h,draw.cpp
5)drawDoc.h,drawDoc.cpp
6)drawView.h,drawView.cpp
7)MainFrm.h,MainFrm.cpp
8)ChildFrm.h,ChildFrm.cpp
9)StdAfx.cpp,StdAfx.h,resource.h

1)------DrawObj.h
//DrawObj.h

#ifndef  __DRAWOBJ_H__
#define  __DRAWOBJ_H__

#include <afxtempl.h>

class CDrawView;
class CDrawDoc;

enum SelectState {none,move,size,range,draw};
enum ToolShape {select,line,rectangle,ellipse,roundRect,arc};

class CDrawObj : public CObject
{
protected:
//serialize
DECLARE_SERIAL(CDrawObj);
CDrawObj();

public:
CDrawObj(const CRect& rect);

//data member
CRect m_prev;  
CRect m_rect;  
CDrawDoc * m_pDocument;
ToolShape m_nShape;
//overrides
virtual void Draw(CDC * pDC, BOOL bMouseDrag);
virtual void Serialize(CArchive & ar);
virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

/////control point
virtual CPoint GetCtrPointPosition(int nCtrID);
virtual HCURSOR GetCtrPointCursor(int nCtrID);

virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);

//operations
void Remove();
void Invalidate();

CRect GetCtrPointRect(int nCtrID,CDrawView * pView);
void DrawCtrPoints(CDC* pDC, SelectState state);

int HitTest(CPoint point,CDrawView* pView,BOOL bSelected);
BOOL IsCross(const CRect& rect);
void MoveTo(const CRect& position,CDrawView* pView=NULL);

//implementation
public:
virtual ~CDrawObj();


#ifdef  _DEBUG
void AssertValid();
#endif

//implementating data
protected:
LOGPEN m_logPen;  
LOGBRUSH m_logBrush;
int m_nCtrCount;  
public:
static int c_nPenColor;  //pen color
static int c_nBrushColor; //brush color
static LOGPEN c_logPen ; //={PS_INSIDEFRAME,1L,RGB(0,0,0)};
static LOGBRUSH c_logBrush ; //={BS_SOLID,RGB(0,255,0),NULL};
};

//CDrawObj
//typedef CTypedPtrList<CObList, CDrawObj*> CDrawObjList;

typedef CTypedPtrList<CObList, CDrawObj*> CDrawObjList;

/////////////////////////

class CDrawLine : public CDrawObj
{
protected:
DECLARE_SERIAL(CDrawLine);
CDrawLine();
public:
CDrawLine(const CRect& position);

//implementation
public:
virtual void Serialize(CArchive & ar);
virtual void Draw(CDC * pDC, BOOL bMouseDrag);
virtual CDrawObj* Clone(CDrawDoc* pDoc,BOOL bAdd=TRUE);

virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);

/////control point
virtual CPoint GetCtrPointPosition(int nCtrID);
virtual HCURSOR GetCtrPointCursor(int nCtrID);

protected:
friend class CDrawTools;
};

/////////////////////////


class CDrawRect : public CDrawObj
{
protected:
DECLARE_SERIAL(CDrawRect);
CDrawRect();
public:
CDrawRect(const CRect& position);

//implementation
public:
virtual void Serialize(CArchive & ar);
virtual void Draw(CDC * pDC, BOOL bMouseDrag);
virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

protected:
friend class CDrawTools;
};

/////////////////////////


class CDrawRound : public CDrawObj
{
protected:
DECLARE_SERIAL(CDrawRound);
CDrawRound();
public:
CDrawRound(const CRect& position);

//implementation
public:
virtual void Serialize(CArchive & ar);
virtual void Draw(CDC * pDC, BOOL bMouseDrag);
virtual CDrawObj* Clone(CDrawDoc* pDoc=NULL,BOOL bAdd=TRUE);

/////control point
virtual CPoint GetCtrPointPosition(int nCtrID);
virtual HCURSOR GetCtrPointCursor(int nCtrID);

virtual void MouseMove(int nCtrID,CPoint point,CDrawView* pView=NULL);

protected:
CPoint m_round;  
CPoint m_startArc;
friend class CDrawTools;
};

#endif

-------------------DrawObj.cpp
//DrawObj.cpp

#include "stdafx.h"
#include "draw.h"
#include "DrawObj.h"
#include "drawDoc.h"
#include "drawView.h"
#include "drawtool.h"


int CDrawObj::c_nPenColor=0;  //static
int CDrawObj::c_nBrushColor=13;  //static

LOGPEN CDrawObj::c_logPen={PS_INSIDEFRAME,1L,RGB(0,0,0)};  //default logPen,static
LOGBRUSH CDrawObj::c_logBrush={BS_SOLID,RGB(0,255,0),NULL};//default logbrush, static

IMPLEMENT_SERIAL(CDrawObj, CObject,0)

CDrawObj::CDrawObj()
{
}

CDrawObj::~CDrawObj()
{
}

CDrawObj::CDrawObj(const CRect& rect)
{
m_rect=rect;
m_pDocument=NULL;
m_logPen=c_logPen;
m_logBrush=c_logBrush;
}

void CDrawObj::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if(ar.IsStoring())
{
ar << m_rect;
ar.Write(&m_logPen,sizeof(LOGPEN));
ar.Write(&m_logBrush,sizeof(LOGBRUSH));
}
else
{
m_pDocument=(CDrawDoc*)ar.m_pDocument;
ASSERT_VALID(m_pDocument);
ASSERT_KINDOF(CDrawDoc,m_pDocument);

ar >> m_rect;
m_prev=m_rect;  
ar.Read(&m_logPen,sizeof(LOGPEN));
ar.Read(&m_logBrush,sizeof(LOGBRUSH));
}

}//

void CDrawObj::Remove()
{
delete this;
}//

void CDrawObj::Draw(CDC* pDC,BOOL bMouseDrag)
{
}//OK!

CDrawObj* CDrawObj::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
ASSERT_VALID(this);

CDrawObj* pClone=new CDrawObj(m_rect);
pClone->m_logPen=m_logPen;
pClone->m_logBrush=m_logBrush;

ASSERT_VALID(pClone);


if(pDoc!=NULL && bAdd)
pDoc->Add(pClone);  
return pClone;
}


void CDrawObj::Invalidate()
{
ASSERT_VALID(this);
m_pDocument->UpdateAllViews(NULL, HINT_UPDATE_SELECTION,this);
}


void CDrawObj::DrawCtrPoints(CDC* pDC, SelectState state)
{
ASSERT_VALID(this);

switch(state)
{
case none: break;
case size:
case range:
case move:
case draw:
{
for(int nCtrID=1;nCtrID<=m_nCtrCount;nCtrID++)
{
CPoint point=GetCtrPointPosition(nCtrID);
//pDC->PatBlt(point.x-4,point.y-4,8,8,PATCOPY);

pDC->Rectangle(point.x-4,point.y-4,point.x+4,point.y+4);
}
}
break;
}
}


CRect CDrawObj::GetCtrPointRect(int nCtrID,CDrawView * pView)
{
ASSERT_VALID(this);
ASSERT(pView!=NULL);

CRect rect;
CPoint point=GetCtrPointPosition(nCtrID);
pView->DocToClient(point);  
rect.SetRect(point.x-4, point.y-4, point.x+4, point.y+4);
pView->ClientToDoc(rect);  

return rect;
}

CPoint CDrawObj::GetCtrPointPosition(int nCtrID)
{
ASSERT_VALID(this);
int x,y,xCenter,yCenter;

xCenter=m_rect.left+m_rect.Width()/2;
yCenter=m_rect.top+m_rect.Height()/2;

switch(nCtrID)
{
case 1:
x=m_rect.left;
y=m_rect.top;
break;
case 2:
x=xCenter;
y=m_rect.top;
break;
case 3:
x=m_rect.right;
y=m_rect.top;
break;
case 4:
x=m_rect.right;
y=yCenter;
break;
case 5:
x=m_rect.right;
y=m_rect.bottom;
break;
case 6:
x=xCenter;
y=m_rect.bottom;
break;
case 7:
x=m_rect.left;
y=m_rect.bottom;
break;
case 8:
x=m_rect.left;
y=yCenter;
break;
default:

ASSERT(FALSE);
}
return CPoint(x,y);
}


HCURSOR CDrawObj::GetCtrPointCursor(int nCtrID)
{
ASSERT_VALID(this);


LPCTSTR curname;
switch(nCtrID)
{
case 1:
case 5:
curname=IDC_SIZENWSE;
break;
case 2:
case 6:
curname=IDC_SIZENS;
break;
case 3:
case 7:
curname=IDC_SIZENESW;
break;
case 4:
case 8:
curname=IDC_SIZEWE;
break;
default:
ASSERT(FALSE);

}
//CWinApp::LoadStandardCursor
//HCURSOR LoadStandardCursor( LPCTSTR lpszCursorName ) const;
return AfxGetApp()->LoadStandardCursor(curname);
}



void CDrawObj::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
ASSERT_VALID(this);
CRect rect=m_rect;
switch(nCtrID)
{
default:
ASSERT(FALSE);

case 1:
rect.left=point.x;
rect.top=point.y;
break;
case 2:
rect.top=point.y;
break;
case 3:
rect.right=point.x;
rect.top=point.y;
break;
case 4:
rect.right=point.x;
break;
case 5:
rect.right=point.x;
rect.bottom=point.y;
break;
case 6:
rect.bottom=point.y;
break;

case 7:
rect.left=point.x;
rect.bottom=point.y;
break;
case 8:
rect.left=point.x;
break;
}
MoveTo(rect,pView);  //
}


int CDrawObj::HitTest(CPoint point,CDrawView* pView,BOOL bSelected)
{
ASSERT_VALID(this);
ASSERT(pView!=NULL);

if(bSelected)
{
for(int nCtrID=1;nCtrID <= m_nCtrCount;nCtrID++)
{
CRect rect=GetCtrPointRect(nCtrID,pView);
rect.NormalizeRect();
//BOOL PtInRect( POINT point ) const;

if(rect.PtInRect(point)) return nCtrID;
}
}
else
{
CRect rect(point,point);
if(IsCross(rect)) return 1;  //
}
return 0;
}


BOOL CDrawObj::IsCross(const CRect& rect)
{
ASSERT_VALID(this);

CRect rectT=m_rect;
rectT.NormalizeRect();
CRect rc=rect;
rc.NormalizeRect();
//CRect operator &( const RECT& rect2 ) const;
//BOOL IsRectEmpty( ) const;
return !(rectT & rc).IsRectEmpty();
}



void CDrawObj::MoveTo(const CRect& position,CDrawView* pView)
{
ASSERT_VALID(this);
if(position == m_rect)
return;
if(pView==NULL)
{
Invalidate();
m_rect=position;
Invalidate();
}
else
{
CClientDC* pDC=new CClientDC(pView);
pView->OnPrepareDC(pDC,NULL);
Draw(pDC,TRUE);
m_rect=position;
Draw(pDC,TRUE);
m_pDocument->SetModifiedFlag();
delete pDC;
}

}


#ifdef _DEBUG
void CDrawObj::AssertValid()
{
ASSERT(m_rect.left <= m_rect.right);
ASSERT(m_rect.bottom <= m_rect.top);
}
#endif

/////////////CDrawLine

IMPLEMENT_SERIAL(CDrawLine, CDrawObj, 0)

CDrawLine::CDrawLine()
{
m_nCtrCount=2;  
}

CDrawLine::CDrawLine(const CRect& position)
: CDrawObj(position)
{
ASSERT_VALID(this);
m_nCtrCount=2;
}

void CDrawLine::Serialize(CArchive& ar)
{
ASSERT_VALID(this);
CDrawObj::Serialize(ar);
}

void CDrawLine::Draw(CDC* pDC, BOOL bMouseDrag)
{
ASSERT_VALID(this);  

CPen pen;
CBrush brush;
//if(!pen.CreatePenIndirect(&m_logPen)) return;
//brush object
if(!brush.CreateBrushIndirect(&m_logBrush)) return;

CPen* pOldPen;
CBrush* pOldBrush;

if(!bMouseDrag)
{

if(!pen.CreatePenIndirect(&m_logPen)) return;
pOldBrush=pDC->SelectObject(&brush);
pOldPen=pDC->SelectObject(&pen);
}
else
{

LOGPEN logPen;
logPen.lopnStyle = PS_DOT;
logPen.lopnWidth = CPoint(1,1);
logPen.lopnColor = RGB(0,0,0);
if (!pen.CreatePenIndirect(&logPen)) return;
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pOldPen = pDC->SelectObject(&pen);
//pDC->SetROP2(R2_NOTXORPEN);
}

//CRect rect=m_rect;

pDC->MoveTo(m_rect.TopLeft());
pDC->LineTo(m_rect.BottomRight());

pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);


} //OK

CDrawObj* CDrawLine::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
ASSERT_VALID(this);
CDrawLine* pClone=new CDrawLine(m_rect);
ASSERT_VALID(pClone);
pClone->m_rect=m_rect;
pClone->m_logPen=m_logPen;
pClone->m_logBrush=m_logBrush;
if(pDoc!=NULL && bAdd)
pDoc->Add(pClone);

return pClone;

}


void CDrawLine::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
ASSERT_VALID(this);

if(nCtrID==2) nCtrID=5;
CDrawObj::MouseMove(nCtrID,point,pView);
}


CPoint CDrawLine::GetCtrPointPosition(int nCtrID)
{
ASSERT_VALID(this);

if(nCtrID==2) nCtrID=5;
return CDrawObj::GetCtrPointPosition(nCtrID);
}

HCURSOR CDrawLine::GetCtrPointCursor(int nCtrID)
{
ASSERT_VALID(this);

if(nCtrID==2) nCtrID=5;
return CDrawObj::GetCtrPointCursor(nCtrID);
}

///////////////////////
//CDrawRect

IMPLEMENT_SREIAL( CDrawRect, CDrawObj, 0)

CDrawRect::CDrawRect()
{
m_nCtrCount=8;
}
 
CDrawRect::CDrawRect(const CRect& position) : CDrawObj(position)
{
ASSERT_VALID(this);
//m_nShape=rectangle;
    m_nCtrCount=8;
}

void CDrawRect::Serialize(CArchive& ar)
{
ASSERT_VALID(this);

CDrawObj::Serialize(ar);
if(ar.IsStoring())
{
ar << (WORD) m_nShape;  //ToolShape

}
else
{
WORD wTemp;
ar >> wTemp;
m_nShape=(ToolShape)wTemp;

}
}//OK!

void CDrawRect::Draw(CDC* pDC,BOOL bMouseDrag)
{
ASSERT_VALID(this);
CPen pen;
CBrush brush;
CBrush * pOldBrush;
CPen* pOldPen;

if (!brush.CreateBrushIndirect(&m_logBrush)) return;

if(!bMouseDrag)
{
if (!pen.CreatePenIndirect(&m_logPen)) return;
pOldBrush = pDC->SelectObject(&brush);
pOldPen = pDC->SelectObject(&pen);
}
else
{
LOGPEN logPen;
logPen.lopnStyle = PS_DOT;
logPen.lopnWidth = CPoint(1,1);
logPen.lopnColor = RGB(0,0,0);

if (!pen.CreatePenIndirect(&logPen)) return;
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pOldPen = pDC->SelectObject(&pen);
//pDC->SetROP2(R2_NOTXORPEN);
}
CRect rect=m_rect;
switch(m_nShape)
{
case rectangle:
pDC->Rectangle(rect);
break;
case ellipse:
pDC->Ellipse(rect);
break;
}
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}//OK!

CDrawObj* CDrawRect::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
ASSERT_VALID(this);

CDrawRect* pClone=new CDrawRect(m_rect);
pClone->m_rect=m_rect;
pClone->m_logPen=m_logPen;
pClone->m_logBrush=m_logBrush;
pClone->m_nShape=m_nShape;
ASSERT_VALID(pClone);

if(pDoc!=NULL && bAdd)
pDoc->Add(pClone);  
return pClone;
}

//////////////////////
////CDrawRound

IMPLEMENT_SERIAL( CDrawRound, CDrawObj, 0)

CDrawRound::CDrawRound()
{
m_nCtrCount=9;
m_round.y=m_round.x=16;  //CPoint m_round
m_startArc.x=m_startArc.y=16;  //CPoint
}//OK!

CDrawRound::CDrawRound(const CRect & position) : CDrawObj(position)
{
ASSERT_VALID(this);
m_nCtrCount=9;
m_round.y=m_round.x=16;  //CPoint m_round
m_startArc.x=m_startArc.y=16;
}//OK!

void CDrawRound::Serialize(CArchive& ar)
{
ASSERT_VALID(this);
CDrawObj::Serialize(ar);
if(ar.IsStoring())
{
ar << (WORD) m_nShape;  //ToolShape
ar << m_round;
}
else
{
WORD wTemp;
ar >> wTemp;
m_nShape=(ToolShape)wTemp;
ar >> m_round;
}
}//OK!

void CDrawRound::Draw(CDC* pDC, BOOL bMouseDrag)
{
ASSERT_VALID(this);
CPen pen;
CBrush brush;
CBrush* pOldBrush;
CPen* pOldPen;

if (!brush.CreateBrushIndirect(&m_logBrush)) return;

if (!bMouseDrag)
{
if (!pen.CreatePenIndirect(&m_logPen)) return;
pOldBrush = pDC->SelectObject(&brush);
pOldPen = pDC->SelectObject(&pen);
}
else
{
LOGPEN logPen;
logPen.lopnStyle = PS_DOT;
logPen.lopnWidth = CPoint(1,1);
logPen.lopnColor = RGB(0,0,0);

if (!pen.CreatePenIndirect(&logPen)) return;
pOldBrush= (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pOldPen = pDC->SelectObject(&pen);
// pDC->SetROP2(R2_NOTXORPEN);
}

CRect rect=m_rect;
switch(m_nShape)
{
case roundRect:
pDC->RoundRect(rect, m_round);
break;
case arc:
//BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd );
pDC->Arc(rect,CPoint(rect.TopLeft()+m_startArc),CPoint(rect.BottomRight()-m_startArc));
break;
}
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}//OK!


CDrawObj* CDrawRound::Clone(CDrawDoc* pDoc,BOOL bAdd)
{
ASSERT_VALID(this);

CDrawRound* pClone = new CDrawRound(m_rect);
pClone->m_rect=m_rect;
pClone->m_logPen=m_logPen;
pClone->m_logBrush=m_logBrush;
pClone->m_nShape=m_nShape;
pClone->m_round=m_round;

ASSERT_VALID(pClone);

if (pDoc != NULL && bAdd) pDoc->Add(pClone);

return pClone;
}



CPoint CDrawRound::GetCtrPointPosition(int nCtrID)
{
ASSERT_VALID(this);
switch(m_nShape)
{
case arc:
if(nCtrID==9)
{
CRect rect=m_rect;
rect.NormalizeRect();
CPoint point;
point=rect.BottomRight();
point.x-=m_startArc.x/2;
point.y-=m_startArc.y/2;
return point;
}
break;
case roundRect:
if(nCtrID==9)
{
CRect rect=m_rect;
rect.NormalizeRect();
CPoint point;
point=rect.BottomRight();
point.x-=m_round.x/2;    
point.y-=m_round.y/2;
return point;
}
break;
default:
ASSERT(FALSE);

}
return CDrawObj::GetCtrPointPosition(nCtrID);
}


HCURSOR CDrawRound::GetCtrPointCursor(int nCtrID)
{
ASSERT_VALID(this);
if(nCtrID==9)
{
return AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
}
return CDrawObj::GetCtrPointCursor(nCtrID);
}


void CDrawRound::MouseMove(int nCtrID,CPoint point,CDrawView* pView)
{
ASSERT_VALID(this);
if(nCtrID==9)
{
CRect rect=m_rect;
rect.NormalizeRect();


if (point.x > rect.right) point.x = rect.right;


else if (point.x < rect.left + rect.Width() / 2)
point.x = rect.left + rect.Width() / 2;

if (point.y > rect.bottom ) point.y = rect.bottom;


else if (point.y < rect.top + rect.Height() / 2)
point.y = rect.top + rect.Height() / 2;

if(m_nShape==roundRect)
{
m_round.x = 2 * (rect.right - point.x);
m_round.y = 2 * (rect.bottom - point.y);
}
else
{
m_startArc.x=2*(rect.right-point.x);
m_startArc.y=2*(rect.bottom-point.y);
}
m_pDocument->SetModifiedFlag();
//if(pView==NULL)
// Invalidate();
//else
pView->InvalDrawObj(this);
return;
}
//baseclass@G mousemove H#Cb
CDrawObj::MouseMove(nCtrID,point,pView);
}

2)------DrawTool.h
///////DrawTool.h
#include "DrawObj.h"

class CDrawView;

class CDrawTool
{
public:
//constructor
CDrawTool(ToolShape shape);

//overridable operations
virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);
//operation
static CDrawTool* GetDrawTool(ToolShape shape);

//attributes
ToolShape m_toolShape;

static CPtrList c_drawTools;
static CPoint c_startPoint;
static CPoint c_endPoint;
static CPoint c_tempPoint;
static SelectState c_selectState;
static ToolShape c_toolShape;

//destructor
~CDrawTool();
};

///////////////////////////////
//CSelectTool class

class CSelectTool : public CDrawTool
{
public:
//constructor
CSelectTool();

//attributes
int m_dragPointID; //?

//operations
virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
//virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);

protected:
//CRect m_ctrRect;
};


////////////////////
//CDrawTools class

class CDrawTools : public CDrawTool
{
public:
//constructors
CDrawTools(ToolShape shape);

//operations
virtual void OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point);
//virtual void OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point);
virtual void OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point);

};

----------DrawTool.cpp

/////DrawTool.cpp
#include "stdafx.h"

#include "DrawTool.h"
#include "DrawObj.h"
#include "DrawDoc.h"
#include "DrawView.h"
#include "mainfrm.h"

//CDrawTool* GetDrawTool(ToolShape shape);
CPtrList CDrawTool::c_drawTools;
CPoint CDrawTool::c_startPoint;
CPoint CDrawTool::c_endPoint;
CPoint CDrawTool::c_tempPoint;
SelectState CDrawTool::c_selectState=none;
ToolShape CDrawTool::c_toolShape=select;

static CSelectTool selectTool;
static CDrawTools lineTool(line);
static CDrawTools rectTool(rectangle);
static CDrawTools ellipseTool(ellipse);
static CDrawTools roundRectTool(roundRect);
static CDrawTools arcTool(arc);
 

CDrawTool::CDrawTool(ToolShape shape)
{
m_toolShape=shape;
c_drawTools.AddTail(this);
}

CDrawTool::~CDrawTool()
{
}

CDrawTool* CDrawTool::GetDrawTool(ToolShape shape)
{
POSITION pos=c_drawTools.GetHeadPosition();
while(pos!=NULL)
{
CDrawTool* pTool=(CDrawTool*)c_drawTools.GetNext(pos);
if(pTool->m_toolShape==shape)
return pTool;
}
return NULL;
}

void CDrawTool::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{
//CWnd* SetCapture( );
pView->SetCapture();
c_startPoint=point;
c_endPoint=point;
}

void CDrawTool::OnLButtonDblClk(CDrawView* pView,UINT nFlags,const CPoint& point)
{
//int GetCount( ) const;


}

void CDrawTool::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
//BOOL ReleaseCapture(VOID)
ReleaseCapture();

}

void CDrawTool::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
c_endPoint=point;
//SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
//if (pView->m_selectList.GetCount() == 1)
//{
// CMainFrame* pMainFrame = (CMainFrame*) AfxGetMainWnd();
// pMainFrame->m_wndStatusBar.DrawCoordinate(2,CPoint(c_endPoint - c_startPoint));
//}
}

/////////////////CSelectTool implementation
CSelectTool::CSelectTool():CDrawTool(select)
{
c_selectState=none;  //static member
}

void CSelectTool::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{

CDrawObj* pObj;
CPoint logicalpoint=point;
pView->ClientToDoc(logicalpoint);//?

c_selectState=none;

if(pView->m_selectList.GetCount()==1)
{
pObj=pView->m_selectList.GetHead();
m_dragPointID=pObj->HitTest(logicalpoint,pView,TRUE);//HitTest controlID return
if(m_dragPointID!=0)
{
c_selectState=size;
//HCURSOR SetCursor( HCURSOR hCursor);
SetCursor(pObj->GetCtrPointCursor(m_dragPointID));
}
  }

if (c_selectState == none)
{
pObj = pView->GetDocument()->GetObjectAt(logicalpoint);//DrawDoc?!<- A$@G
if (pObj != NULL)
{
c_selectState = move;
pView->Select(pObj, (nFlags & MK_SHIFT) != 0);

if ((nFlags & MK_CONTROL) != 0)
pView->CloneSelect();
}

else
{
c_selectState = range;
// if ((nFlags & MK_SHIFT) == 0)
// pView->Select(NULL);
CClientDC dc(pView);
CRect rect(point.x, point.y, point.x, point.y);
rect.NormalizeRect();
dc.DrawFocusRect(rect);
}
}

c_tempPoint = logicalpoint;
CDrawTool::OnLButtonDown(pView, nFlags, point);

}

void CSelectTool::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
if (pView->GetCapture() == pView)
{
if (c_selectState == range)
{
CClientDC dc(pView);
CRect rect(c_startPoint.x, c_startPoint.y, c_endPoint.x, c_endPoint.y);
rect.NormalizeRect();
dc.DrawFocusRect(rect);
pView->SelectWithinRect(rect, TRUE);
}
else if (c_selectState != none)
{
POSITION pos = pView->m_selectList.GetHeadPosition();
while (pos != NULL)
{
CDrawObj* pObj = pView->m_selectList.GetNext(pos);

CRect tempRect = pObj->m_rect;
pObj->m_rect = pObj->m_prev;
pView->InvalDrawObj(pObj);
pObj->m_prev = pObj->m_rect = tempRect;
pView->InvalDrawObj(pObj);
}
pView->GetDocument()->UpdateAllViews(pView);
}
}
CDrawTool::OnLButtonUp(pView, nFlags, point);
}

void CSelectTool::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
if (pView->GetCapture() != pView)
{
//AfxMessageBox("pView->GetCapture() != pView");
if ( pView->m_selectList.GetCount() == 1)
{
CDrawObj* pObj = pView->m_selectList.GetHead();
CPoint logical = point;
pView->ClientToDoc(logical);
int nHandle = pObj->HitTest(logical, pView, TRUE);
if (nHandle != 0)
{
SetCursor(pObj->GetCtrPointCursor(nHandle));
return;
}
}
CDrawTool::OnMouseMove(pView, nFlags, point);
return;
}

if (c_selectState == range)
{
CClientDC dc(pView);
CRect rect(c_startPoint.x, c_startPoint.y, c_endPoint.x, c_endPoint.y);
rect.NormalizeRect();
dc.DrawFocusRect(rect);
rect.SetRect(c_startPoint.x, c_startPoint.y, point.x, point.y);
rect.NormalizeRect();
dc.DrawFocusRect(rect);

CDrawTool::OnMouseMove(pView, nFlags, point);
return;
}

CPoint logical = point;
pView->ClientToDoc(logical);
CPoint delta = (CPoint)(logical - c_tempPoint);
POSITION pos = pView->m_selectList.GetHeadPosition();
while (pos != NULL)
{
CDrawObj* pObj = pView->m_selectList.GetNext(pos);
CRect position = pObj->m_rect;
if (c_selectState == move)
{
position += delta;
pObj->MoveTo(position, pView);
}
else if (m_dragPointID != 0)
pObj->MouseMove( m_dragPointID, logical, pView);
}
c_tempPoint = logical;
c_endPoint = point;
if (c_selectState == size)
{
SetCursor(pView->m_selectList.GetHead()->GetCtrPointCursor(m_dragPointID));
return;
}
CDrawTool::OnMouseMove(pView, nFlags, point);
}


////////////////CDrawTools implementation


CDrawTools::CDrawTools(ToolShape shape):CDrawTool(shape)
{
}

void CDrawTools::OnLButtonDown(CDrawView* pView,UINT nFlags,const CPoint& point)
{
CDrawTool::OnLButtonDown(pView,nFlags,point);

CPoint logical=point;
pView->ClientToDoc(logical);
c_tempPoint=logical;
CDrawObj * pObj;

switch(c_toolShape)
{
case line:
{
pObj= new CDrawLine(CRect(logical,CSize(0,0)));
}
break;
case rectangle:
{
pObj=new CDrawRect(CRect(logical,CSize(0,0)));
pObj->m_nShape=rectangle;
}
break;
case ellipse:
{
pObj=new CDrawRect(CRect(logical,CSize(0,0)));
pObj->m_nShape=ellipse;
}
break;
case roundRect:
{
pObj=new CDrawRound(CRect(logical,CSize(0,0)));
pObj->m_nShape=roundRect;
}
break;
case arc:
{
pObj=new CDrawRound(CRect(logical,CSize(0,0)));
pObj->m_nShape=arc;
}
break;
default:
pObj=new CDrawLine(CRect(logical,CSize(0,0)));
break;

}

pView->GetDocument()->Add(pObj);
c_selectState=none;
pView->OnUpdate(NULL,HINT_UPDATE_SELECTION,NULL);
pView->m_selectList.RemoveAll();
pView->m_selectList.AddTail(pObj);
}

void CDrawTools::OnLButtonUp(CDrawView* pView,UINT nFlags,const CPoint& point)
{
if(point==c_startPoint)
{
CDrawObj* pObj=pView->m_selectList.GetTail();
pView->GetDocument()->Remove(pObj);
pObj->Remove();
selectTool.OnLButtonDown(pView,nFlags,point);
}

else if(pView->m_selectList.GetCount()==1)
{
CDrawObj* pObj=pView->m_selectList.GetHead();
c_selectState=draw;
pView->InvalDrawObj(pObj);
pObj->m_prev=pObj->m_rect;
}
CDrawTool::OnLButtonUp(pView,nFlags,point);
}

void CDrawTools::OnMouseMove(CDrawView* pView,UINT nFlags,const CPoint& point)
{
if(pView->GetCapture() ==pView)
{
CPoint logicalpoint=point;
pView->ClientToDoc(logicalpoint);
CDrawObj* pObj=pView->m_selectList.GetHead();
CRect rect=pObj->m_rect;
rect.left=logicalpoint.x;
rect.top=logicalpoint.y;
pObj->MoveTo(rect,pView);
c_tempPoint=logicalpoint;
}

CDrawTool::OnMouseMove(pView,nFlags,point);
}
--------------3)toolbar.h
/////toolbar.h
#ifndef __TOOLBAR_H__
#define __TOOLBAR_H__


class CPaletteBar : public CToolBar
{
// Construction
public:
void SetColumns(UINT nColumns);
UINT GetColumns();
CPaletteBar();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPaletteBar)
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CPaletteBar();

// Generated message map functions
protected:
UINT m_nColumns;
//{{AFX_MSG(CPaletteBar)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

#endif
-------3)toolbar.cpp
////toolbar.cpp


#include "stdafx.h"
#include "draw.h"
#include "toolbar.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CPaletteBar::CPaletteBar()
{
}
CPaletteBar::~CPaletteBar()
{
}
BEGIN_MESSAGE_MAP(CPaletteBar, CToolBar)
//{{AFX_MSG_MAP(CPaletteBar)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


UINT CPaletteBar::GetColumns()
{
return m_nColumns;
}

void CPaletteBar::SetColumns(UINT nColumns)
{
m_nColumns = nColumns;
int nCount = GetToolBarCtrl().GetButtonCount();

for(int i=0; i<nCount; i++){

UINT nStyle = GetButtonStyle(i);
BOOL bWrap = (((i+1) % nColumns) == 0);

if(bWrap) nStyle |= TBBS_WRAPPED;
else nStyle &= ~TBBS_WRAPPED;

SetButtonStyle(i, nStyle);
}

Invalidate();
GetParentFrame()->RecalcLayout();
}
--------4)draw.h
// draw.h : main header file for the DRAW application
//

#if !defined(AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"       // main symbols
#include "afxtempl.h"

/////////////////////////////////////////////////////////////////////////////
// CDrawApp:
// See draw.cpp for the implementation of this class
//

class CDrawApp : public CWinApp
{
public:
CDrawApp();

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDrawApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CDrawApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAW_H__F3513DA5_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
---------4)draw.cpp

// draw.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "draw.h"

#include "MainFrm.h"
#include "ChildFrm.h"
#include "drawDoc.h"
#include "drawView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawApp

BEGIN_MESSAGE_MAP(CDrawApp, CWinApp)
//{{AFX_MSG_MAP(CDrawApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawApp construction

CDrawApp::CDrawApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDrawApp object

CDrawApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CDrawApp initialization

BOOL CDrawApp::InitInstance()
{
AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
//  of your final executable, you should remove from the following
//  the specific initialization routines you do not need.

#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));

LoadStdProfileSettings();  // Load standard INI file options (including MRU)

// Register the application's document templates.  Document templates
//  serve as the connection between documents, frame windows and views.

CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_DRAWTYPE,
RUNTIME_CLASS(CDrawDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CDrawView));
AddDocTemplate(pDocTemplate);

// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;

// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();

// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;

// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();

return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CDrawApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CDrawApp commands
----------5)drawDoc.h

// drawDoc.h : interface of the CDrawDoc class
//
/////////////////////////////////////////////////////////////////////////////
#include "drawobj.h"

#if !defined(AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class CDrawView;

class CDrawDoc : public CDocument
{
protected: // create from serialization only
CDrawDoc();
DECLARE_DYNCREATE(CDrawDoc)

// Attributes
public:
CDrawObjList m_objects;
int m_nMapMode;

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDrawDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CDrawDoc();
CDrawObj* GetObjectAt(const CPoint&  point);
CDrawObjList * GetObjects() {return &m_objects;}

void Add(CDrawObj* pObj);
void Remove(CDrawObj* pObj);
void Draw(CDC* pDC,CDrawView * pView );
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
//{{AFX_MSG(CDrawDoc)
// NOTE - the ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAWDOC_H__F3513DAD_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
--------5)drawDoc.cpp

// drawDoc.cpp : implementation of the CDrawDoc class
//

#include "stdafx.h"
#include "draw.h"

#include "drawDoc.h"
#include "drawview.h"
#include "drawtool.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc

IMPLEMENT_DYNCREATE(CDrawDoc, CDocument)

BEGIN_MESSAGE_MAP(CDrawDoc, CDocument)
//{{AFX_MSG_MAP(CDrawDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc construction/destruction

CDrawDoc::CDrawDoc()
{
// TODO: add one-time construction code here
m_nMapMode=MM_TEXT;  //-MM_TEXT
}

CDrawDoc::~CDrawDoc()
{
POSITION pos=m_objects.GetHeadPosition();
while(pos !=NULL)
delete m_objects.GetNext(pos);
}

BOOL CDrawDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;

// TODO: add reinitialization code here
// (SDI documents will reuse this document)

return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CDrawDoc serialization

void CDrawDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
m_objects.Serialize(ar);
}
else
{
// TODO: add loading code here
m_objects.Serialize(ar);
}
CDocument::Serialize(ar);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc diagnostics

#ifdef _DEBUG
void CDrawDoc::AssertValid() const
{
CDocument::AssertValid();
}

void CDrawDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDrawDoc commands

CDrawObj* CDrawDoc::GetObjectAt(const CPoint&  point)
{
    CRect rect(point, CSize(1, 1));
POSITION pos = m_objects.GetTailPosition();
while (pos != NULL)
{
CDrawObj* pObj = m_objects.GetPrev(pos);
if (pObj->IsCross(rect)) return pObj;
}
return NULL;
}

void CDrawDoc::Add(CDrawObj* pObj)
{
m_objects.AddTail(pObj);
pObj->m_pDocument=this;
SetModifiedFlag();
}

void CDrawDoc::Remove(CDrawObj* pObj)
{
POSITION pos = m_objects.Find(pObj);
if(pos != NULL)
m_objects.RemoveAt(pos);
SetModifiedFlag();
pos=GetFirstViewPosition();
while(pos!=NULL)
((CDrawView*)GetNextView(pos))->Remove(pObj);
}

void CDrawDoc::Draw(CDC* pDC,CDrawView * pView )
{
POSITION pos = m_objects.GetHeadPosition();
while (pos != NULL)
{
CDrawObj* pObj = m_objects.GetNext(pos);
pObj->Draw(pDC, FALSE);
if(!pDC->IsPrinting() && pView->IsSelected(pObj))
pObj->DrawCtrPoints(pDC, CDrawTool::c_selectState);
}

}

-------6)drawView.h
// drawView.h : interface of the CDrawView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define HINT_UPDATE_SELECTION  0
#define HINT_DELETE_SELECTION  1

class CDrawObj;

class CDrawView : public CScrollView
{
protected: // create from serialization only
CDrawView();
DECLARE_DYNCREATE(CDrawView)

// Attributes
public:
CDrawObj* m_selectObj;
CDrawObjList m_selectList;
CDrawObjList m_selectEdit;
      BOOL m_bDragging;



// Operations
public:
CDrawDoc* GetDocument();
virtual void OnUpdate(CScrollView* pSender,LPARAM lHint, CObject* pHint);

void Remove(CDrawObj* pObj);
BOOL IsSelected(CDrawObj* pObj) const ;
void InvalDrawObj(CDrawObj* pObj);
void Select(CDrawObj* pObj,BOOL bAdd=FALSE);
void SelectWithinRect(CRect rect,BOOL bAdd);
void CloneSelect();

void ClientToDoc(CPoint & point);
void ClientToDoc(CRect& rect);
void DocToClient(CPoint& point);
void DocToClient(CRect& rect);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDrawView)
public:
virtual void OnDraw(CDC* pDC);  // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate(); // called first time after construct
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CDrawView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg void OnToolSelection(UINT ID);
afx_msg void OnUpdateToolSelection(CCmdUI* pCmdUI);
DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in drawView.cpp
inline CDrawDoc* CDrawView::GetDocument()
   { return (CDrawDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAWVIEW_H__F3513DAF_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
--------6)DrawView.cpp
// drawView.cpp : implementation of the CDrawView class
//

#include "stdafx.h"
#include "draw.h"
#include "drawobj.h"
#include "drawtool.h"
#include "drawDoc.h"
#include "drawView.h"
#include "mainfrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDrawView

IMPLEMENT_DYNCREATE(CDrawView, CScrollView)

BEGIN_MESSAGE_MAP(CDrawView, CScrollView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND_RANGE(ID_TOOL_SELECT, ID_TOOL_ARC, OnToolSelection)
ON_UPDATE_COMMAND_UI_RANGE(ID_TOOL_SELECT, ID_TOOL_ARC, OnUpdateToolSelection)
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrawView construction/destruction

CDrawView::CDrawView()
{
// TODO: add construction code here
CDrawTool::c_toolShape=select;

}

CDrawView::~CDrawView()
{
}

BOOL CDrawView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs

return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView drawing
void CDrawView::OnDraw(CDC* pDC)
{
CDrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

// TODO: add draw code for native data here
ASSERT_VALID(this);
CDC dc;
CDC* pMemDC=pDC;
CBitmap bitmap;
CBitmap* pOldBitmap;

CRect client;
pDC->GetClipBox(client);
CRect rect=client;
DocToClient(rect);


if (dc.CreateCompatibleDC(pDC))
{
if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
{
//TCHAR str[50];
//wsprintf(str,"rect.width() is %d,rect.height() is %d",rect.Width(),rect.Height());
//AfxMessageBox(str);
OnPrepareDC(&dc, NULL);
pMemDC = &dc;
dc.OffsetViewportOrg(-rect.left, -rect.top);
pOldBitmap = dc.SelectObject(&bitmap);
//dc.IntersectClipRect(client);
}
}

CBrush brush;
if (!brush.CreateSolidBrush(RGB(255,255,255)))
return;  

pMemDC->FillRect(client, &brush);


pDoc->Draw(pMemDC, this);
     
if (pMemDC != pDC)
{
pDC->SetViewportOrg(0, 0);
pDC->SetWindowOrg(0,0);
pDC->SetMapMode(MM_TEXT);
dc.SetViewportOrg(0, 0);
dc.SetWindowOrg(0,0);
dc.SetMapMode(MM_TEXT);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&dc, 0, 0, SRCCOPY);
dc.SelectObject(pOldBitmap);
}
}

void CDrawView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView printing


BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void CDrawView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void CDrawView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CDrawView diagnostics

#ifdef _DEBUG
void CDrawView::AssertValid() const
{
CScrollView::AssertValid();
}

void CDrawView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}

CDrawDoc* CDrawView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawDoc)));
return (CDrawDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDrawView message handlers

void CDrawView::OnToolSelection(UINT ID)
{
switch(ID)
{
case ID_TOOL_SELECT: CDrawTool::c_toolShape = select; break;
case ID_TOOL_LINE: CDrawTool::c_toolShape = line; break;
case ID_TOOL_RECT: CDrawTool::c_toolShape = rectangle; break;
case ID_TOOL_ROUNDRECT: CDrawTool::c_toolShape = roundRect; break;
case ID_TOOL_ELLIPSE: CDrawTool::c_toolShape = ellipse; break;
case ID_TOOL_ARC: CDrawTool::c_toolShape = arc; break;
}
}

void CDrawView::OnUpdateToolSelection(CCmdUI* pCmdUI)
{
switch(pCmdUI->m_nID){
case ID_TOOL_SELECT:
pCmdUI->SetRadio(CDrawTool::c_toolShape == select );
break;
case ID_TOOL_LINE:
pCmdUI->SetRadio(CDrawTool::c_toolShape == line );
break;
case ID_TOOL_RECT:
pCmdUI->SetRadio(CDrawTool::c_toolShape == rectangle );
break;
case ID_TOOL_ROUNDRECT:
pCmdUI->SetRadio(CDrawTool::c_toolShape == roundRect );
break;
case ID_TOOL_ELLIPSE:
pCmdUI->SetRadio(CDrawTool::c_toolShape == ellipse );
break;
case ID_TOOL_ARC:
pCmdUI->SetRadio(CDrawTool::c_toolShape == arc );
break;
}
}


void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
if(pTool!=NULL)
pTool->OnLButtonDown(this,nFlags,point);

//CScrollView::OnLButtonDown(nFlags, point);
}

void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
if(pTool!=NULL)
pTool->OnLButtonUp(this,nFlags,point);
//CScrollView::OnLButtonUp(nFlags, point);
}

void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDrawTool* pTool=CDrawTool::GetDrawTool(CDrawTool::c_toolShape);
if(pTool!=NULL)
pTool->OnMouseMove(this,nFlags,point);
//CScrollView::OnMouseMove(nFlags, point);
}

void CDrawView::OnUpdate(CScrollView* pSender,LPARAM lHint, CObject* pHint)
{
switch(lHint)
{
case HINT_UPDATE_SELECTION:
{

CDrawObjList* pList = pHint != NULL ?
(CDrawObjList*)pHint : &m_selectList;
POSITION pos = pList->GetHeadPosition();
while (pos != NULL)
InvalDrawObj(pList->GetNext(pos));
}
break;
case HINT_DELETE_SELECTION:
{
CDrawObjList* pList =  &m_selectList;
POSITION pos = pList->GetHeadPosition();
while (pos != NULL)
{
CDrawObj* pObj = pList->GetNext(pos);
InvalDrawObj(pObj);
Remove(pObj);  
GetDocument()->Remove(pObj);
pObj->Remove();
}
m_selectList.RemoveAll();
}
break;
default:
ASSERT(FALSE);
break;
}

}

void CDrawView::Remove(CDrawObj* pObj)
{
POSITION pos=m_selectList.Find(pObj);
if(pos!=NULL)
m_selectList.RemoveAt(pos);
}

BOOL CDrawView::IsSelected(CDrawObj* pObj) const
{
return m_selectList.Find(pObj)!=NULL;
}

void CDrawView::InvalDrawObj(CDrawObj* pObj)
{
CRect rect=pObj->m_rect;
DocToClient(rect);
if(IsSelected(pObj))
{
rect.left -=4;
rect.top -=4;
rect.right +=4;
rect.bottom +=4;
}
//rect.InflateRect(1,1);
InvalidateRect(rect,FALSE);
}

void CDrawView::Select(CDrawObj* pObj,BOOL bAdd)
{
if(!bAdd)
{
OnUpdate(NULL,HINT_UPDATE_SELECTION,NULL);
m_selectList.RemoveAll();
}

if(pObj==NULL || IsSelected(pObj))
return;
m_selectList.AddTail(pObj);
InvalDrawObj(pObj);
}

void CDrawView::SelectWithinRect(CRect rect,BOOL bAdd)
{
if (!bAdd) Select(NULL);

ClientToDoc(rect);
OnUpdate(NULL, HINT_UPDATE_SELECTION, NULL);
m_selectList.RemoveAll();
CDrawObjList* pObList = GetDocument()->GetObjects();
POSITION posObj = pObList->GetHeadPosition();
while (posObj != NULL)
{
CDrawObj* pObj = pObList->GetNext(posObj);
if (pObj->IsCross(rect)){
Select(pObj,TRUE);
InvalDrawObj(pObj);
}
}

}

void CDrawView::CloneSelect()
{
POSITION pos = m_selectList.GetHeadPosition();
while (pos != NULL)
{
CDrawObj* pObj = m_selectList.GetNext(pos);
pObj->Clone(pObj->m_pDocument);
}
}

void CDrawView::ClientToDoc(CPoint & point)
{
CClientDC dc(this);
OnPrepareDC(&dc,NULL);
dc.DPtoLP(&point);
}

void CDrawView::ClientToDoc(CRect& rect)
{
ASSERT_VALID(this);
CClientDC dc(this);
OnPrepareDC(&dc,NULL);
dc.DPtoLP(rect);
}

void CDrawView::DocToClient(CPoint& point)
{
CClientDC dc(this);
OnPrepareDC(&dc,NULL);
dc.LPtoDP(&point);
}

void CDrawView::DocToClient(CRect& rect)
{
CClientDC dc(this);
OnPrepareDC(&dc,NULL);
dc.LPtoDP(rect);
rect.NormalizeRect();
}

------------7)MainFrm.h
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "toolbar.h"
//class CPaletteBar;

class CMainFrame : public CMDIFrameWnd
{
DECLARE_DYNAMIC(CMainFrame)
public:
CMainFrame();


// Attributes
public:

CPaletteBar m_wndPaletteBar;

// Operations
public:

BOOL CreatePaletteBar();



// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // control bar embedded members
CStatusBar  m_wndStatusBar;
CToolBar    m_wndToolBar;


// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI);
//}}AFX_MSG
afx_msg BOOL OnBarCheck(UINT nID);
DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__F3513DA9_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

--------7)MainFrm.cpp
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "draw.h"
#include "toolbar.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(IDW_PALETTE_BAR, OnUpdateControlBarMenu)
//}}AFX_MSG_MAP
ON_COMMAND_EX(IDW_PALETTE_BAR,OnBarCheck)
END_MESSAGE_MAP()

static UINT indicators[] =
{
ID_SEPARATOR,           // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
// TODO: add member initialization code here

}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1;      // fail to create
}

if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
  sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1;      // fail to create
}

// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

// TODO: Delete these three lines if you don't want the toolbar to
//  be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);


if(! CreatePaletteBar())
{
TRACE0("Failed to create Palette bar\n");
return -1;      // fail to create
}

return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs

return CMDIFrameWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
BOOL CMainFrame::CreatePaletteBar()
{
static UINT BASED_CODE PaletteButtons[] =
{
ID_TOOL_SELECT,
ID_TOOL_LINE,    
ID_TOOL_RECT,    
ID_TOOL_ROUNDRECT,    
ID_TOOL_ELLIPSE,
ID_TOOL_ARC,

};

if (!m_wndPaletteBar.Create(this,  WS_VISIBLE | WS_CHILD |
CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS |CBRS_TOP|
CBRS_FLYBY , IDW_PALETTE_BAR) ||
!m_wndPaletteBar.LoadBitmap(IDR_PALETTE_BAR) ||
!m_wndPaletteBar.SetButtons(PaletteButtons,
sizeof(PaletteButtons)/sizeof(UINT)))
{
TRACE0("Failed to create Palettebar\n");
return -1;      // fail to create
}
m_wndPaletteBar.SetWindowText(_T("Palette"));
m_wndPaletteBar.EnableDocking(CBRS_ALIGN_ANY);

CPoint pt(GetSystemMetrics(SM_CXSCREEN)/ 3,
GetSystemMetrics(SM_CYSCREEN) / 5);

m_wndPaletteBar.SetColumns(2);
FloatControlBar(&m_wndPaletteBar, pt);

return TRUE;
}


void CMainFrame::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
CControlBar* pBar = GetControlBar(pCmdUI->m_nID);
if (pBar != NULL)
{
pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);
return;
}
pCmdUI->ContinueRouting();
}

BOOL CMainFrame::OnBarCheck(UINT nID)
{
CControlBar* pBar = GetControlBar(nID);
if (pBar != NULL)
{
ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);
return TRUE;
}
return FALSE;
}
--------8)ChildFrm.h
// ChildFrm.h : interface of the CChildFrame class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

class CChildFrame : public CMDIChildWnd
{
DECLARE_DYNCREATE(CChildFrame)
public:
CChildFrame();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChildFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CChildFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

// Generated message map functions
protected:
//{{AFX_MSG(CChildFrame)
// NOTE - the ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CHILDFRM_H__F3513DAB_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

-------8)ChildFrm.cpp
// ChildFrm.cpp : implementation of the CChildFrame class
//

#include "stdafx.h"
#include "draw.h"

#include "ChildFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CChildFrame

IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
//{{AFX_MSG_MAP(CChildFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChildFrame construction/destruction

CChildFrame::CChildFrame()
{
// TODO: add member initialization code here

}

CChildFrame::~CChildFrame()
{
}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs

return CMDIChildWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CChildFrame diagnostics

#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
CMDIChildWnd::AssertValid();
}

void CChildFrame::Dump(CDumpContext& dc) const
{
CMDIChildWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChildFrame message handlers
----------9)stdafx.h
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_)
#define AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC OLE automation classes
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT


//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__F3513DA7_2B88_11D2_9D9D_006097DDC581__INCLUDED_)

-----9)stdafx.cpp
// stdafx.cpp : source file that includes just the standard includes
// draw.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

---------10)resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by draw.rc
//
#define IDD_ABOUTBOX                    100
#define IDR_MAINFRAME                   128
#define IDR_DRAWTYPE                    129
#define IDR_PALETTE_BAR                 130
#define ID_TOOL_SELECT                  32771
#define ID_MENUITEM32772                32772
#define ID_TOOL_LINE                    32773
#define ID_TOOL_RECT                    32774
#define ID_TOOL_ROUNDRECT               32775
#define ID_TOOL_ELLIPSE                 32776
#define ID_TOOL_ARC                     32777
#define IDW_PALETTE_BAR                 32778
#define IDW_COLOR_BAR                   32779

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS                     1
#define _APS_NEXT_RESOURCE_VALUE        131
#define _APS_NEXT_COMMAND_VALUE         32780
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
---------end of file
 
 
 
   
 
 


0
 
LVL 1

Expert Comment

by:Booth882
ID: 1169753
what is going on with your program, man? that was complete madness!  
0
 

Author Comment

by:k1024
ID: 1169754
I'm too crazy, I think no problem but building this program
token error !!! and many of error !!!

IMPLEMENT_SREIAL( CDrawRect, CDrawObj, 0)
C:\Program Files\DevStudio\MyProjects\draw\DrawObj.cpp(458) : error C2059: syntax error : 'constant'
and 78 error create!!!!

0
 
LVL 22

Expert Comment

by:nietod
ID: 1169755
That means there is code that it is interpretting as an ilegal constant on line 458 of DrawObj.cpp.  post the code at and around that line.  (Just post 1 or two lines before it and 1 or two lines after it--don't post the whole thing!)  
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:k1024
ID: 1169756
-----line455~463---------
///////////////////////
//CDrawRect

IMPLEMENT_SREIAL( CDrawRect, CDrawObj, 0)  

CDrawRect::CDrawRect()
{
      m_nCtrCount=8; //ÄÁÆ®·Ñ Æ÷ÀÎÆ®ÀÇ °¹¼ö
}
-------end of list-----------------------
0
 
LVL 22

Expert Comment

by:nietod
ID: 1169757
Do you need a ";" after the IMPLIMENT_SERIAL?  I believe you do.  

If that doesn't help.  Ask a new question for 0 points with my name on it.  We'll have to continue on this in a new question, because this one takes TOO long to load.
0
 
LVL 1

Accepted Solution

by:
payn earned 200 total points
ID: 1169758
You don't need a semicolon after IMPLEMENT_SERIAL. Look at what the macro expands to; it includes it own semicolon.

You do need to spell it right. You've spelled it as "IMPLEMENT_SREIAL," not only in your code, but in both subsequent messages. That's exactly the error message you'll get when you put any garbage string of characters in place of the macro name in an otherwise valid macro call.

Fix your spelling and it should go away.

By the way, a good way to deal with problems like this--where the compiler gives you cryptic error messages and the line referred to contains an MFC macro--is to manually expand the offending MFC macro, which will make the compiler give you better error messages. Or make the preprocessor manually expand your macro by compiling with -i, then compile the intermediate file. Again, you'll get better error messages.

In this case, running the compiler with -i would have left the macro unexpanded, which would give you a good idea that you weren't using a valid macro.


0
 
LVL 22

Expert Comment

by:nietod
ID: 1169759
k1024, I spent a lot of time on this and you accepted an answer for this from, payn, that had the same information that I had already told you.  
0
 

Author Comment

by:k1024
ID: 1169760
yes.I see...
To expert group
this problem is previously solved  by netiod!!!
and I hope my 200 point is gived netiod..
I send my project file to netiod, so he solved problem and send
me email with problem solution.
of course,thanks for payn's comment
0
 

Author Comment

by:k1024
ID: 1169761
It's a my mistake!!!
IMPLEMENT_SREIAL( CDrawRect, CDrawObj, 0)
===>IMPLEMENT_SERIAL( CDrawRect, CDrawObj, 0)

then compile and build, program is running !!!
this is a basic graphic editor.
as I compiling this project,there is no compile error
so I absolutly thinked not miss typing...
but,because  this is a  dynamic macro, this is not catch!!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1169762
k1024, in the future, look to see the name on the "Proposed answer"  (now "accepted answer").  Make sure it is the name of the expert that you want to get the grade.
0
 
LVL 1

Expert Comment

by:payn
ID: 1169763
I just wanted to point something out--nietod, I don't see an answer or comment from you anywhere here that pointed out the solution. (The last thing I saw from you was a suggestion that he needed a semicolon, which is wrong--and you corrected his misspelling, but added one of your own--from IMPLEMENT_SREIAL to IMPLIMENT_SERIAL.)

I have no doubt that you emailed him a solution and a good explanation--I've seen your other answers and comments and you obviously know what you're talking about and how to explain it. But--and bear in mind that I don't know the EE system too well--shouldn't you post the solution as well as emailing it to the questioner, so future readers can see it? Don't people have to spend points to read old questions?

By the way, it would be nice if VC's compiler could give better error messages in cases like this. Of course if MFC didn't use so many macros that wouldn't be as much of a problem...

0
 
LVL 22

Expert Comment

by:nietod
ID: 1169764
I was not criticising you.  There was no way for you to know what had happened behind the scenes.  But to clarify,

I had pointed out the fact that it was commented out because that was an obvious problem and then didn't look closely enough to see spelling error.  I informed him of the spellling error in an e-mail after he sent me the code.

I had not intended for him to reject my answer on this question.  I suggested that he ask a new question for 0 points so that I could continue to dicuss the problem without having to return to this BIG and SLOW page.  But instead he rejected my answer and asked a new one for 200 points.  Then you answered this one and he accepted it.  Just a comedy of errors...

Hopefully, it won't happen again.  EE finally added a message that informs the client of which expert will get the points.  We've been having lots of problems where the wrong expert gets the grade.   I lost 3 questions like that alone this weekend.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now