home *** CD-ROM | disk | FTP | other *** search
/ Using Visual Basic 5 (Platinum Edition) / vb5.iso / ACTIVEX / SRDVID / DATA.Z / svview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-10  |  13.3 KB  |  512 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. //    svview.cpp : Implementation of the CSVViewerView class
  4. //
  5. /////////////////////////////////////////////////////////////////////////////
  6. //
  7. //  (C) Copyright Black Diamond Consulting, Inc 1996. All rights reserved.
  8. //
  9. //    You have a royalty-free right to use, modify, reproduce and 
  10. //    distribute the Sample Files (and/or any modified version) in 
  11. //    any way you find useful, provided that you agree that Black 
  12. //    Diamond Consulting has no warranty obligations or liability
  13. //    for any Sample Application Files which are modified. 
  14. //
  15. //    Revision History:
  16. //
  17. /////////////////////////////////////////////////////////////////////////////
  18.  
  19. #include "stdafx.h"
  20. #include "windowsx.h"
  21. #include "resource.h"
  22.  
  23. #ifndef _Surround_H_
  24.     #include "Surround.h"
  25. #endif
  26.  
  27. #ifndef __CSURVIEW_H__
  28.     #include "CSurView.h"
  29. #endif
  30.  
  31. #ifndef __SVVIEW_H__
  32.     #include "SVView.h"
  33. #endif
  34.  
  35. #ifndef __svDoc_H__
  36.     #include "svDoc.h"
  37. #endif
  38.  
  39. #ifndef __PSHOTSP_H__
  40.     #include "psHotsp.h"
  41. #endif
  42.  
  43. #ifndef __PPHSGEN_H__
  44.     #include "ppHSGen.h"
  45. #endif
  46.  
  47. #ifdef _DEBUG
  48.     #undef THIS_FILE
  49.     static char BASED_CODE THIS_FILE[] = __FILE__;
  50. #endif
  51.  
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CSVViewerView
  54.  
  55. IMPLEMENT_DYNCREATE(CSVViewerView, CSurroundView)
  56.  
  57. BEGIN_MESSAGE_MAP(CSVViewerView, CSurroundView)
  58.     //{{AFX_MSG_MAP(CSVViewerView)
  59.     ON_WM_LBUTTONDOWN()
  60.     ON_WM_LBUTTONUP()
  61.     ON_WM_RBUTTONDOWN()
  62.     ON_WM_RBUTTONUP()
  63.     ON_WM_MOUSEMOVE()
  64.     ON_WM_LBUTTONDBLCLK()
  65.     ON_COMMAND( ID_EDIT_HOTSPOT, OnEditHotspot )
  66.     ON_COMMAND( ID_EDIT_DELETE, OnDeleteHotspot )
  67.     ON_COMMAND( ID_MODE_RUN, OnModeEdit )
  68.     ON_COMMAND( ID_MODE_EDIT, OnModeEdit )
  69.     ON_UPDATE_COMMAND_UI( ID_EDIT_HOTSPOT, OnUpdateCurrentHotspot )
  70.     ON_UPDATE_COMMAND_UI( ID_EDIT_DELETE, OnUpdateCurrentHotspot )
  71.     ON_UPDATE_COMMAND_UI( ID_MODE_RUN, OnUpdateModeRun )
  72.     ON_UPDATE_COMMAND_UI( ID_MODE_EDIT, OnUpdateModeEdit )
  73.     ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateSave)
  74.     //}}AFX_MSG_MAP
  75. END_MESSAGE_MAP()
  76.  
  77. /////////////////////////////////////////////////////////////////////////////
  78. // CSVViewerView construction/destruction
  79.  
  80. CSVViewerView::CSVViewerView()
  81. {
  82.     // No current hotspot
  83.     m_currentHotspot = NULL;
  84.     m_pHotspotDib = NULL;
  85.     m_pAlteredDib = NULL;
  86.  
  87.     // Set default CRectTracker settings
  88.     m_rectTracker.m_nStyle = CRectTracker::resizeInside;
  89.     m_rectTracker.m_nHandleSize = ::GetSystemMetrics( SM_CYFRAME ) << 1;
  90.  
  91.     // Default to edit mode
  92.     m_bEdit = TRUE;
  93. }
  94.  
  95. CSVViewerView::~CSVViewerView()
  96. {
  97. }
  98.  
  99. /////////////////////////////////////////////////////////////////////////////
  100. // CSVViewerView drawing
  101. void CSVViewerView::OnDraw(CDC* pDC)
  102. {
  103.     // Base class will draw the image...
  104.     CSurroundView::OnDraw(pDC);
  105.  
  106.     // Draw this scene's hotspots
  107.     if( m_bEdit )
  108.         DrawHotspots( pDC );
  109.  
  110.     // Draw a focus rect over the currently selected hotspot
  111.     if( m_currentHotspot != NULL && m_bEdit )
  112.     {
  113.         m_rectTracker.m_nStyle = ( m_currentHotspot->IsLocked() )
  114.                                  ? CRectTracker::hatchInside
  115.                                  : CRectTracker::resizeInside;
  116.         if( GetHotspotRect( &m_rectTracker.m_rect ) )
  117.             m_rectTracker.Draw( pDC );
  118.     }
  119. }
  120.  
  121. // PtInHotspot() - Returns hotspot at current screen location 
  122. CHotspot* CSVViewerView::PtInHotspot( CPoint point )
  123. {
  124.     CHotspot *pHotspot;
  125.     CHotspotList* pHotspots = ((CSVViewerDoc*)GetDocument())->GetHotspotList();
  126.     CRect rect;
  127.  
  128.     int index = 0;
  129.     while( ( pHotspot = (CHotspot *)pHotspots->GetByIndex( index++ ) ) != NULL )
  130.     {
  131.         if( GetHotspotRect( &rect, pHotspot ) && rect.PtInRect( point ) )
  132.             return pHotspot;        
  133.     }
  134.     return (CHotspot *)NULL;
  135. }
  136.  
  137. // DrawHotspots() - Draw hotspots
  138. void CSVViewerView::DrawHotspots( CDC *pDC )
  139. {
  140.     CHotspot* pHotspot;
  141.     CHotspotList* pHotspots = ((CSVViewerDoc*)GetDocument())->GetHotspotList();
  142.     RECT rect;
  143.  
  144.     int index = 0;
  145.     while( ( pHotspot = (CHotspot *)pHotspots->GetByIndex( index++ ) ) != NULL )
  146.     {
  147.         if( GetHotspotRect( &rect, pHotspot ) )
  148.         {
  149.             if( pDC->RectVisible( &rect ) )
  150.                 pDC->DrawFocusRect( &rect );
  151.         }
  152.     }        
  153. }
  154.  
  155. // GetISuurround() - Returns the ISurround Interface pointer
  156. //
  157. // Note: This pure virtual member function of the CSurroundView class
  158. //         is called from the base class to obtain the ISurround interface
  159. //         pointer.
  160. //
  161. ISurround* CSVViewerView::GetISurround()
  162. {
  163.     return ((CSVViewerDoc*)this->GetDocument())->GetISurround(); 
  164. }
  165.  
  166. // GetHotspotRect() - return hotspot rect in client co-ordinates
  167. //
  168. // Accepts:
  169. //    pRect        Pointer to RECT in which client co-ordinates of the hotspot
  170. //                will be returned
  171. //    pHotspot    Pointer to hotspot, if NULL, m_currentHotspot is assumed
  172. //
  173. // Returns:
  174. //    TRUE        pRect contains hotspot co-ordinates relative to client co-ordinates
  175. //    FALSE        pHotspot was invalid or there was no current view (program bug) 
  176. //
  177. BOOL CSVViewerView::GetHotspotRect( RECT* pRect, CHotspot *pHotspot )
  178. {
  179.     CHotspotList* hotspots = ((CSVViewerDoc*)GetDocument())->GetHotspotList();
  180.     
  181.     if( pHotspot == NULL )
  182.         pHotspot = m_currentHotspot;
  183.  
  184.     if( !hotspots->IsValidEntry( pHotspot ) )
  185.         return FALSE;
  186.  
  187.     // Calculate the viewport rect based on hotspot location and size
  188.     return this->SphereToView( pHotspot->Location(), pHotspot->Size(), pRect ) == S_OK;
  189. }
  190.  
  191. // SetHotspotRect() - Set Hotspot rect based on client rect
  192. //
  193. // Accepts:
  194. //    pRect        Pointer to RECT containing co-ordinates relative to client area
  195. //    pHotspot    Pointer to hotspot, if NULL, m_currentHotspot is assumed
  196. //
  197. // Returns:
  198. //    TRUE        Sets the hotspot size and location (in image co-ordinates)
  199. //    FALSE        pHotspot was invalid or there was no current view (program bug) 
  200. //
  201. BOOL CSVViewerView::SetHotspotRect( RECT* pRect, CHotspot *pHotspot )
  202. {
  203.     CHotspotList* hotspots = ((CSVViewerDoc*)GetDocument())->GetHotspotList();
  204.     
  205.     if( pHotspot == NULL )
  206.         pHotspot = m_currentHotspot;
  207.  
  208.     if( !hotspots->IsValidEntry( pHotspot ) )
  209.         return FALSE;
  210.  
  211.     // Set hotspot size and location based on client rect
  212.     return this->ViewToSphere( pRect, pHotspot->Location(), pHotspot->Size() ) == S_OK;
  213. }
  214.  
  215. // Alter() - Alter a Dib's bits so it will stand out
  216. //
  217. // This is pretty brain dead but works with bitmaps of any
  218. // bit depth and we just want to make it look different.
  219. //
  220. void CSVViewerView::Alter( PDIB pDib )
  221. {
  222.     BYTE *pByte;
  223.     LONG n;
  224.  
  225.     if( pDib == NULL )
  226.         return;
  227.  
  228.     for( n=DibSizeImage(pDib), pByte = DibPtr(pDib); n > 0; n-- )
  229.         *(pByte++) = ~(*pByte);
  230.  
  231. }
  232.  
  233. // SetCurrentHotspot() - Make the give hotspot the currently selected one
  234. //
  235. // Note: If pHotspot is NULL, there will be no currently active hotspot
  236. //         upon return.
  237. void CSVViewerView::SetCurrentHotspot( CHotspot *pHotspot )
  238. {
  239.     CRect rect;
  240.  
  241.     // It it's the same, don't need to go any further
  242.     if( m_currentHotspot == pHotspot )
  243.         return;
  244.  
  245.     // Clean up the last hotspot if there was one
  246.     if( m_currentHotspot != NULL  )
  247.     {
  248.         GetHotspotRect( &rect, m_currentHotspot );
  249.           InvalidateRect( &rect, FALSE );
  250.  
  251.         if( !m_bEdit )
  252.         {
  253.             if( m_pHotspotDib != NULL )
  254.             {
  255.                 PutImage( m_pHotspotDib, m_currentHotspot->Location(), m_currentHotspot->Size() );
  256.                 Invalidate();
  257.                 GlobalFreePtr( m_pHotspotDib );
  258.                 m_pHotspotDib = NULL;
  259.             }
  260.  
  261.             if( m_pAlteredDib != NULL )
  262.             {
  263.                 GlobalFreePtr( m_pAlteredDib );
  264.                 m_pAlteredDib = NULL;
  265.             }
  266.         }
  267.     }
  268.  
  269.     // Make the new hotspot the current one
  270.     m_currentHotspot = pHotspot;
  271.     
  272.     // It there is a new current hotspot make sure it force it
  273.     // to get redrawn (will be redrawn in OnDraw with focus)
  274.     if( m_currentHotspot != NULL )
  275.     {
  276.         GetHotspotRect( &m_rectTracker.m_rect, m_currentHotspot );
  277.         InvalidateRect( &m_rectTracker.m_rect, FALSE );
  278.  
  279. // This next line would copy the hotspot image to the clipboard
  280. // if you so desired
  281. //        CopyImage( m_currentHotspot->Location(), m_currentHotspot->Size() );
  282.  
  283.         if( !m_bEdit )
  284.         {
  285.             HGLOBAL hDib;
  286.             hDib = GetImage( m_currentHotspot->Location(), m_currentHotspot->Size() );
  287.             if( hDib != NULL )
  288.             {
  289.                 m_pHotspotDib = (PDIB)GlobalLock( hDib );
  290.                 hDib = GetImage( m_currentHotspot->Location(), m_currentHotspot->Size() );
  291.                 if( hDib != NULL )
  292.                     m_pAlteredDib = (PDIB)GlobalLock( hDib );
  293.  
  294.                 if( m_pAlteredDib != NULL )
  295.                 {
  296.                     this->Alter( m_pAlteredDib );
  297.                     PutImage( m_pAlteredDib, m_currentHotspot->Location(), m_currentHotspot->Size() );
  298.                     Invalidate();
  299.                 }
  300.             }
  301.         }
  302.     }
  303.     else
  304.         m_rectTracker.m_rect.SetRectEmpty();
  305. }
  306.  
  307. // OnEditHotspot() - Edit the current hotspot
  308. afx_msg void CSVViewerView::OnEditHotspot() 
  309. {
  310.     if( m_currentHotspot != NULL )
  311.     {
  312.         CPSHotspot PSHotspot( this, (CSVViewerDoc *)GetDocument(), m_currentHotspot );
  313.         PSHotspot.DoModal();
  314.     }
  315. }
  316.  
  317. // OnDeleteHotspot() - Delete the current hotspot
  318. afx_msg void CSVViewerView::OnDeleteHotspot()
  319. {
  320.     CSVViewerDoc* pDoc = (CSVViewerDoc*)GetDocument();
  321.     CHotspotList* pHotspots = pDoc->GetHotspotList();
  322.     CHotspot* pHotspot;
  323.  
  324.     if( m_currentHotspot != NULL && m_bEdit )
  325.     {
  326.         CString string;
  327.         pHotspot = m_currentHotspot;
  328.  
  329.         AfxFormatString1( string, AFX_MSG_DELETEHOTSPOT, pHotspot->GetName() );
  330.         if( AfxMessageBox( string, MB_YESNO ) != IDYES )
  331.             return;
  332.  
  333.         SetCurrentHotspot( NULL );
  334.         
  335.         pHotspots->Delete( pHotspot->GetID() );
  336.         pDoc->SetModifiedFlag();
  337.     }
  338. }
  339.  
  340. // OnModeEdit() - Switch between Edit and Run mode
  341. afx_msg void CSVViewerView::OnModeEdit() 
  342. {
  343.     SetCurrentHotspot(NULL);
  344.     m_bEdit = !m_bEdit;
  345.     Invalidate();
  346. }
  347.  
  348. // OnUpdateCurrentHotspot() - Update CCmdUI object based on presence of a current hotspot
  349. afx_msg void CSVViewerView::OnUpdateCurrentHotspot( CCmdUI* pCmdUI ) 
  350. {
  351.     pCmdUI->Enable( this->IsViewPresent() &&
  352.                     m_bEdit &&
  353.                     m_currentHotspot != NULL );
  354. }
  355.  
  356. // OnUpdateModeEdit() - Update CCmdUI object based on Edit mode
  357. afx_msg void CSVViewerView::OnUpdateModeEdit( CCmdUI* pCmdUI ) 
  358. {
  359.     if( this->IsViewPresent() )
  360.     {
  361.         pCmdUI->SetCheck( (m_bEdit) ? 1 : 0 );
  362.         pCmdUI->Enable( !m_bEdit );
  363.     }
  364.     else
  365.     {
  366.         pCmdUI->SetCheck(0);
  367.         pCmdUI->Enable(FALSE);
  368.     }
  369. }
  370.  
  371. // OnUpdateModeRun() - Update CCmdUI object
  372. afx_msg void CSVViewerView::OnUpdateSave(CCmdUI* pCmdUI) 
  373. {
  374.     char drive[255], dir[255], fname[255], ext[255];
  375.     _splitpath(((CSVViewerDoc*)GetDocument())->GetPathName(), drive, dir, fname, ext);
  376.  
  377.     if(((CSVViewerDoc*)GetDocument())->IsModified())
  378.         pCmdUI->Enable(TRUE);
  379.     else
  380.         pCmdUI->Enable(FALSE);
  381. }
  382.  
  383. // OnUpdateModeRun() - Update CCmdUI object based on Edit mode
  384. afx_msg void CSVViewerView::OnUpdateModeRun( CCmdUI* pCmdUI ) 
  385. {
  386.     if( this->IsViewPresent() )
  387.     {
  388.         pCmdUI->SetCheck( (!m_bEdit) ? 1 : 0 );
  389.         pCmdUI->Enable( m_bEdit );
  390.     }
  391.     else
  392.     {
  393.         pCmdUI->SetCheck(0);
  394.         pCmdUI->Enable(FALSE);
  395.     }
  396. }
  397.  
  398. afx_msg void CSVViewerView::OnLButtonDblClk( UINT nFlags, CPoint point )
  399. {
  400.     CHotspot* pHotspot;
  401.  
  402.     // If we don't have a view, bail
  403.     if( !this->IsViewPresent() )
  404.         return;
  405.      
  406.     // See if we have a Hotspot here
  407.     if( ( pHotspot = PtInHotspot( point ) ) != NULL )
  408.     {
  409.         // Set the current hotspot...
  410.         SetCurrentHotspot( pHotspot );
  411.         
  412.         // ...and edit it
  413.         OnEditHotspot();
  414.     }
  415. }
  416.  
  417. afx_msg void CSVViewerView::OnLButtonDown( UINT nFlags, CPoint point )
  418. {
  419.     CSVViewerDoc* pDoc = (CSVViewerDoc*)GetDocument();
  420.     CHotspotList* pHotspots = pDoc->GetHotspotList();
  421.     CHotspot* pHotspot;
  422.     CRect rect;
  423.     int id;
  424.  
  425.     // If we don't have a view, bail
  426.     if( GetView() == NULL )
  427.         return;
  428.     
  429.     if( !m_bEdit )
  430.         return;
  431.  
  432.     // See if we have a Hotspot here
  433.     if( ( pHotspot = PtInHotspot( point ) ) != NULL )
  434.     {
  435.         // Set the current hotspot
  436.         SetCurrentHotspot( pHotspot );
  437.         
  438.         // Get current rect
  439.         if( !GetHotspotRect( rect ) )
  440.             return;
  441.         
  442.         m_rectTracker.m_rect = rect;
  443.  
  444.         // Let the user resize the rect (unless it's locked)
  445.         if( !pHotspot->IsLocked() && m_rectTracker.Track( this, point ) )
  446.         {
  447.             SetHotspotRect( m_rectTracker.m_rect );
  448.             
  449.             // Mark the document as dirty
  450.             pDoc->SetModifiedFlag();
  451.             
  452.             // Invalidate origional and resultant rects
  453.             this->InvalidateRect( &m_rectTracker.m_rect, FALSE );
  454.             this->InvalidateRect( &rect, FALSE );
  455.         }
  456.         return;
  457.     }
  458.  
  459.     // See if we are going to create a new hotspot...
  460.     //
  461.     // Note: If the new hotspot is too small then the user
  462.     //         probably didn't want to make one, so don't.
  463.     SetCurrentHotspot( (CHotspot *)NULL );
  464.     m_rectTracker.m_rect.SetRect( point.x, point.y, point.x, point.y );
  465.     if( m_rectTracker.TrackRubberBand( this, point ) && 
  466.         m_rectTracker.m_rect.Height() > 10 &&
  467.         m_rectTracker.m_rect.Width() > 10 )
  468.     {
  469.         pHotspot = pHotspots->Create( &id );
  470.         
  471.         SetHotspotRect( &m_rectTracker.m_rect, pHotspot );
  472.         SetCurrentHotspot( pHotspot );
  473.         
  474.         // Bring up the dialog so the user can edit it
  475.         CPSHotspot PSHotspot( this, pDoc, m_currentHotspot );
  476.         if( PSHotspot.DoModal() == IDOK )
  477.         {
  478.             // Mark the document as dirty
  479.             pDoc->SetModifiedFlag();
  480.         }
  481.         else
  482.         {
  483.             pHotspots->Delete( id );
  484.             SetCurrentHotspot( (CHotspot *)NULL );
  485.         }
  486.     }
  487. }
  488.  
  489. afx_msg void CSVViewerView::OnLButtonUp(UINT nFlags, CPoint point)
  490. {
  491. }
  492.  
  493. afx_msg void CSVViewerView::OnRButtonDown(UINT nFlags, CPoint point) 
  494. {
  495.     // Scroll the image until WM_RBUTTONUP message received
  496.     ScrollImage( point, FALSE );    
  497. }
  498.  
  499. afx_msg void CSVViewerView::OnRButtonUp( UINT nFlags, CPoint point )
  500. {
  501.     CSurroundView::OnRButtonUp( nFlags, point );
  502. }
  503.  
  504. afx_msg void CSVViewerView::OnMouseMove( UINT nFlags, CPoint point )
  505. {
  506.     if( m_bEdit )
  507.         CSurroundView::OnMouseMove( nFlags, point );
  508.     else
  509.         SetCurrentHotspot( PtInHotspot( point ) );
  510. }
  511.  
  512.