home *** CD-ROM | disk | FTP | other *** search
/ Mastering Microsoft Visual C++ 4 (2nd Edition) / VisualC4.ISO / minidrw7 / minidrvw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  12.3 KB  |  403 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.    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  28.    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  29. END_MESSAGE_MAP()
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CMiniDrawView construction/destruction
  33.  
  34. CMiniDrawView::CMiniDrawView()
  35. {
  36.    // TODO: add construction code here
  37.  
  38.    m_Dragging = 0;
  39.    m_HArrow = AfxGetApp ()->LoadStandardCursor (IDC_ARROW);
  40.    m_HCross = AfxGetApp ()->LoadStandardCursor (IDC_CROSS);
  41.    m_PenDotted.CreatePen (PS_DOT, 1, RGB (0,0,0));
  42. }
  43.  
  44. CMiniDrawView::~CMiniDrawView()
  45. {
  46. }
  47.  
  48. BOOL CMiniDrawView::PreCreateWindow(CREATESTRUCT& cs)
  49. {
  50.    // TODO: Modify the Window class or styles here by modifying
  51.    //  the CREATESTRUCT cs
  52.  
  53.    m_ClassName = AfxRegisterWndClass
  54.       (CS_HREDRAW | CS_VREDRAW,                // class styles
  55.       0,                                       // no cursor
  56.       (HBRUSH)::GetStockObject (WHITE_BRUSH),  // assign white background brush
  57.       0);                                      // no icon
  58.    cs.lpszClass = m_ClassName;      
  59.  
  60.    return CScrollView::PreCreateWindow(cs);
  61. }
  62.    
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CMiniDrawView drawing
  65.  
  66. void CMiniDrawView::OnDraw(CDC* pDC)
  67. {
  68.    CMiniDrawDoc* pDoc = GetDocument();
  69.    ASSERT_VALID(pDoc);
  70.  
  71.    // TODO: add draw code for native data here
  72.  
  73.    if (pDC->GetDeviceCaps (TECHNOLOGY) == DT_RASDISPLAY)
  74.       {
  75.       CSize ScrollSize = GetTotalSize ();
  76.       pDC->MoveTo (ScrollSize.cx, 0);
  77.       pDC->LineTo (ScrollSize.cx, ScrollSize.cy);
  78.       pDC->LineTo (0, ScrollSize.cy);
  79.       }
  80.  
  81.    CRect ClipRect;
  82.    CRect DimRect;
  83.    CRect IntRect;
  84.    CFigure *PFigure;
  85.    
  86.    pDC->GetClipBox (&ClipRect);
  87.  
  88.    int NumFigs = pDoc->GetNumFigs ();
  89.    for (int Index = 0; Index < NumFigs; ++Index)
  90.       {
  91.       PFigure = pDoc->GetFigure (Index);
  92.       DimRect = PFigure->GetDimRect ();
  93.       if (IntRect.IntersectRect (DimRect, ClipRect))
  94.          PFigure->Draw (pDC);
  95.       }   
  96. }
  97.  
  98. /////////////////////////////////////////////////////////////////////////////
  99. // CMiniDrawView diagnostics
  100.  
  101. #ifdef _DEBUG
  102. void CMiniDrawView::AssertValid() const
  103. {
  104.    CScrollView::AssertValid();
  105. }
  106.  
  107. void CMiniDrawView::Dump(CDumpContext& dc) const
  108. {
  109.    CScrollView::Dump(dc);
  110. }
  111.  
  112. CMiniDrawDoc* CMiniDrawView::GetDocument() // non-debug version is inline
  113. {
  114.    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMiniDrawDoc)));
  115.    return (CMiniDrawDoc*)m_pDocument;
  116. }
  117. #endif //_DEBUG
  118.  
  119. /////////////////////////////////////////////////////////////////////////////
  120. // CMiniDrawView message handlers
  121.  
  122. void CMiniDrawView::OnLButtonDown(UINT nFlags, CPoint point)
  123. {
  124.    // TODO: Add your message handler code here and/or call default
  125.  
  126.    CClientDC ClientDC (this);
  127.    OnPrepareDC (&ClientDC);
  128.    ClientDC.DPtoLP (&point);
  129.  
  130.    // test whether cursor is within drawing area of view window:
  131.    CSize ScrollSize = GetTotalSize ();
  132.    CRect ScrollRect (0, 0, ScrollSize.cx, ScrollSize.cy);
  133.    if (!ScrollRect.PtInRect (point))
  134.       return;
  135.  
  136.    // save cursor position, capture mouse, & set dragging flag:
  137.    m_PointOrigin = point;
  138.    m_PointOld = point;
  139.    SetCapture ();
  140.    m_Dragging = 1;
  141.  
  142.    // clip mouse cursor:
  143.    ClientDC.LPtoDP (&ScrollRect);
  144.    CRect ViewRect;
  145.    GetClientRect (&ViewRect);
  146.    CRect IntRect;
  147.    IntRect.IntersectRect (&ScrollRect, &ViewRect);
  148.    ClientToScreen (&IntRect);
  149.    ::ClipCursor (&IntRect);
  150.    
  151.    CScrollView::OnLButtonDown(nFlags, point);
  152. }
  153.  
  154. void CMiniDrawView::OnMouseMove(UINT nFlags, CPoint point) 
  155. {
  156.    // TODO: Add your message handler code here and/or call default
  157.  
  158.    CClientDC ClientDC (this);
  159.    OnPrepareDC (&ClientDC);
  160.    ClientDC.DPtoLP (&point);
  161.  
  162.    if (!m_Dragging)
  163.       {
  164.       CSize ScrollSize = GetTotalSize ();
  165.       CRect ScrollRect (0, 0, ScrollSize.cx, ScrollSize.cy);
  166.       if (ScrollRect.PtInRect (point))
  167.          ::SetCursor (m_HCross);
  168.       else
  169.          ::SetCursor (m_HArrow);      
  170.       return;
  171.       }
  172.    
  173.    ClientDC.SetROP2 (R2_NOT);
  174.    ClientDC.SelectObject (&m_PenDotted);
  175.    ClientDC.SetBkMode (TRANSPARENT);
  176.    ClientDC.SelectStockObject (NULL_BRUSH);
  177.    
  178.    switch (((CMiniDrawApp *)AfxGetApp ())->m_CurrentTool)
  179.       {
  180.       case ID_TOOLS_LINE:
  181.          ClientDC.MoveTo (m_PointOrigin);
  182.          ClientDC.LineTo (m_PointOld);
  183.          ClientDC.MoveTo (m_PointOrigin);
  184.          ClientDC.LineTo (point);
  185.          break;
  186.          
  187.       case ID_TOOLS_RECTANGLE:
  188.       case ID_TOOLS_RECTFILL:
  189.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  190.                              m_PointOld.x, m_PointOld.y);
  191.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  192.                              point.x, point.y);                             
  193.          break;                    
  194.          
  195.       case ID_TOOLS_RECTROUND:
  196.       case ID_TOOLS_RECTROUNDFILL:
  197.          {
  198.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  199.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  200.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  201.                              m_PointOld.x, m_PointOld.y,
  202.                              SizeRound, SizeRound);
  203.          SizeRound = (abs (point.x - m_PointOrigin.x) +
  204.                       abs (point.y - m_PointOrigin.y)) / 6;                             
  205.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  206.                              point.x, point.y,
  207.                              SizeRound, SizeRound);                             
  208.          break;                    
  209.          }
  210.  
  211.       case ID_TOOLS_CIRCLE:   
  212.       case ID_TOOLS_CIRCLEFILL:
  213.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  214.                            m_PointOld.x, m_PointOld.y);
  215.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  216.                            point.x, point.y);                             
  217.          break;            
  218.       }
  219.        
  220.    m_PointOld = point;
  221.               
  222.    CScrollView::OnMouseMove(nFlags, point);
  223. }
  224.  
  225. void CMiniDrawView::OnLButtonUp(UINT nFlags, CPoint point) 
  226. {
  227.    // TODO: Add your message handler code here and/or call default
  228.  
  229.    if (!m_Dragging)
  230.       return;
  231.    
  232.    m_Dragging = 0;
  233.    ::ReleaseCapture ();
  234.    ::ClipCursor (NULL);
  235.       
  236.    CClientDC ClientDC (this);
  237.    OnPrepareDC (&ClientDC);
  238.    ClientDC.DPtoLP (&point);
  239.    ClientDC.SetROP2 (R2_NOT);
  240.    ClientDC.SelectObject (&m_PenDotted);
  241.    ClientDC.SetBkMode (TRANSPARENT);
  242.    ClientDC.SelectStockObject (NULL_BRUSH);
  243.    
  244.    CMiniDrawApp *PApp = (CMiniDrawApp *)AfxGetApp ();
  245.    CFigure *PFigure;
  246.    
  247.    switch (PApp->m_CurrentTool)
  248.       {
  249.       case ID_TOOLS_LINE:
  250.          ClientDC.MoveTo (m_PointOrigin);
  251.          ClientDC.LineTo (m_PointOld);
  252.          PFigure = new CLine 
  253.             (m_PointOrigin.x, m_PointOrigin.y,
  254.             point.x, point.y,
  255.             PApp->m_CurrentColor,
  256.             PApp->m_CurrentThickness);                    
  257.          break;
  258.          
  259.       case ID_TOOLS_RECTANGLE:
  260.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  261.                              m_PointOld.x, m_PointOld.y);
  262.          PFigure = new CRectangle
  263.             (m_PointOrigin.x, m_PointOrigin.y,
  264.             point.x, point.y,
  265.             PApp->m_CurrentColor,
  266.             PApp->m_CurrentThickness);                    
  267.          break;
  268.                
  269.       case ID_TOOLS_RECTFILL:
  270.          ClientDC.Rectangle (m_PointOrigin.x, m_PointOrigin.y,
  271.                              m_PointOld.x, m_PointOld.y);
  272.          PFigure = new CRectFill
  273.             (m_PointOrigin.x, m_PointOrigin.y,
  274.             point.x, point.y,
  275.             PApp->m_CurrentColor);
  276.          break;                    
  277.          
  278.       case ID_TOOLS_RECTROUND:
  279.          {
  280.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  281.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  282.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  283.                              m_PointOld.x, m_PointOld.y,
  284.                              SizeRound, SizeRound);
  285.          PFigure = new CRectRound
  286.             (m_PointOrigin.x, m_PointOrigin.y,
  287.             point.x, point.y,
  288.             PApp->m_CurrentColor,
  289.             PApp->m_CurrentThickness);                    
  290.          break;                    
  291.          }
  292.       
  293.       case ID_TOOLS_RECTROUNDFILL:
  294.          {
  295.          int SizeRound = (abs (m_PointOld.x - m_PointOrigin.x) +
  296.                           abs (m_PointOld.y - m_PointOrigin.y)) / 6;
  297.          ClientDC.RoundRect (m_PointOrigin.x, m_PointOrigin.y,
  298.                              m_PointOld.x, m_PointOld.y,
  299.                              SizeRound, SizeRound);
  300.          PFigure = new CRectRoundFill
  301.             (m_PointOrigin.x, m_PointOrigin.y,
  302.             point.x, point.y,
  303.             PApp->m_CurrentColor);
  304.          break;                    
  305.          }                    
  306.          
  307.       case ID_TOOLS_CIRCLE:   
  308.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  309.                            m_PointOld.x, m_PointOld.y);
  310.          PFigure = new CCircle
  311.             (m_PointOrigin.x, m_PointOrigin.y,
  312.             point.x, point.y,
  313.             PApp->m_CurrentColor,
  314.             PApp->m_CurrentThickness);                    
  315.          break;                  
  316.       
  317.       case ID_TOOLS_CIRCLEFILL:
  318.          ClientDC.Ellipse (m_PointOrigin.x, m_PointOrigin.y,
  319.                            m_PointOld.x, m_PointOld.y);
  320.          PFigure = new CCircleFill
  321.             (m_PointOrigin.x, m_PointOrigin.y,
  322.             point.x, point.y,
  323.             PApp->m_CurrentColor);
  324.          break;            
  325.       }
  326.    
  327.    ClientDC.SetROP2 (R2_COPYPEN);
  328.    PFigure->Draw (&ClientDC);
  329.  
  330.    CMiniDrawDoc* PDoc = GetDocument();
  331.    PDoc->AddFigure (PFigure);
  332.    
  333.    PDoc->UpdateAllViews (this, 0, PFigure);
  334.               
  335.    CScrollView::OnLButtonUp(nFlags, point);
  336. }
  337.  
  338. void CMiniDrawView::OnInitialUpdate() 
  339. {
  340.    CScrollView::OnInitialUpdate();
  341.    
  342.    // TODO: Add your specialized code here and/or call the base class
  343.    
  344.    SIZE Size = {DRAWWIDTH, DRAWHEIGHT};
  345.    SetScrollSizes (MM_TEXT, Size); 
  346. }
  347.  
  348. void CMiniDrawView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  349. {
  350.    // TODO: Add your specialized code here and/or call the base class
  351.    
  352.    if (pHint != 0)
  353.       {
  354.       CRect InvalidRect = ((CLine *)pHint)->GetDimRect ();
  355.       CClientDC ClientDC (this);
  356.       OnPrepareDC (&ClientDC);
  357.       ClientDC.LPtoDP (&InvalidRect);
  358.       InvalidateRect (&InvalidRect);            
  359.       }
  360.    else
  361.       CScrollView::OnUpdate (pSender, lHint, pHint);      
  362. }
  363.  
  364. BOOL CMiniDrawView::OnPreparePrinting(CPrintInfo* pInfo) 
  365. {
  366.    // TODO: Add your specialized code here and/or call the base class
  367.    
  368.    return DoPreparePrinting (pInfo);
  369. }
  370.  
  371. void CMiniDrawView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
  372. {
  373.    // TODO: Add your specialized code here and/or call the base class
  374.  
  375.    m_PageHeight = pDC->GetDeviceCaps (VERTRES);
  376.    m_PageWidth = pDC->GetDeviceCaps (HORZRES);
  377.    
  378.    m_NumRows = DRAWHEIGHT / m_PageHeight  + (DRAWHEIGHT % m_PageHeight > 0);
  379.    m_NumCols = DRAWWIDTH / m_PageWidth  + (DRAWWIDTH % m_PageWidth > 0);
  380.    pInfo->SetMinPage (1);
  381.    pInfo->SetMaxPage (m_NumRows * m_NumCols);
  382.    
  383.    CScrollView::OnBeginPrinting(pDC, pInfo);
  384. }
  385.  
  386. void CMiniDrawView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
  387. {
  388.    // TODO: Add your specialized code here and/or call the base class
  389.    
  390.    CScrollView::OnPrepareDC(pDC, pInfo);
  391.  
  392.    if (pInfo == NULL)
  393.       return;                 
  394.       
  395.    int CurRow = pInfo->m_nCurPage / m_NumCols + 
  396.                (pInfo->m_nCurPage % m_NumCols > 0);
  397.    int CurCol = (pInfo->m_nCurPage - 1) % m_NumCols + 1;   
  398.       
  399.    pDC->SetViewportOrg 
  400.       (-m_PageWidth * (CurCol - 1),
  401.        -m_PageHeight * (CurRow - 1));
  402. }
  403.