home *** CD-ROM | disk | FTP | other *** search
/ Mastering Microsoft Visual C++ 4 (2nd Edition) / VisualC4.ISO / minidrw6 / minidrvw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  10.9 KB  |  358 lines

  1. // MiniDrVw.cpp : implementation of the CMiniDrawView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "MiniDraw.h"
  6.  
  7. #include "MiniDDoc.h"
  8. #include "MiniDrVw.h"
  9.  
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CMiniDrawView
  18.  
  19. IMPLEMENT_DYNCREATE(CMiniDrawView, CScrollView)
  20.  
  21. BEGIN_MESSAGE_MAP(CMiniDrawView, CScrollView)
  22.    //{{AFX_MSG_MAP(CMiniDrawView)
  23.    ON_WM_LBUTTONDOWN()
  24.    ON_WM_MOUSEMOVE()
  25.    ON_WM_LBUTTONUP()
  26.    //}}AFX_MSG_MAP
  27. END_MESSAGE_MAP()
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CMiniDrawView construction/destruction
  31.  
  32. CMiniDrawView::CMiniDrawView()
  33. {
  34.    // TODO: add construction code here
  35.  
  36.    m_Dragging = 0;
  37.    m_HArrow = AfxGetApp ()->LoadStandardCursor (IDC_ARROW);
  38.    m_HCross = AfxGetApp ()->LoadStandardCursor (IDC_CROSS);
  39.    m_PenDotted.CreatePen (PS_DOT, 1, RGB (0,0,0));
  40. }
  41.  
  42. CMiniDrawView::~CMiniDrawView()
  43. {
  44. }
  45.  
  46. BOOL CMiniDrawView::PreCreateWindow(CREATESTRUCT& cs)
  47. {
  48.    // TODO: Modify the Window class or styles here by modifying
  49.    //  the CREATESTRUCT cs
  50.  
  51.    m_ClassName = AfxRegisterWndClass
  52.       (CS_HREDRAW | CS_VREDRAW,                // class styles
  53.       0,                                       // no cursor
  54.       (HBRUSH)::GetStockObject (WHITE_BRUSH),  // assign white background brush
  55.       0);                                      // no icon
  56.    cs.lpszClass = m_ClassName;      
  57.  
  58.    return CScrollView::PreCreateWindow(cs);
  59. }
  60.    
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CMiniDrawView drawing
  63.  
  64. void CMiniDrawView::OnDraw(CDC* pDC)
  65. {
  66.    CMiniDrawDoc* pDoc = GetDocument();
  67.    ASSERT_VALID(pDoc);
  68.  
  69.    // TODO: add draw code for native data here
  70.  
  71.    CSize ScrollSize = GetTotalSize ();
  72.    pDC->MoveTo (ScrollSize.cx, 0);
  73.    pDC->LineTo (ScrollSize.cx, ScrollSize.cy);
  74.    pDC->LineTo (0, ScrollSize.cy);
  75.  
  76.    CRect ClipRect;
  77.    CRect DimRect;
  78.    CRect IntRect;
  79.    CFigure *PFigure;
  80.    
  81.    pDC->GetClipBox (&ClipRect);
  82.  
  83.    int NumFigs = pDoc->GetNumFigs ();
  84.    for (int Index = 0; Index < NumFigs; ++Index)
  85.       {
  86.       PFigure = pDoc->GetFigure (Index);
  87.       DimRect = PFigure->GetDimRect ();
  88.       if (IntRect.IntersectRect (DimRect, ClipRect))
  89.          PFigure->Draw (pDC);
  90.       }   
  91. }
  92.  
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CMiniDrawView diagnostics
  95.  
  96. #ifdef _DEBUG
  97. void CMiniDrawView::AssertValid() const
  98. {
  99.    CScrollView::AssertValid();
  100. }
  101.  
  102. void CMiniDrawView::Dump(CDumpContext& dc) const
  103. {
  104.    CScrollView::Dump(dc);
  105. }
  106.  
  107. CMiniDrawDoc* CMiniDrawView::GetDocument() // non-debug version is inline
  108. {
  109.    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMiniDrawDoc)));
  110.    return (CMiniDrawDoc*)m_pDocument;
  111. }
  112. #endif //_DEBUG
  113.  
  114. /////////////////////////////////////////////////////////////////////////////
  115. // CMiniDrawView message handlers
  116.  
  117. void CMiniDrawView::OnLButtonDown(UINT nFlags, CPoint point)
  118. {
  119.    // TODO: Add your message handler code here and/or call default
  120.  
  121.    CClientDC ClientDC (this);
  122.    OnPrepareDC (&ClientDC);
  123.    ClientDC.DPtoLP (&point);
  124.  
  125.    // test whether cursor is within drawing area of view window:
  126.    CSize ScrollSize = GetTotalSize ();
  127.    CRect ScrollRect (0, 0, ScrollSize.cx, ScrollSize.cy);
  128.    if (!ScrollRect.PtInRect (point))
  129.       return;
  130.  
  131.    // save cursor position, capture mouse, & set dragging flag:
  132.    m_PointOrigin = point;
  133.    m_PointOld = point;
  134.    SetCapture ();
  135.    m_Dragging = 1;
  136.  
  137.    // clip mouse cursor:
  138.    ClientDC.LPtoDP (&ScrollRect);
  139.    CRect ViewRect;
  140.    GetClientRect (&ViewRect);
  141.    CRect IntRect;
  142.    IntRect.IntersectRect (&ScrollRect, &ViewRect);
  143.    ClientToScreen (&IntRect);
  144.    ::ClipCursor (&IntRect);
  145.    
  146.    CScrollView::OnLButtonDown(nFlags, point);
  147. }
  148.  
  149. void CMiniDrawView::OnMouseMove(UINT nFlags, CPoint point) 
  150. {
  151.    // TODO: Add your message handler code here and/or call default
  152.  
  153.    CClientDC ClientDC (this);
  154.    OnPrepareDC (&ClientDC);
  155.    ClientDC.DPtoLP (&point);
  156.  
  157.    if (!m_Dragging)
  158.       {
  159.       CSize ScrollSize = GetTotalSize ();
  160.       CRect ScrollRect (0, 0, ScrollSize.cx, ScrollSize.cy);
  161.       if (ScrollRect.PtInRect (point))
  162.          ::SetCursor (m_HCross);
  163.       else
  164.          ::SetCursor (m_HArrow);      
  165.       return;
  166.       }
  167.    
  168.    ClientDC.SetROP2 (R2_NOT);
  169.    ClientDC.SelectObject (&m_PenDotted);
  170.    ClientDC.SetBkMode (TRANSPARENT);
  171.    ClientDC.SelectStockObject (NULL_BRUSH);
  172.    
  173.    switch (((CMiniDrawApp *)AfxGetApp ())->m_CurrentTool)
  174.       {
  175.       case ID_TOOLS_LINE:
  176.          ClientDC.MoveTo (m_PointOrigin);
  177.          ClientDC.LineTo (m_PointOld);
  178.          ClientDC.MoveTo (m_PointOrigin);
  179.          ClientDC.LineTo (point);
  180.          break;
  181.          
  182.       case ID_TOOLS_RECTANGLE:
  183.       case ID_TOOLS_RECTFILL:
  184.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  185.                              m_PointOld.x, m_PointOld.y);
  186.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  187.                              point.x, point.y);                             
  188.          break;                    
  189.          
  190.       case ID_TOOLS_RECTROUND:
  191.       case ID_TOOLS_RECTROUNDFILL:
  192.          {
  193.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  194.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  195.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  196.                              m_PointOld.x, m_PointOld.y,
  197.                              SizeRound, SizeRound);
  198.          SizeRound = (abs (point.x - m_PointOrigin.x) +
  199.                       abs (point.y - m_PointOrigin.y)) / 6;                             
  200.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  201.                              point.x, point.y,
  202.                              SizeRound, SizeRound);                             
  203.          break;                    
  204.          }
  205.  
  206.       case ID_TOOLS_CIRCLE:   
  207.       case ID_TOOLS_CIRCLEFILL:
  208.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  209.                            m_PointOld.x, m_PointOld.y);
  210.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  211.                            point.x, point.y);                             
  212.          break;            
  213.       }
  214.        
  215.    m_PointOld = point;
  216.               
  217.    CScrollView::OnMouseMove(nFlags, point);
  218. }
  219.  
  220. void CMiniDrawView::OnLButtonUp(UINT nFlags, CPoint point) 
  221. {
  222.    // TODO: Add your message handler code here and/or call default
  223.  
  224.    if (!m_Dragging)
  225.       return;
  226.    
  227.    m_Dragging = 0;
  228.    ::ReleaseCapture ();
  229.    ::ClipCursor (NULL);
  230.       
  231.    CClientDC ClientDC (this);
  232.    OnPrepareDC (&ClientDC);
  233.    ClientDC.DPtoLP (&point);
  234.    ClientDC.SetROP2 (R2_NOT);
  235.    ClientDC.SelectObject (&m_PenDotted);
  236.    ClientDC.SetBkMode (TRANSPARENT);
  237.    ClientDC.SelectStockObject (NULL_BRUSH);
  238.    
  239.    CMiniDrawApp *PApp = (CMiniDrawApp *)AfxGetApp ();
  240.    CFigure *PFigure;
  241.    
  242.    switch (PApp->m_CurrentTool)
  243.       {
  244.       case ID_TOOLS_LINE:
  245.          ClientDC.MoveTo (m_PointOrigin);
  246.          ClientDC.LineTo (m_PointOld);
  247.          PFigure = new CLine 
  248.             (m_PointOrigin.x, m_PointOrigin.y,
  249.             point.x, point.y,
  250.             PApp->m_CurrentColor,
  251.             PApp->m_CurrentThickness);                    
  252.          break;
  253.          
  254.       case ID_TOOLS_RECTANGLE:
  255.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  256.                              m_PointOld.x, m_PointOld.y);
  257.          PFigure = new CRectangle
  258.             (m_PointOrigin.x, m_PointOrigin.y,
  259.             point.x, point.y,
  260.             PApp->m_CurrentColor,
  261.             PApp->m_CurrentThickness);                    
  262.          break;
  263.                
  264.       case ID_TOOLS_RECTFILL:
  265.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  266.                              m_PointOld.x, m_PointOld.y);
  267.          PFigure = new CRectFill
  268.             (m_PointOrigin.x, m_PointOrigin.y,
  269.             point.x, point.y,
  270.             PApp->m_CurrentColor);
  271.          break;                    
  272.          
  273.       case ID_TOOLS_RECTROUND:
  274.          {
  275.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  276.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  277.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  278.                              m_PointOld.x, m_PointOld.y,
  279.                              SizeRound, SizeRound);
  280.          PFigure = new CRectRound
  281.             (m_PointOrigin.x, m_PointOrigin.y,
  282.             point.x, point.y,
  283.             PApp->m_CurrentColor,
  284.             PApp->m_CurrentThickness);                    
  285.          break;                    
  286.          }
  287.       
  288.       case ID_TOOLS_RECTROUNDFILL:
  289.          {
  290.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  291.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  292.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  293.                              m_PointOld.x, m_PointOld.y,
  294.                              SizeRound, SizeRound);
  295.          PFigure = new CRectRoundFill
  296.             (m_PointOrigin.x, m_PointOrigin.y,
  297.             point.x, point.y,
  298.             PApp->m_CurrentColor);
  299.          break;                    
  300.          }                    
  301.          
  302.       case ID_TOOLS_CIRCLE:   
  303.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  304.                            m_PointOld.x, m_PointOld.y);
  305.          PFigure = new CCircle
  306.             (m_PointOrigin.x, m_PointOrigin.y,
  307.             point.x, point.y,
  308.             PApp->m_CurrentColor,
  309.             PApp->m_CurrentThickness);                    
  310.          break;                  
  311.       
  312.       case ID_TOOLS_CIRCLEFILL:
  313.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  314.                            m_PointOld.x, m_PointOld.y);
  315.          PFigure = new CCircleFill
  316.             (m_PointOrigin.x, m_PointOrigin.y,
  317.             point.x, point.y,
  318.             PApp->m_CurrentColor);
  319.          break;            
  320.       }
  321.    
  322.    ClientDC.SetROP2 (R2_COPYPEN);
  323.    PFigure->Draw (&ClientDC);
  324.  
  325.    CMiniDrawDoc* PDoc = GetDocument();
  326.    PDoc->AddFigure (PFigure);
  327.    
  328.    PDoc->UpdateAllViews (this, 0, PFigure);
  329.               
  330.    CScrollView::OnLButtonUp(nFlags, point);
  331. }
  332.  
  333. void CMiniDrawView::OnInitialUpdate() 
  334. {
  335.    CScrollView::OnInitialUpdate();
  336.    
  337.    // TODO: Add your specialized code here and/or call the base class
  338.    
  339.    SIZE Size = {640, 480};
  340.    SetScrollSizes (MM_TEXT, Size); 
  341. }
  342.  
  343. void CMiniDrawView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  344. {
  345.    // TODO: Add your specialized code here and/or call the base class
  346.    
  347.    if (pHint != 0)
  348.       {
  349.       CRect InvalidRect = ((CLine *)pHint)->GetDimRect ();
  350.       CClientDC ClientDC (this);
  351.       OnPrepareDC (&ClientDC);
  352.       ClientDC.LPtoDP (&InvalidRect);
  353.       InvalidateRect (&InvalidRect);            
  354.       }
  355.    else
  356.       CScrollView::OnUpdate (pSender, lHint, pHint);      
  357. }
  358.