home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / tstcon / tcview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  63.6 KB  |  2,660 lines

  1. // CTestContainer98View.cpp : implementation of the CTestContainer98View class
  2. //
  3.  
  4. #include "StdAfx.H"
  5. #include "TestCon.H"
  6.  
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12.  
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CTestContainer98View
  15.  
  16. IMPLEMENT_DYNCREATE( CTestContainer98View, CView )
  17.  
  18. BEGIN_MESSAGE_MAP( CTestContainer98View, CView )
  19.    //{{AFX_MSG_MAP(CTestContainer98View)
  20.    ON_WM_DESTROY()
  21.    ON_WM_SETFOCUS()
  22.    ON_WM_SIZE()
  23.    ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
  24.    ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
  25.    ON_WM_LBUTTONDOWN()
  26.    ON_WM_LBUTTONDBLCLK()
  27.    ON_WM_SETCURSOR()
  28.    ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
  29.    ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
  30.    ON_WM_RBUTTONDOWN()
  31.    ON_COMMAND(ID_OPTIONS_DESIGNMODE, OnOptionsDesignMode)
  32.    ON_UPDATE_COMMAND_UI(ID_OPTIONS_DESIGNMODE, OnUpdateOptionsDesignMode)
  33.    ON_WM_CREATE()
  34.    ON_WM_LBUTTONUP()
  35.    ON_WM_MOUSEMOVE()
  36.    ON_WM_RBUTTONDBLCLK()
  37.    ON_WM_RBUTTONUP()
  38.    ON_WM_CAPTURECHANGED()
  39.    ON_WM_KILLFOCUS()
  40.    ON_WM_KEYDOWN()
  41.    ON_WM_KEYUP()
  42.    ON_WM_CHAR()
  43.    ON_WM_CANCELMODE()
  44.    ON_COMMAND(ID_CONTROL_SAVETOSTREAM, OnControlSaveToStream)
  45.    ON_COMMAND(ID_EDIT_INSERTFROMSTREAM, OnEditInsertFromStream)
  46.     ON_COMMAND(ID_CONTROL_SAVETOPROPERTYBAG, OnControlSaveToPropertyBag)
  47.     ON_UPDATE_COMMAND_UI(ID_CONTROL_SAVETOPROPERTYBAG, OnUpdateControlSaveToPropertyBag)
  48.     ON_UPDATE_COMMAND_UI(ID_CONTROL_SAVETOSTREAM, OnUpdateControlSaveToStream)
  49.     ON_COMMAND(ID_CONTROL_INVOKEMETHODS, OnControlInvokeMethods)
  50.     ON_UPDATE_COMMAND_UI(ID_CONTROL_INVOKEMETHODS, OnUpdateControlInvokeMethods)
  51.     ON_COMMAND(ID_CONTROL_LOGGING, OnControlLogging)
  52.     ON_UPDATE_COMMAND_UI(ID_CONTROL_LOGGING, OnUpdateControlLogging)
  53.     ON_COMMAND(ID_CONTROL_ACTIVATE, OnControlActivate)
  54.     ON_COMMAND(ID_CONTROL_DEACTIVATE, OnControlDeactivate)
  55.     ON_COMMAND(ID_CONTROL_UIACTIVATE, OnControlUIActivate)
  56.     ON_COMMAND(ID_CONTROL_UIDEACTIVATE, OnControlUIDeactivate)
  57.     ON_UPDATE_COMMAND_UI(ID_CONTROL_UIDEACTIVATE, OnUpdateControlUIDeactivate)
  58.     ON_UPDATE_COMMAND_UI(ID_CONTROL_UIACTIVATE, OnUpdateControlUIActivate)
  59.     ON_UPDATE_COMMAND_UI(ID_CONTROL_ACTIVATE, OnUpdateControlActivate)
  60.     ON_UPDATE_COMMAND_UI(ID_CONTROL_DEACTIVATE, OnUpdateControlDeactivate)
  61.     ON_COMMAND(ID_EDIT_BRINGTOFRONT, OnEditBringToFront)
  62.     ON_UPDATE_COMMAND_UI(ID_EDIT_BRINGTOFRONT, OnUpdateEditBringToFront)
  63.     ON_COMMAND(ID_EDIT_SENDTOBACK, OnEditSendToBack)
  64.     ON_UPDATE_COMMAND_UI(ID_EDIT_SENDTOBACK, OnUpdateEditSendToBack)
  65.     ON_WM_CONTEXTMENU()
  66.     ON_COMMAND(ID_EDIT_PROPERTIES, OnEditProperties)
  67.     ON_UPDATE_COMMAND_UI(ID_EDIT_PROPERTIES, OnUpdateEditProperties)
  68.     ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectAll)
  69.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  70.     ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  71.     ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  72.     ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
  73.     ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  74.     ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
  75.     ON_COMMAND(ID_TOOLS_OLEVIEW, OnToolsOLEView)
  76.     ON_COMMAND(ID_TOOLS_REGEDIT, OnToolsRegEdit)
  77.     ON_COMMAND(ID_CONTROL_SAVETOSTORAGE, OnControlSaveToStorage)
  78.     ON_UPDATE_COMMAND_UI(ID_CONTROL_SAVETOSTORAGE, OnUpdateControlSaveToStorage)
  79.     ON_COMMAND(ID_EDIT_INSERTCONTROLFROMSTORAGE, OnEditInsertControlFromStorage)
  80.     ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTALL, OnUpdateEditSelectAll)
  81.     ON_COMMAND(ID_CONTROL_DRAWMETAFILE, OnControlDrawMetaFile)
  82.     ON_UPDATE_COMMAND_UI(ID_CONTROL_DRAWMETAFILE, OnUpdateControlDrawMetaFile)
  83.     //}}AFX_MSG_MAP
  84. END_MESSAGE_MAP()
  85.  
  86. CLIPFORMAT CTestContainer98View::s_cfObjectDescriptor = NULL;
  87.  
  88. /////////////////////////////////////////////////////////////////////////////
  89. // CTestContainer98View construction/destruction
  90.  
  91. CTestContainer98View::CTestContainer98View() :
  92.    m_pSelection( NULL ),
  93. //   m_tDoingDrag( FALSE ),
  94.    m_pItemWithCapture( NULL ),
  95.    m_pItemWithFocus( NULL ),
  96.    m_pItemToDeactivateOnLeave( NULL ),
  97.    m_pInactiveDropTarget( NULL ),
  98.    m_pWindowlessDropTarget( NULL ),
  99.    m_dwLastDropKeyState( 0 )
  100. {
  101.    if( s_cfObjectDescriptor == NULL )
  102.    {
  103.       s_cfObjectDescriptor = CLIPFORMAT( ::RegisterClipboardFormat( _T(
  104.          "Object Descriptor" ) ) );
  105.    }
  106. }
  107.  
  108. CTestContainer98View::~CTestContainer98View()
  109. {
  110. }
  111.  
  112. BOOL CTestContainer98View::PreCreateWindow( CREATESTRUCT& cs )
  113. {
  114.    cs.style |= WS_CLIPCHILDREN;
  115.  
  116.    return( CView::PreCreateWindow( cs ) );
  117. }
  118.  
  119. void CTestContainer98View::ClearSelection()
  120. {
  121.    m_pSelection = NULL;
  122.    m_lpSelectedItems.RemoveAll();
  123. }
  124.  
  125. /////////////////////////////////////////////////////////////////////////////
  126. // CTestContainer98View drawing
  127.  
  128. void CTestContainer98View::OnDraw( CDC* pDC )
  129. {
  130.    POSITION posItem;
  131.    CTestContainer98Doc* pDoc;
  132.    CTestContainer98Item* pItem;
  133.  
  134.    pDoc = GetDocument();
  135.    ASSERT_VALID( pDoc );
  136.  
  137.    if( pDoc->UseTwoPassDrawing() )
  138.    {
  139.       // Draw the opaque parts of the controls from front to back.
  140.       TCTrace( TRACELEVEL_VERBOSE, "Starting drawing pass 1.\n" );
  141.       posItem = pDoc->GetStartPosition();
  142.       while( posItem != NULL )
  143.       {
  144.          pItem = (CTestContainer98Item*)pDoc->GetNextItem( posItem );
  145.  
  146.          // Push the state of the DC onto the stack.  This is to save the
  147.          // current clip region for when we do the second pass.
  148.          pDC->SaveDC();
  149.  
  150.          // The item will exclude any opaque areas from the clip region of the
  151.          // DC.
  152.          pItem->DrawFrontToBack( pDC, pItem->m_rect );
  153.  
  154.          if( pDoc->UseSlowDrawing() )
  155.          {
  156.             Sleep( 1000 );
  157.          }
  158.       }
  159.  
  160.       // Draw the rest of each control from back to front, clipping out opaque
  161.       // regions of any controls in front.
  162.       TCTrace( TRACELEVEL_VERBOSE, "Starting drawing pass 2.\n" );
  163.       posItem = pDoc->GetTailPosition();
  164.       while( posItem != NULL )
  165.       {
  166.          pItem = (CTestContainer98Item*)pDoc->GetPrevItem( posItem );
  167.  
  168.          // Draw the tracker for the item.
  169.          CRectTracker tracker;
  170.          SetupTracker( pItem, &tracker );
  171.          tracker.Draw( pDC );
  172.  
  173.          // Pop the state of the DC off the stack.  This makes sure the
  174.          // clipping region excludes only the opaque regions of all the
  175.          // controls in front of this one.
  176.          pDC->RestoreDC( -1 );
  177.  
  178.          pItem->DrawBackToFront( pDC, pItem->m_rect );
  179.  
  180.          if( pDoc->UseSlowDrawing() )
  181.          {
  182.             Sleep( 1000 );
  183.          }
  184.       }
  185.    }
  186.    else
  187.    {
  188.       // Draw the OLE items from the list.
  189.       posItem = pDoc->GetTailPosition();
  190.       while( posItem != NULL )
  191.       {
  192.          pItem = (CTestContainer98Item*)pDoc->GetPrevItem( posItem );
  193.  
  194.          // Draw the tracker for the item.
  195.          CRectTracker tracker;
  196.          SetupTracker( pItem, &tracker );
  197.          tracker.Draw( pDC );
  198.  
  199.          // Draw the item.
  200.          pItem->Draw( pDC, pItem->m_rect );
  201.  
  202.          if( pDoc->UseSlowDrawing() )
  203.          {
  204.             Sleep( 1000 );
  205.          }
  206.       }
  207.    }
  208. }
  209.  
  210. void CTestContainer98View::OnInitialUpdate()
  211. {
  212.    CView::OnInitialUpdate();
  213.  
  214.    m_pSelection = NULL;
  215.    m_lpSelectedItems.RemoveAll();
  216. }
  217.  
  218. /////////////////////////////////////////////////////////////////////////////
  219. // CTestContainer98View printing
  220.  
  221. void CTestContainer98View::OnDestroy()
  222. {
  223.    // Deactivate the item on destruction; this is important
  224.    // when a splitter view is being used.
  225.    CView::OnDestroy();
  226.  
  227.    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem( this );
  228.    if( (pActiveItem != NULL) && (pActiveItem->GetActiveView() == this) )
  229.    {
  230.       pActiveItem->Deactivate();
  231.       ASSERT( GetDocument()->GetInPlaceActiveItem( this ) == NULL );
  232.    }
  233. }
  234.  
  235.  
  236. /////////////////////////////////////////////////////////////////////////////
  237. // OLE Client support and commands
  238.  
  239. BOOL CTestContainer98View::IsSelected( const CObject* pDocItem ) const
  240. {
  241.    // The implementation below is adequate if your selection consists of
  242.    //  only CTestContainer98Item objects.  To handle different selection
  243.    //  mechanisms, the implementation here should be replaced.
  244.  
  245.    // TODO: implement this function that tests for a selected OLE client item
  246.  
  247.    return( pDocItem == m_pSelection );
  248. }
  249.  
  250. void CTestContainer98View::OnInsertObject()
  251. {
  252.    CTestContainer98Item* pItem;
  253.    CTestContainer98Doc* pDoc;
  254.    CInsertControlDlg dlg;
  255.    int nResult;
  256.  
  257.    nResult = dlg.DoModal();
  258.    if( nResult != IDOK )
  259.    {
  260.       return;
  261.    }
  262.  
  263.    BeginWaitCursor();
  264.  
  265.    pItem = NULL;
  266.    try
  267.    {
  268.       // Create new item connected to this document.
  269.       pDoc = GetDocument();
  270.  
  271.       pItem = pDoc->AddControl( dlg.m_clsid, NULL );
  272.       ASSERT_VALID( pItem );
  273.  
  274.       // As an arbitrary user interface design, this sets the selection to the
  275.       // last item inserted.
  276.  
  277.       SetSelection( pItem );
  278.  
  279.       pItem->InvalidateItem();
  280.    }
  281.    catch( COleException* pException )
  282.    {
  283.       CString strErrorMessage;
  284.       _com_error error( pException->m_sc );
  285.  
  286.       pException->Delete();
  287.  
  288.       if( pItem != NULL )
  289.       {
  290.          ASSERT_VALID( pItem );
  291.          pItem->Delete();
  292.       }
  293.  
  294.       AfxFormatString1( strErrorMessage, IDS_CREATEFAILED,
  295.          error.ErrorMessage() );
  296.  
  297.       AfxMessageBox( strErrorMessage );
  298.    }
  299.    catch( CException* pException )
  300.    {
  301.       pException->Delete();
  302.  
  303.       if( pItem != NULL )
  304.       {
  305.          ASSERT_VALID( pItem );
  306.          pItem->Delete();
  307.       }
  308.  
  309.       AfxMessageBox( IDP_FAILED_TO_CREATE );
  310.    }
  311.  
  312.    EndWaitCursor();
  313. }
  314.  
  315. // The following command handler provides the standard keyboard
  316. //  user interface to cancel an in-place editing session.  Here,
  317. //  the container (not the server) causes the deactivation.
  318. void CTestContainer98View::OnCancelEditCntr()
  319. {
  320.    // Close any in-place active item on this view.
  321.    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem( this );
  322.    if( pActiveItem != NULL )
  323.    {
  324.       pActiveItem->Close();
  325.    }
  326.    ASSERT( GetDocument()->GetInPlaceActiveItem( this ) == NULL );
  327. }
  328.  
  329. // Special handling of OnSetFocus and OnSize are required for a container
  330. //  when an object is being edited in-place.
  331. void CTestContainer98View::OnSetFocus( CWnd* pOldWnd )
  332. {
  333.    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem( this );
  334.    if( (pActiveItem != NULL) && (pActiveItem->GetItemState() ==
  335.       COleClientItem::activeUIState) )
  336.    {
  337.       // need to set focus to this item if it is in the same view
  338.       CWnd* pWnd = pActiveItem->GetInPlaceWindow();
  339.       if( pWnd != NULL )
  340.       {
  341.          pWnd->SetFocus();   // don't call the base class
  342.          return;
  343.       }
  344.    }
  345.  
  346.    CView::OnSetFocus( pOldWnd );
  347. }
  348.  
  349. void CTestContainer98View::OnSize( UINT nType, int cx, int cy )
  350. {
  351.    COleClientItem* pActiveItem;
  352.  
  353.    CView::OnSize( nType, cx, cy );
  354.  
  355.    pActiveItem = GetDocument()->GetInPlaceActiveItem( this );
  356.    if( pActiveItem != NULL )
  357.    {
  358.       pActiveItem->SetItemRects();
  359.    }
  360. }
  361.  
  362. /////////////////////////////////////////////////////////////////////////////
  363. // CTestContainer98View diagnostics
  364.  
  365. #ifdef _DEBUG
  366. void CTestContainer98View::AssertValid() const
  367. {
  368.    CView::AssertValid();
  369. }
  370.  
  371. void CTestContainer98View::Dump( CDumpContext& dc ) const
  372. {
  373.    CView::Dump( dc );
  374. }
  375.  
  376. // non-debug version is inline.
  377. CTestContainer98Doc* CTestContainer98View::GetDocument()
  378. {
  379.    ASSERT( m_pDocument->IsKindOf( RUNTIME_CLASS( CTestContainer98Doc ) ) );
  380.    return( (CTestContainer98Doc*)m_pDocument );
  381. }
  382. #endif //_DEBUG
  383.  
  384. /////////////////////////////////////////////////////////////////////////////
  385. // CTestContainer98View message handlers
  386.  
  387. // Method: HitTestItems
  388. // Description: Determines the topmost item that contains the given point.
  389. // Parameters:
  390. //    point - (IN) The point to hit test.
  391. //    pdwHitType - (OUT) Which part of the item was hit.  Possible values are:
  392. //       HITTYPE_NONE - No item was hit.
  393. //       HITTYPE_OBJECT - The item itself was hit.
  394. //       HITTYPE_BORDER - The grab border of the item was hit.
  395. // Return Value: Topmost item containing the point, or NULL if the point is not
  396. //    inside any of the items.
  397. CTestContainer98Item* CTestContainer98View::HitTestItems( CPoint point,
  398.    DWORD* pdwHitType )
  399. {
  400.    CTestContainer98Doc* pDoc;
  401.    CTestContainer98Item* pItem;
  402.    POSITION posItem;
  403.    CRect rectBorder;
  404.    DWORD dwHitResult;
  405.  
  406.    pDoc = GetDocument();
  407.  
  408.    *pdwHitType = HITTYPE_NONE;  // Assume that we don't hit anything.
  409.  
  410.    // Traverse the list of controls from front to back.
  411.    posItem = pDoc->GetStartPosition();
  412.    while( posItem != NULL )
  413.    {
  414.       pItem = (CTestContainer98Item*)pDoc->GetNextItem( posItem );
  415.       dwHitResult = pItem->HitTest( point );
  416.       if( dwHitResult == HITRESULT_HIT )
  417.       {
  418.          // We hit the control itself.
  419.          *pdwHitType = HITTYPE_OBJECT;
  420.          return( pItem );
  421.       }
  422.       else
  423.       {
  424.          // We missed the control, so check the grab border that we added to
  425.          // it.
  426.          rectBorder = pItem->m_rect;
  427.          rectBorder.InflateRect( MARGIN_PIXELS, MARGIN_PIXELS );
  428.          if( rectBorder.PtInRect( point ) && !pItem->m_rect.PtInRect( point ) )
  429.          {
  430.             // The point is outside the item's bounding rectangle, but inside
  431.             // the border rect.
  432.             *pdwHitType = HITTYPE_BORDER;
  433.             return( pItem );
  434.          }
  435.       }
  436.    }
  437.  
  438.    return( NULL );
  439. }
  440.  
  441. void CTestContainer98View::SetMultiSelect( CTestContainer98Item* pItem,
  442.    BOOL tSelect )
  443. {
  444.    POSITION posItem;
  445.  
  446.    ASSERT( pItem != NULL );
  447.  
  448.    posItem = m_lpSelectedItems.Find( pItem );
  449.    if( tSelect )
  450.    {
  451.       if( posItem != NULL )
  452.       {
  453.          // Already selected
  454.          return;
  455.       }
  456.       else
  457.       {
  458.          m_lpSelectedItems.AddHead( pItem );
  459.          if( m_lpSelectedItems.GetCount() == 1 )
  460.          {
  461.             ASSERT( m_pSelection == NULL );
  462.             m_pSelection = pItem;
  463.             m_pSelection->OnSelect();
  464.          }
  465.          else
  466.          {
  467.             if( m_pSelection != NULL )
  468.             {
  469.                OnUpdate( NULL, HINT_UPDATE_ITEM, m_pSelection );
  470.                m_pSelection->OnDeselect();
  471.                m_pSelection = NULL;
  472.             }
  473.          }
  474.          OnUpdate( NULL, HINT_UPDATE_ITEM, pItem );
  475.       }
  476.    }
  477.    else
  478.    {
  479.       if( posItem == NULL )
  480.       {
  481.          // Already not selected
  482.          return;
  483.       }
  484.       else
  485.       {
  486.          if( m_pSelection == pItem )
  487.          {
  488.             ASSERT( m_lpSelectedItems.GetCount() == 1 );
  489.             m_pSelection->OnDeselect();
  490.             m_pSelection = NULL;
  491.          }
  492.          m_lpSelectedItems.RemoveAt( posItem );
  493.          if( m_lpSelectedItems.GetCount() == 1 )
  494.          {
  495.             ASSERT( m_pSelection == NULL );
  496.             m_pSelection = m_lpSelectedItems.GetHead();
  497.             m_pSelection->OnSelect();
  498.             OnUpdate( NULL, HINT_UPDATE_ITEM, m_pSelection );
  499.          }
  500.          OnUpdate( NULL, HINT_UPDATE_ITEM, pItem );
  501.       }
  502.    }
  503. }
  504.  
  505. void CTestContainer98View::ToggleMultiSelect( CTestContainer98Item* pItem )
  506. {
  507.    POSITION posItem;
  508.  
  509.    ASSERT( pItem != NULL );
  510.  
  511.    posItem = m_lpSelectedItems.Find( pItem );
  512.    if( posItem == NULL )
  513.    {
  514.       m_lpSelectedItems.AddHead( pItem );
  515.       if( m_lpSelectedItems.GetCount() == 1 )
  516.       {
  517.          ASSERT( m_pSelection == NULL );
  518.          m_pSelection = pItem;
  519.          m_pSelection->OnSelect();
  520.       }
  521.       else
  522.       {
  523.          if( m_pSelection != NULL )
  524.          {
  525.             m_pSelection->OnDeselect();
  526.             m_pSelection = NULL;
  527.          }
  528.       }
  529.    }
  530.    else
  531.    {
  532.       if( m_pSelection == pItem )
  533.       {
  534.          ASSERT( m_lpSelectedItems.GetCount() == 1 );
  535.          m_pSelection->OnDeselect();
  536.          m_pSelection = NULL;
  537.       }
  538.       m_lpSelectedItems.RemoveAt( posItem );
  539.       if( m_lpSelectedItems.GetCount() == 1 )
  540.       {
  541.          ASSERT( m_pSelection == NULL );
  542.          m_pSelection = m_lpSelectedItems.GetHead();
  543.          m_pSelection->OnSelect();
  544.       }
  545.    }
  546.    OnUpdate( NULL, HINT_UPDATE_ITEM, pItem );
  547. }
  548.  
  549. void CTestContainer98View::SetSelection( CTestContainer98Item* pItem )
  550. {
  551.    CTestContainer98Item* pSelectedItem;
  552.  
  553.    if( (pItem != NULL ) && (m_pSelection == pItem) )
  554.    {
  555.       // No change in selection
  556.       return;
  557.    }
  558.  
  559.    if( m_pSelection != NULL )
  560.    {
  561.       m_pSelection->OnDeselect();
  562.       m_pSelection = NULL;
  563.    }
  564.  
  565.    while( !m_lpSelectedItems.IsEmpty() )
  566.    {
  567.       pSelectedItem = m_lpSelectedItems.RemoveHead();
  568.       if( pSelectedItem != pItem )
  569.       {
  570.          OnUpdate( NULL, HINT_UPDATE_ITEM, pSelectedItem );
  571.       }
  572.    }
  573.  
  574.    if( pItem != NULL )
  575.    {
  576.       m_lpSelectedItems.AddHead( pItem );
  577.       m_pSelection = pItem;
  578.       m_pSelection->OnSelect();
  579.       OnUpdate( NULL, HINT_UPDATE_ITEM, pItem );
  580.    }
  581. }
  582.  
  583. BOOL CTestContainer98View::HandleWindowlessKeyboardMessage()
  584. {
  585.    if( m_pItemWithFocus != NULL )
  586.    {
  587.       if( m_pItemWithFocus->IsWindowless() )
  588.       {
  589.          m_pItemWithFocus->OnWindowMessage( GetCurrentMessage() );
  590.          return( TRUE );
  591.       }
  592.    }
  593.  
  594.    return( FALSE );
  595. }
  596.  
  597. BOOL CTestContainer98View::HandlePointerInactiveMove( CPoint point,
  598.    DWORD dwKeyState )
  599. {
  600.    CTestContainer98Item* pItemHit;
  601.    CRect rect;
  602.    BOOL tHandled;
  603.    DWORD dwPolicy;
  604.    MSG msg;
  605.    DWORD dwHitType;
  606.  
  607.    if( !GetDocument()->UseIPointerInactive() )
  608.    {
  609.       return( FALSE );
  610.    }
  611.  
  612.    tHandled = FALSE;
  613.  
  614.    pItemHit = HitTestItems( point, &dwHitType );
  615.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->SupportsIPointerInactive() )
  616.    {
  617.       pItemHit = NULL;
  618.    }
  619.  
  620.    if( m_pItemToDeactivateOnLeave != NULL )
  621.    {
  622.       // We have an active object that wants to be deactivated as soon as the
  623.       // mouse leaves its extents.
  624.       if( m_pItemToDeactivateOnLeave != pItemHit )
  625.       {
  626.          TCTrace( TRACELEVEL_NORMAL,
  627.             "Deactivating item because of POINTERINACTIVE_DEACTIVATEONLEAVE.\n" );
  628.          m_pItemToDeactivateOnLeave->Deactivate();
  629.          m_pItemToDeactivateOnLeave = NULL;
  630.       }
  631.    }
  632.  
  633.    if( pItemHit != NULL )
  634.    {
  635.       if( !pItemHit->IsInPlaceActive() )
  636.       {
  637.          // The mouse was over an inactive control that wants to receive mouse
  638.          // pointer messages, so send the message to that control first.
  639.          dwPolicy = pItemHit->OnPointerInactiveMove( point, dwKeyState );
  640.          if( dwPolicy&POINTERINACTIVE_ACTIVATEONENTRY )
  641.          {
  642.             msg = *GetCurrentMessage();
  643.             TCTrace( TRACELEVEL_NORMAL,
  644.                "Activating item because of POINTERINACTIVE_ACTIVATEONENTRY.\n" );
  645.             pItemHit->Activate( OLEIVERB_SHOW, this, &msg );
  646.             if( dwPolicy&POINTERINACTIVE_DEACTIVATEONLEAVE )
  647.             {
  648.                // The control wants to be deactivated as soon as the mouse
  649.                // leaves its extents.
  650.                m_pItemToDeactivateOnLeave = pItemHit;
  651.             }
  652.          }
  653.          tHandled = TRUE;
  654.       }
  655.    }
  656.    else
  657.    {
  658.       tHandled = FALSE;
  659.    }
  660.  
  661.    return( tHandled );
  662. }
  663.  
  664. BOOL CTestContainer98View::HandlePointerInactiveSetCursor(
  665.    DWORD dwMouseMessage )
  666. {
  667.    CTestContainer98Item* pItemHit;
  668.    CRect rect;
  669.    BOOL tHandled;
  670.    DWORD dwPolicy;
  671.    MSG msg;
  672.    CPoint point;
  673.    DWORD dwHitType;
  674.  
  675.    if( !GetDocument()->UseIPointerInactive() )
  676.    {
  677.       return( FALSE );
  678.    }
  679.  
  680.    point = m_ptLastMousePosition;
  681.    pItemHit = HitTestItems( point, &dwHitType );
  682.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->SupportsIPointerInactive() )
  683.    {
  684.       pItemHit = NULL;
  685.    }
  686.  
  687.    if( m_pItemToDeactivateOnLeave != NULL )
  688.    {
  689.       // If the pointer is still over the same control, then we really haven't
  690.       // left it.
  691.       if( m_pItemToDeactivateOnLeave != pItemHit )
  692.       {
  693.          TCTrace( TRACELEVEL_NORMAL,
  694.             "Deactivating item because of POINTERINACTIVE_DEACTIVATEONLEAVE.\n" );
  695.          m_pItemToDeactivateOnLeave->Deactivate();
  696.          m_pItemToDeactivateOnLeave = NULL;
  697.       }
  698.    }
  699.  
  700.    tHandled = FALSE;
  701.    if( pItemHit != NULL )
  702.    {
  703.       if( !pItemHit->IsInPlaceActive() )
  704.       {
  705.          // The mouse was over an inactive control that wants to receive mouse
  706.          // pointer messages, so send the message to that control first.
  707.          dwPolicy = pItemHit->OnPointerInactiveSetCursor( point,
  708.             dwMouseMessage, &tHandled );
  709.          if( dwPolicy&POINTERINACTIVE_ACTIVATEONENTRY )
  710.          {
  711.             msg = *GetCurrentMessage();
  712.             TCTrace( TRACELEVEL_NORMAL,
  713.                "Activating item because of POINTERINACTIVE_ACTIVATEONENTRY.\n" );
  714.             pItemHit->Activate( OLEIVERB_SHOW, this, &msg );
  715.             if( dwPolicy&POINTERINACTIVE_DEACTIVATEONLEAVE )
  716.             {
  717.                m_pItemToDeactivateOnLeave = pItemHit;
  718.             }
  719.             tHandled = TRUE;
  720.          }
  721.       }
  722.    }
  723.  
  724.    return( tHandled );
  725. }
  726.  
  727. BOOL CTestContainer98View::HandlePointerInactiveDragOver( CPoint point )
  728. {
  729.    CTestContainer98Item* pItemHit;
  730.    DWORD dwHitType;
  731.    DWORD dwPolicy;
  732.    BOOL tHandled;
  733.  
  734.    if( !GetDocument()->UseIPointerInactive() )
  735.    {
  736.       return( FALSE );
  737.    }
  738.  
  739.    pItemHit = HitTestItems( point, &dwHitType );
  740.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->SupportsIPointerInactive() )
  741.    {
  742.       pItemHit = NULL;
  743.    }
  744.  
  745.    tHandled = FALSE;
  746.    if( pItemHit != NULL )
  747.    {
  748.       if( !pItemHit->IsInPlaceActive() )
  749.       {
  750.          dwPolicy = pItemHit->GetActivationPolicy();
  751.          if( dwPolicy&POINTERINACTIVE_ACTIVATEONDRAG )
  752.          {
  753.             TCTrace( TRACELEVEL_NORMAL,
  754.                "Activating item because of POINTERINACTIVE_ACTIVATEONDRAG.\n" );
  755.             pItemHit->Activate( OLEIVERB_SHOW, this );
  756.          }
  757.       }
  758.    }
  759.  
  760.    return( tHandled );
  761. }
  762.  
  763. BOOL CTestContainer98View::HandleWindowlessDragEnter(
  764.    COleDataObject* pDataObject, DWORD dwKeyState, CPoint point,
  765.    DWORD* pdwDropEffect )
  766. {
  767.    CTestContainer98Item* pItemHit;
  768.    DWORD dwHitType;
  769.    BOOL tHandled;
  770.  
  771.    ASSERT( m_pWindowlessDropTarget == NULL );
  772.  
  773.    pItemHit = HitTestItems( point, &dwHitType );
  774.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->IsWindowless() )
  775.    {
  776.       pItemHit = NULL;
  777.    }
  778.  
  779.    tHandled = FALSE;
  780.    if( pItemHit != NULL )
  781.    {
  782.       tHandled = pItemHit->OnWindowlessDragEnter( pDataObject, dwKeyState,
  783.          point, pdwDropEffect );
  784.       if( tHandled )
  785.       {
  786.          // Remember which item we're over.
  787.          m_pWindowlessDropTarget = pItemHit;
  788.       }
  789.    }
  790.  
  791.    return( tHandled );
  792. }
  793.  
  794. BOOL CTestContainer98View::HandleWindowlessDragOver(
  795.    COleDataObject* pDataObject, DWORD dwKeyState, CPoint point,
  796.    DWORD* pdwDropEffect )
  797. {
  798.    CTestContainer98Item* pItemHit;
  799.    DWORD dwHitType;
  800.    BOOL tHandled;
  801.  
  802.    pItemHit = HitTestItems( point, &dwHitType );
  803.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->IsWindowless() )
  804.    {
  805.       pItemHit = NULL;
  806.    }
  807.  
  808.    tHandled = FALSE;
  809.    if( m_pWindowlessDropTarget != NULL )
  810.    {
  811.       // The cursor was previously over a windowless control.
  812.       if( m_pWindowlessDropTarget != pItemHit )
  813.       {
  814.          // The cursor left that windowless control.
  815.          m_pWindowlessDropTarget->OnWindowlessDragLeave();
  816.          m_pWindowlessDropTarget = NULL;
  817.       }
  818.    }
  819.  
  820.    if( pItemHit != NULL )
  821.    {
  822.       // The cursor is now over a windowless control.
  823.       if( pItemHit != m_pWindowlessDropTarget )
  824.       {
  825.          // The cursor entered a new windowless control.
  826.          ASSERT( m_pWindowlessDropTarget == NULL );
  827.          tHandled = pItemHit->OnWindowlessDragEnter( pDataObject, dwKeyState,
  828.             point, pdwDropEffect );
  829.          if( tHandled )
  830.          {
  831.             m_pWindowlessDropTarget = pItemHit;
  832.          }
  833.       }
  834.       else
  835.       {
  836.          // The cursor is still over the same windowless control.
  837.          pItemHit->OnWindowlessDragOver( dwKeyState, point, pdwDropEffect );
  838.          tHandled = TRUE;
  839.       }
  840.    }
  841.  
  842.    return( tHandled );
  843. }
  844.  
  845. void CTestContainer98View::HandleWindowlessDragLeave()
  846. {
  847.    if( m_pWindowlessDropTarget != NULL )
  848.    {
  849.       m_pWindowlessDropTarget->OnWindowlessDragLeave();
  850.       m_pWindowlessDropTarget = NULL;
  851.    }
  852. }
  853.  
  854. BOOL CTestContainer98View::HandleWindowlessDrop( COleDataObject* pDataObject,
  855.    DWORD dwKeyState, CPoint point, DWORD* pdwEffect )
  856. {
  857.    if( m_pWindowlessDropTarget != NULL )
  858.    {
  859.       m_pWindowlessDropTarget->OnWindowlessDrop( pDataObject, dwKeyState,
  860.          point, pdwEffect );
  861.       m_pWindowlessDropTarget = NULL;
  862.       return( TRUE );
  863.    }
  864.    else
  865.    {
  866.       return( FALSE );
  867.    }
  868. }
  869.  
  870. BOOL CTestContainer98View::HandleWindowlessMouseMessage( CPoint point )
  871. {
  872.    CTestContainer98Item* pItemHit;
  873.    DWORD dwHitType;
  874.    BOOL tHandled;
  875.    CRect rect;
  876.  
  877.    // First, see if a windowless control has mouse capture.
  878.    if( m_pItemWithCapture != NULL )
  879.    {
  880.       m_pItemWithCapture->OnWindowMessage( GetCurrentMessage() );
  881.       return( TRUE );
  882.    }
  883.  
  884.    // Now, see if we hit a windowless control.
  885.    pItemHit = HitTestItems( point, &dwHitType );
  886.    if( (dwHitType != HITTYPE_OBJECT) || !pItemHit->IsWindowless() )
  887.    {
  888.       pItemHit = NULL;
  889.    }
  890.  
  891.    if( pItemHit != NULL )
  892.    {
  893.       // The mouse was over a windowless control, so send the message to that
  894.       // control first.
  895.       tHandled = pItemHit->OnWindowMessage( GetCurrentMessage() );
  896.       if( !tHandled )
  897.       {
  898.          // The windowless control didn't do anything, but we don't want the
  899.          // container to do anything either.
  900.          {
  901.             Default();
  902.          }
  903.       }
  904.       return( TRUE );
  905.    }
  906.  
  907.    return( FALSE );
  908. }
  909.  
  910. void CTestContainer98View::OnLButtonDown( UINT nFlags, CPoint point )
  911. {
  912.    BOOL tHandled;
  913.    CTestContainer98Item* pItemHit;
  914.    CTestContainer98Item* pItem;
  915.    POSITION posItem;
  916.    DWORD dwHitType;
  917.    int eHitType;
  918.    MSG msg;
  919.  
  920.    tHandled = HandleWindowlessMouseMessage( point );
  921.    if( tHandled )
  922.    {
  923.       return;
  924.    }
  925.  
  926.    pItemHit = HitTestItems( point, &dwHitType );
  927.    if( nFlags&MK_CONTROL )
  928.    {
  929.       if( pItemHit != NULL )
  930.       {
  931.          ToggleMultiSelect( pItemHit );
  932.       }
  933.    }
  934.    else
  935.    {
  936.       if( m_lpSelectedItems.Find( pItemHit ) == NULL )
  937.       {
  938.          SetSelection( pItemHit );
  939.       }
  940.    }
  941.  
  942.    if( (pItemHit != NULL) && (dwHitType != HITTYPE_BORDER) )
  943.    {
  944.       if( !pItemHit->IsInPlaceActive() )
  945.       {
  946.          msg = *GetCurrentMessage();
  947.          pItemHit->Activate( OLEIVERB_SHOW, this, &msg );
  948.       }
  949.    }
  950.  
  951.    if( !m_lpSelectedItems.IsEmpty() )
  952.    {
  953.       if( dwHitType == HITTYPE_BORDER )
  954.       {
  955.          CRectTracker tracker;
  956.          CPoint ptStart;
  957.          CSize sizeDisplacement;
  958.          CRect rectItem;
  959.  
  960.          SetupSelectionTracker( &tracker );
  961.          ptStart = tracker.m_rect.TopLeft();
  962.          eHitType = tracker.HitTest( point );
  963.          if( eHitType == CRectTracker::hitMiddle )
  964.          {
  965.             // Drag the selection
  966.             if( tracker.Track( this, point ) )
  967.             {
  968.                posItem = m_lpSelectedItems.GetHeadPosition();
  969.                while( posItem != NULL )
  970.                {
  971.                   pItem = m_lpSelectedItems.GetNext( posItem );
  972.                   pItem->InvalidateItem();
  973.                }
  974.  
  975.                sizeDisplacement = tracker.m_rect.TopLeft()-ptStart;
  976.  
  977.                posItem = m_lpSelectedItems.GetHeadPosition();
  978.                while( posItem != NULL )
  979.                {
  980.                   pItem = m_lpSelectedItems.GetNext( posItem );
  981.                   rectItem = pItem->m_rect;
  982.                   rectItem.OffsetRect( sizeDisplacement );
  983.                   pItem->Move( rectItem );
  984.                   pItem->InvalidateItem();
  985.                }
  986.  
  987.                GetDocument()->SetModifiedFlag();
  988.             }
  989.          }
  990.          else
  991.          {
  992.             if( (eHitType != CRectTracker::hitNothing) && (m_pSelection !=
  993.                NULL) )
  994.             {
  995.                // Resize the item.
  996.                if( tracker.Track( this, point ) )
  997.                {
  998.                   m_pSelection->InvalidateItem();
  999.                }
  1000.  
  1001.                tracker.m_rect.DeflateRect( MARGIN_PIXELS, MARGIN_PIXELS );
  1002.                m_pSelection->Move( tracker.m_rect );
  1003.                m_pSelection->InvalidateItem();
  1004.  
  1005.                GetDocument()->SetModifiedFlag();
  1006.             }
  1007.          }
  1008.       }
  1009.    }
  1010.    else
  1011.    {
  1012.       CRectTracker tracker;
  1013.       CRect rectIntersection;
  1014.       CTestContainer98Doc* pDoc;
  1015.  
  1016.       if( tracker.TrackRubberBand( this, point, TRUE ) )
  1017.       {
  1018.          tracker.m_rect.NormalizeRect();
  1019.  
  1020.          pDoc = GetDocument();
  1021.          posItem = pDoc->GetStartPosition();
  1022.          while( posItem != NULL )
  1023.          {
  1024.             pItem = STATIC_DOWNCAST( CTestContainer98Item, pDoc->GetNextItem(
  1025.                posItem ) );
  1026.             if( rectIntersection.IntersectRect( tracker.m_rect,
  1027.                pItem->m_rect ) )
  1028.             {
  1029.                SetMultiSelect( pItem, TRUE );
  1030.             }
  1031.          }
  1032.       }
  1033.    }
  1034. }
  1035.  
  1036. void CTestContainer98View::SetupSelectionTracker( CRectTracker* pTracker )
  1037. {
  1038.    POSITION posItem;
  1039.    CTestContainer98Item* pItem;
  1040.  
  1041.    ASSERT( !m_lpSelectedItems.IsEmpty() );
  1042.    if( m_pSelection != NULL )
  1043.    {
  1044.       // Only one item is selected, so use its tracker.
  1045.       SetupTracker( m_pSelection, pTracker );
  1046.    }
  1047.    else
  1048.    {
  1049.       pTracker->m_rect.SetRectEmpty();
  1050.       posItem = m_lpSelectedItems.GetHeadPosition();
  1051.       while( posItem != NULL )
  1052.       {
  1053.          pItem = m_lpSelectedItems.GetNext( posItem );
  1054.          pTracker->m_rect.UnionRect( pTracker->m_rect, pItem->m_rect );
  1055.       }
  1056.       pTracker->m_rect.InflateRect( MARGIN_PIXELS, MARGIN_PIXELS );
  1057.       pTracker->m_nHandleSize = MARGIN_PIXELS+1;
  1058.       pTracker->m_sizeMin.cx = 8;
  1059.       pTracker->m_sizeMin.cy = 8;
  1060.       pTracker->m_nStyle = CRectTracker::solidLine;
  1061.    }
  1062. }
  1063.  
  1064. void CTestContainer98View::SetupTracker( CTestContainer98Item* pItem,
  1065.    CRectTracker* pTracker )
  1066. {
  1067.    pTracker->m_rect = pItem->m_rect;
  1068.    pTracker->m_rect.InflateRect( MARGIN_PIXELS, MARGIN_PIXELS );
  1069.    pTracker->m_nHandleSize = MARGIN_PIXELS+1;
  1070.    pTracker->m_sizeMin.cx = 8;
  1071.    pTracker->m_sizeMin.cy = 8;
  1072.  
  1073.    pTracker->m_nStyle = 0;
  1074.  
  1075.    if( m_lpSelectedItems.Find( pItem ) != NULL )
  1076.    {
  1077.       pTracker->m_nStyle |= CRectTracker::resizeInside;
  1078.    }
  1079.  
  1080.    pTracker->m_nStyle |= CRectTracker::solidLine;
  1081.  
  1082.    if( (pItem->GetItemState() == COleClientItem::openState) ||
  1083.       (pItem->GetItemState() == COleClientItem::activeUIState) )
  1084.    {
  1085.       pTracker->m_nStyle |= CRectTracker::hatchInside;
  1086.    }
  1087. }
  1088.  
  1089. void CTestContainer98View::OnLButtonDblClk( UINT nFlags, CPoint point )
  1090. {
  1091.    LONG iVerb;
  1092.    BOOL tHandled;
  1093.    CTestContainer98Item* pItemHit;
  1094.    MSG msg;
  1095.    DWORD dwHitType;
  1096.  
  1097.    tHandled = HandleWindowlessMouseMessage( point );
  1098.    if( tHandled )
  1099.    {
  1100.       return;
  1101.    }
  1102.  
  1103.    pItemHit = HitTestItems( point, &dwHitType );
  1104.  
  1105.    SetSelection( pItemHit );
  1106.  
  1107.    if( pItemHit != NULL )
  1108.    {
  1109.       if( !GetDocument()->GetUserMode() && pItemHit->IsInsideOut() &&
  1110.          !pItemHit->IsUIActive() )
  1111.       {
  1112.          // UIActivate the selected object.
  1113.          msg = *GetCurrentMessage();
  1114.          pItemHit->DoVerb( OLEIVERB_UIACTIVATE, this, &msg );
  1115.       }
  1116.    }
  1117.  
  1118.    Invalidate();
  1119.  
  1120.    if( m_pSelection != NULL )
  1121.    {
  1122.       if( GetKeyState( VK_CONTROL ) < 0 )
  1123.       {
  1124.          iVerb = OLEIVERB_OPEN;
  1125.       }
  1126.       else
  1127.       {
  1128.          iVerb = OLEIVERB_PRIMARY;
  1129.       }
  1130.  
  1131.       m_pSelection->DoVerb( iVerb, this );
  1132.    }
  1133.  
  1134.    CView::OnLButtonDblClk( nFlags, point );
  1135. }
  1136.  
  1137. HRESULT CTestContainer98View::OnWindowlessDefWindowMessage( UINT nMessage,
  1138.    WPARAM wParam, LPARAM lParam, LRESULT* plResult )
  1139. {
  1140.    const MSG* pMessage;
  1141.  
  1142.    (void)nMessage;
  1143.    (void)wParam;
  1144.    (void)lParam;
  1145.  
  1146.    pMessage = GetCurrentMessage();
  1147.    ASSERT( pMessage->message == nMessage );
  1148.    ASSERT( pMessage->wParam == wParam );
  1149.    ASSERT( pMessage->lParam == lParam );
  1150.  
  1151.    *plResult = Default();
  1152.  
  1153.    return( S_OK );
  1154. }
  1155.  
  1156. BOOL CTestContainer98View::OnSetCursor( CWnd* pWnd, UINT nHitTest,
  1157.    UINT message )
  1158. {
  1159.    CPoint pt;
  1160.    DWORD dwHitType;
  1161.    CRectTracker tracker;
  1162.    BOOL tHandled;
  1163.    CTestContainer98Item* pItemHit;
  1164.  
  1165.    // First, give the any inactive objects underneath the cursor a chance to
  1166.    // set the cursor and/or activate.
  1167.    tHandled = HandlePointerInactiveSetCursor( message );
  1168.    if( tHandled )
  1169.    {
  1170.       return( TRUE );
  1171.    }
  1172.  
  1173.    // Now, see if a windowless control should be handling this message.
  1174.    tHandled = HandleWindowlessMouseMessage( m_ptLastMousePosition );
  1175.    if( tHandled )
  1176.    {
  1177.       return( FALSE );
  1178.    }
  1179.  
  1180.    // None of the controls handled the message, so set the cursor ourselves.
  1181.    // The only interesting thing we do is let the tracker for the current
  1182.    // selection set the cursor to show resize/move arrows.
  1183.    if( pWnd == this )
  1184.    {
  1185.       GetCursorPos( &pt );
  1186.       ScreenToClient( &pt );
  1187.       pItemHit = HitTestItems( pt, &dwHitType );
  1188.       if( (pItemHit != NULL) && (dwHitType == HITTYPE_BORDER) &&
  1189.          (m_lpSelectedItems.Find( pItemHit ) != NULL) )
  1190.       {
  1191.          SetupTracker( pItemHit, &tracker );
  1192.          if( tracker.SetCursor( this, nHitTest ) )
  1193.          {
  1194.             return( TRUE );
  1195.          }
  1196.       }
  1197.    }
  1198.  
  1199.    return( CView::OnSetCursor( pWnd, nHitTest, message ) );
  1200. }
  1201.  
  1202. void CTestContainer98View::OnEditClear()
  1203. {
  1204.    POSITION posItem;
  1205.    CTestContainer98Item* pItem;
  1206.  
  1207.    ASSERT( !m_lpSelectedItems.IsEmpty() );
  1208.  
  1209.    posItem = m_lpSelectedItems.GetHeadPosition();
  1210.    while( posItem != NULL )
  1211.    {
  1212.       pItem = m_lpSelectedItems.GetNext( posItem );
  1213.       pItem->Delete();
  1214.    }
  1215.    ClearSelection();
  1216.    GetDocument()->UpdateAllViews( NULL );
  1217. }
  1218.  
  1219. void CTestContainer98View::OnUpdateEditClear( CCmdUI* pCmdUI )
  1220. {
  1221.    pCmdUI->Enable( !m_lpSelectedItems.IsEmpty() );
  1222. }
  1223.  
  1224. void CTestContainer98View::OnUpdate( CView* pSender, LPARAM lHint,
  1225.    CObject* pHint )
  1226. {
  1227.    (void)pSender;
  1228.  
  1229.    switch( lHint )
  1230.    {
  1231.    case HINT_UPDATE_WINDOW:
  1232.       Invalidate();
  1233.       break;
  1234.  
  1235.    case HINT_UPDATE_ITEM:
  1236.       {
  1237.          CRectTracker tracker;
  1238.          CRect rect;
  1239.  
  1240.          SetupTracker( (CTestContainer98Item*)pHint, &tracker );
  1241.          tracker.GetTrueRect( &rect );
  1242.          InvalidateRect( rect );
  1243.       }
  1244.       break;
  1245.    }
  1246. }
  1247.  
  1248. void CTestContainer98View::OnRButtonDown( UINT nFlags, CPoint point )
  1249. {
  1250.    CTestContainer98Item* pItemHit;
  1251.    BOOL tHandled;
  1252.    DWORD dwHitType;
  1253.    MSG msg;
  1254.  
  1255.    tHandled = HandleWindowlessMouseMessage( point );
  1256.    if( tHandled )
  1257.    {
  1258.       return;
  1259.    }
  1260.  
  1261.    pItemHit = HitTestItems( point, &dwHitType );
  1262.  
  1263.    if( !(nFlags&MK_CONTROL) )
  1264.    {
  1265.       if( (pItemHit != NULL) && (m_lpSelectedItems.Find( pItemHit ) == NULL) )
  1266.       {
  1267.          SetSelection( pItemHit );
  1268.       }
  1269.    }
  1270.  
  1271.    if( (pItemHit != NULL) && (dwHitType != HITTYPE_BORDER) )
  1272.    {
  1273.       if( !pItemHit->IsInPlaceActive() )
  1274.       {
  1275.          msg = *GetCurrentMessage();
  1276.          pItemHit->Activate( OLEIVERB_SHOW, this, &msg );
  1277.       }
  1278.    }
  1279. }
  1280.  
  1281. BOOL CTestContainer98View::PreTranslateMessage( MSG* pMsg )
  1282. {
  1283.    CTestContainer98Item* pItem;
  1284.    CTestContainer98Doc* pDoc;
  1285.    MSG msg;
  1286.    IOleInPlaceActiveObjectPtr pInPlaceActiveObject;
  1287.    HRESULT hResult;
  1288.    POSITION posItem;
  1289.    CTestContainer98Item* pCurrentItem;
  1290.  
  1291.    pDoc = GetDocument();
  1292.  
  1293.    pCurrentItem = NULL;
  1294.    if( m_pItemWithFocus != NULL )
  1295.    {
  1296.       pCurrentItem = m_pItemWithFocus;
  1297.    }
  1298.    else
  1299.    {
  1300.       // Try the UI active control
  1301.       posItem = pDoc->GetStartPosition();
  1302.       while( (posItem != NULL) && (pCurrentItem == NULL) )
  1303.       {
  1304.          pItem = (CTestContainer98Item*)pDoc->GetNextItem( posItem );
  1305.          if( pItem->IsUIActive() )
  1306.          {
  1307.             pCurrentItem = pItem;
  1308.          }
  1309.       }
  1310.    }
  1311.  
  1312.    if( ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST)) ||
  1313.       ((pMsg->message >= WM_MOUSEFIRST) && (pMsg->message <= WM_MOUSELAST)) )
  1314.    {
  1315.       // Give the item with focus first crack at keyboard and mouse messages
  1316.       if( pCurrentItem != NULL )
  1317.       {
  1318.          pInPlaceActiveObject = pCurrentItem->m_lpObject;
  1319.          if( pInPlaceActiveObject != NULL )
  1320.          {
  1321.             hResult = pInPlaceActiveObject->TranslateAccelerator( pMsg );
  1322.             if( hResult == S_OK )
  1323.             {
  1324.                return( TRUE );
  1325.             }
  1326.          }
  1327.       }
  1328.    }
  1329.  
  1330.    if( pMsg->message == WM_KEYDOWN )
  1331.    {
  1332.       if( LOWORD( pMsg->wParam ) == VK_TAB )
  1333.       {
  1334.          pItem = pDoc->GetNextTabItem( pCurrentItem );
  1335.          if( pItem != NULL )
  1336.          {
  1337.             if( pItem->HasUIActiveState() )
  1338.             {
  1339.                if( !pItem->IsUIActive() )
  1340.                {
  1341.                   msg = *pMsg;
  1342.                   pItem->DoVerb( OLEIVERB_UIACTIVATE, this, &msg );
  1343.                }
  1344.             }
  1345.             if( pItem->ActsLikeButton() )
  1346.             {
  1347.                pItem->DisplayAsDefault( TRUE );
  1348.             }
  1349.          }
  1350.  
  1351.          return( TRUE );
  1352.       }
  1353.    }
  1354.    else if( pMsg->message == WM_KEYUP )
  1355.    {
  1356.       if( LOWORD( pMsg->wParam ) == VK_TAB )
  1357.       {
  1358.          return( TRUE );
  1359.       }
  1360.    }
  1361.  
  1362.    return( CView::PreTranslateMessage( pMsg ) );
  1363. }
  1364.  
  1365. void CTestContainer98View::OnOptionsDesignMode()
  1366. {
  1367.    CTestContainer98Doc* pDoc;
  1368.  
  1369.    pDoc = GetDocument();
  1370.    pDoc->SetUserMode( !pDoc->GetUserMode() );
  1371. }
  1372.  
  1373. void CTestContainer98View::OnUpdateOptionsDesignMode( CCmdUI* pCmdUI )
  1374. {
  1375.    if( GetDocument()->GetUserMode() )
  1376.    {
  1377.       pCmdUI->SetCheck( 0 );
  1378.    }
  1379.    else
  1380.    {
  1381.       pCmdUI->SetCheck( 1 );
  1382.    }
  1383. }
  1384.  
  1385. BOOL CTestContainer98View::OnDrop( COleDataObject* pDataObject,
  1386.    DROPEFFECT dropEffect, CPoint point )
  1387. {
  1388.    DWORD dwDropEffect;
  1389.    BOOL tHandled;
  1390.  
  1391.    TRACE( "OnDrop()\n" );
  1392.  
  1393.    dwDropEffect = dropEffect;
  1394.    tHandled = HandleWindowlessDrop( pDataObject, m_dwLastDropKeyState, point,
  1395.       &dwDropEffect );
  1396.    if( tHandled )
  1397.    {
  1398.       return( CView::OnDrop( pDataObject, dropEffect, point ) );
  1399.    }
  1400.  
  1401.    return( CView::OnDrop( pDataObject, dropEffect, point ) );
  1402. }
  1403.  
  1404. CTestContainer98Item* CTestContainer98View::GetItemWithCapture() const
  1405. {
  1406.    return( m_pItemWithCapture );
  1407. }
  1408.  
  1409. CTestContainer98Item* CTestContainer98View::GetItemWithFocus() const
  1410. {
  1411.    return( m_pItemWithFocus );
  1412. }
  1413.  
  1414. HRESULT CTestContainer98View::OnWindowlessReleaseCapture(
  1415.    CTestContainer98Item* pItem )
  1416. {
  1417.    if( m_pItemWithCapture == pItem )
  1418.    {
  1419.       m_pItemWithCapture = NULL;
  1420.       ReleaseCapture();
  1421.    }
  1422.  
  1423.    return( S_OK );
  1424. }
  1425.  
  1426. HRESULT CTestContainer98View::OnWindowlessReleaseFocus()
  1427. {
  1428.    ASSERT( m_pItemWithFocus != NULL );
  1429.  
  1430.    m_pItemWithFocus = NULL;
  1431.  
  1432.    return( S_OK );
  1433. }
  1434.  
  1435. HRESULT CTestContainer98View::OnWindowlessSetCapture(
  1436.    CTestContainer98Item* pItem )
  1437. {
  1438.    ASSERT( pItem != NULL );
  1439. //   ASSERT( m_pItemWithCapture == NULL );
  1440.  
  1441.    SetCapture();
  1442.    m_pItemWithCapture = pItem;
  1443.  
  1444.    return( S_OK );
  1445. }
  1446.  
  1447. HRESULT CTestContainer98View::OnWindowlessSetFocus(
  1448.    CTestContainer98Item* pItem )
  1449. {
  1450.    ASSERT( pItem != NULL );
  1451.  
  1452.    TCTrace( TRACELEVEL_NORMAL, "Setting focus to windowless control.\n" );
  1453.  
  1454.    SetFocus();
  1455.    m_pItemWithFocus = pItem;
  1456.  
  1457.    return( S_OK );
  1458. }
  1459.  
  1460. DROPEFFECT CTestContainer98View::OnDragEnter( COleDataObject* pDataObject,
  1461.    DWORD dwKeyState, CPoint point )
  1462. {
  1463.    BOOL tHandled;
  1464.    DWORD dwDropEffect;
  1465.  
  1466.    TRACE( "OnDragEnter()\n" );
  1467.  
  1468.    HandlePointerInactiveDragOver( point );
  1469.  
  1470.    dwDropEffect = DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK;
  1471.    tHandled = HandleWindowlessDragEnter( pDataObject, dwKeyState, point,
  1472.       &dwDropEffect );
  1473.    if( tHandled )
  1474.    {
  1475.       return( dwDropEffect );
  1476.    }
  1477.  
  1478.     return( DROPEFFECT_NONE );
  1479. }
  1480.  
  1481. DROPEFFECT CTestContainer98View::OnDragOver( COleDataObject* pDataObject,
  1482.    DWORD dwKeyState, CPoint point )
  1483. {
  1484.    DWORD dwDropEffect;
  1485.    BOOL tHandled;
  1486.  
  1487.    m_dwLastDropKeyState = dwKeyState;
  1488.  
  1489.    HandlePointerInactiveDragOver( point );
  1490.  
  1491.    dwDropEffect = DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK;
  1492.    tHandled = HandleWindowlessDragOver( pDataObject, dwKeyState, point,
  1493.       &dwDropEffect );
  1494.    if( tHandled )
  1495.    {
  1496.       return( dwDropEffect );
  1497.    }
  1498.  
  1499.    return( DROPEFFECT_NONE );
  1500. }
  1501.  
  1502. int CTestContainer98View::OnCreate(LPCREATESTRUCT lpCreateStruct)
  1503. {
  1504.    if( CView::OnCreate( lpCreateStruct ) == -1 )
  1505.    {
  1506.       return( -1 );
  1507.    }
  1508.  
  1509.    // Register drop target.
  1510.    m_dropTarget.Register( this );
  1511.  
  1512.    return( 0 );
  1513. }
  1514.  
  1515. void CTestContainer98View::OnLButtonUp( UINT nFlags, CPoint point )
  1516. {
  1517.    BOOL tHandled;
  1518.  
  1519.    tHandled = HandleWindowlessMouseMessage( point );
  1520.    if( tHandled )
  1521.    {
  1522.       return;
  1523.    }
  1524.  
  1525.    CView::OnLButtonUp( nFlags, point );
  1526. }
  1527.  
  1528. void CTestContainer98View::OnMouseMove( UINT nFlags, CPoint point )
  1529. {
  1530.    BOOL tHandled;
  1531.  
  1532.    m_ptLastMousePosition = point;
  1533.  
  1534.    tHandled = HandlePointerInactiveMove( point, nFlags );
  1535.    if( tHandled )
  1536.    {
  1537.       return;
  1538.    }
  1539.  
  1540.    tHandled = HandleWindowlessMouseMessage( point );
  1541.    if( tHandled )
  1542.    {
  1543.       return;
  1544.    }
  1545.  
  1546.    CView::OnMouseMove( nFlags, point );
  1547. }
  1548.  
  1549. void CTestContainer98View::OnRButtonDblClk( UINT nFlags, CPoint point )
  1550. {
  1551.    BOOL tHandled;
  1552.  
  1553.    tHandled = HandleWindowlessMouseMessage( point );
  1554.    if( tHandled )
  1555.    {
  1556.       return;
  1557.    }
  1558.  
  1559.    CView::OnRButtonDblClk( nFlags, point );
  1560. }
  1561.  
  1562. void CTestContainer98View::OnRButtonUp( UINT nFlags, CPoint point )
  1563. {
  1564.    BOOL tHandled;
  1565.  
  1566.    tHandled = HandleWindowlessMouseMessage( point );
  1567.    if( tHandled )
  1568.    {
  1569.       return;
  1570.    }
  1571.  
  1572.    CView::OnRButtonUp( nFlags, point );
  1573. }
  1574.  
  1575. void CTestContainer98View::OnCaptureChanged( CWnd *pWnd )
  1576. {
  1577.    // We're losing the capture, so the windowless item that has the capture
  1578.    // loses it, too.
  1579.    m_pItemWithCapture = NULL;
  1580.  
  1581.     CView::OnCaptureChanged( pWnd );
  1582. }
  1583.  
  1584. void CTestContainer98View::OnFocus( CTestContainer98Item* pItem,
  1585.    BOOL tGotFocus )
  1586. {
  1587.    ASSERT( pItem != NULL );
  1588.  
  1589.    if( tGotFocus )
  1590.    {
  1591.       m_pItemWithFocus = pItem;
  1592.    }
  1593.    else
  1594.    {
  1595.       if( m_pItemWithFocus == pItem )
  1596.       {
  1597.          m_pItemWithFocus = NULL;
  1598.       }
  1599.    }
  1600. }
  1601.  
  1602. void CTestContainer98View::OnKillFocus( CWnd* pNewWnd )
  1603. {
  1604.     CView ::OnKillFocus( pNewWnd );
  1605. }
  1606.  
  1607. void CTestContainer98View::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
  1608. {
  1609.    BOOL tHandled;
  1610.  
  1611.    tHandled = HandleWindowlessKeyboardMessage();
  1612.    if( tHandled )
  1613.    {
  1614.       return;
  1615.    }
  1616.  
  1617.    CView::OnKeyDown( nChar, nRepCnt, nFlags );
  1618. }
  1619.  
  1620. void CTestContainer98View::OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags )
  1621. {
  1622.    BOOL tHandled;
  1623.  
  1624.    tHandled = HandleWindowlessKeyboardMessage();
  1625.    if( tHandled )
  1626.    {
  1627.       return;
  1628.    }
  1629.  
  1630.    CView::OnKeyUp( nChar, nRepCnt, nFlags );
  1631. }
  1632.  
  1633. void CTestContainer98View::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
  1634. {
  1635.    BOOL tHandled;
  1636.  
  1637.    tHandled = HandleWindowlessKeyboardMessage();
  1638.    if( tHandled )
  1639.    {
  1640.       return;
  1641.    }
  1642.  
  1643.    CView::OnChar( nChar, nRepCnt, nFlags );
  1644. }
  1645.  
  1646. void CTestContainer98View::OnCancelMode()
  1647. {
  1648.    BOOL tHandled;
  1649.  
  1650.    CView::OnCancelMode();
  1651.  
  1652.    tHandled = HandleWindowlessKeyboardMessage();
  1653.    if( tHandled )
  1654.    {
  1655.       return;
  1656.    }
  1657. }
  1658.  
  1659. void CTestContainer98View::OnControlSaveToStream()
  1660. {
  1661.    int nResult;
  1662.    CFileDialog dlg( FALSE, _T( "TSM" ), NULL, OFN_HIDEREADONLY|
  1663.       OFN_OVERWRITEPROMPT, _T( "Test Container Stream Files (*.TSM)|*.TSM||" ) );
  1664.    HRESULT hResult;
  1665.    IStreamPtr pStream;
  1666.    LARGE_INTEGER nDisplacement;
  1667.    ULARGE_INTEGER iSeekPtr;
  1668.    ULONG nBytesLeft;
  1669.    ULONG nBytesRead;
  1670.    BYTE abData[512];
  1671.  
  1672.    ASSERT( m_pSelection != NULL );
  1673.  
  1674.    nResult = dlg.DoModal();
  1675.    if( nResult != IDOK )
  1676.    {
  1677.       return;
  1678.    }
  1679.  
  1680.    hResult = CreateStreamOnHGlobal( NULL, TRUE, &pStream );
  1681.    if( FAILED( hResult ) )
  1682.    {
  1683.       TRACE( "CreateStreamOnHGlobal() failed.\n" );
  1684.       return;
  1685.    }
  1686.  
  1687.    hResult = m_pSelection->SaveToStream( pStream );
  1688.    if( FAILED( hResult ) )
  1689.    {
  1690.       CString strErrorMessage;
  1691.       _com_error e( hResult );
  1692.  
  1693.       strErrorMessage.LoadString( IDS_SAVETOSTREAMFAILED );
  1694.       strErrorMessage += e.ErrorMessage();
  1695.       AfxMessageBox( strErrorMessage );
  1696.       return;
  1697.    }
  1698.  
  1699.    try
  1700.    {
  1701.       CFile file( dlg.GetPathName(), CFile::modeCreate|CFile::modeWrite|
  1702.          CFile::shareExclusive );
  1703.  
  1704.       nDisplacement.QuadPart = 0;
  1705.       pStream->Seek( nDisplacement, STREAM_SEEK_CUR, &iSeekPtr );
  1706.       nBytesLeft = ULONG( iSeekPtr.QuadPart );
  1707.       pStream->Seek( nDisplacement, STREAM_SEEK_SET, NULL );
  1708.       while( nBytesLeft > 0 )
  1709.       {
  1710.          pStream->Read( abData, min( nBytesLeft, sizeof( abData ) ),
  1711.             &nBytesRead );
  1712.          ASSERT( nBytesRead > 0 );
  1713.          file.Write( abData, nBytesRead );
  1714.          nBytesLeft -= nBytesRead;
  1715.       }
  1716.    }
  1717.    catch( CFileException* pException )
  1718.    {
  1719.       pException->Delete();
  1720.  
  1721.       AfxMessageBox( IDS_ERRORWRITINGTOFILE );
  1722.    }
  1723. }
  1724.  
  1725. void CTestContainer98View::OnEditInsertFromStream()
  1726. {
  1727.    int nResult;
  1728.    HRESULT hResult;
  1729.    IStreamPtr pStream;
  1730.    LARGE_INTEGER nDisplacement;
  1731.    ULONG nBytesLeft;
  1732.    ULONG nBytesToRead;
  1733.    CTestContainer98Doc* pDoc;
  1734.    CTestContainer98Item* pItem;
  1735.    CLSID clsid;
  1736.    BYTE abData[512];
  1737.    CFileDialog dlg( TRUE, _T( "TSM" ), NULL, OFN_HIDEREADONLY|
  1738.       OFN_OVERWRITEPROMPT, _T( "Test Container Stream Files (*.TSM)|*.TSM||" ) );
  1739.  
  1740.    nResult = dlg.DoModal();
  1741.    if( nResult != IDOK )
  1742.    {
  1743.       return;
  1744.    }
  1745.  
  1746.    hResult = CreateStreamOnHGlobal( NULL, TRUE, &pStream );
  1747.    if( FAILED( hResult ) )
  1748.    {
  1749.       TRACE( "CreateStreamOnHGlobal() failed.\n" );
  1750.       return;
  1751.    }
  1752.  
  1753.    try
  1754.    {
  1755.       CFile file( dlg.GetPathName(), CFile::modeRead|CFile::shareDenyWrite );
  1756.  
  1757.       nBytesLeft = file.GetLength();
  1758.       while( nBytesLeft > 0 )
  1759.       {
  1760.          nBytesToRead = min( nBytesLeft, sizeof( abData ) );
  1761.          file.Read( abData, nBytesToRead );
  1762.          pStream->Write( abData, nBytesToRead, NULL );
  1763.          nBytesLeft -= nBytesToRead;
  1764.       }
  1765.    }
  1766.    catch( CFileException* pException )
  1767.    {
  1768.       pException->Delete();
  1769.       AfxMessageBox( IDS_ERRORREADINGFROMFILE );
  1770.       return;
  1771.    }
  1772.  
  1773.    nDisplacement.QuadPart = 0;
  1774.    pStream->Seek( nDisplacement, STREAM_SEEK_SET, NULL );
  1775.  
  1776.    BeginWaitCursor();
  1777.  
  1778.    pItem = NULL;
  1779.    try
  1780.    {
  1781.       hResult = ReadClassStm( pStream, &clsid );
  1782.       if( FAILED( hResult ) )
  1783.       {
  1784.          AfxThrowOleException( hResult );
  1785.       }
  1786.  
  1787.       pDoc = GetDocument();
  1788.       pItem = pDoc->AddControl( clsid, NULL, IID_IStream, pStream );
  1789.    }
  1790.    catch( COleException* pException )
  1791.    {
  1792.       CString strErrorMessage;
  1793.       _com_error error( pException->m_sc );
  1794.  
  1795.       pException->Delete();
  1796.  
  1797.       if( pItem != NULL )
  1798.       {
  1799.          ASSERT_VALID( pItem );
  1800.          pItem->Delete();
  1801.       }
  1802.  
  1803.       AfxFormatString1( strErrorMessage, IDS_CREATEFAILED,
  1804.          error.ErrorMessage() );
  1805.  
  1806.       AfxMessageBox( strErrorMessage );
  1807.    }
  1808.    catch( CException* pException )
  1809.    {
  1810.       pException->Delete();
  1811.  
  1812.       AfxMessageBox( IDP_FAILED_TO_CREATE );
  1813.    }
  1814.  
  1815.    EndWaitCursor();
  1816. }
  1817.  
  1818. void CTestContainer98View::OnDragLeave()
  1819. {
  1820.    TRACE( "OnDragLeave()\n" );
  1821.  
  1822.    HandleWindowlessDragLeave();
  1823.  
  1824.     CView::OnDragLeave();
  1825. }
  1826.  
  1827. void CTestContainer98View::OnControlSaveToPropertyBag()
  1828. {
  1829.    CPropertyBag* pPropertyBagObject;
  1830.    IPropertyBagPtr pPropertyBag;
  1831.    HRESULT hResult;
  1832.  
  1833.    pPropertyBagObject = new CPropertyBag;
  1834.    if( pPropertyBagObject == NULL )
  1835.    {
  1836.       return;
  1837.    }
  1838.  
  1839.    hResult = pPropertyBagObject->QueryInterface( IID_IPropertyBag,
  1840.       (void**)&pPropertyBag );
  1841.    ASSERT( SUCCEEDED( hResult ) );
  1842.  
  1843.    hResult = m_pSelection->SaveToPropertyBag( pPropertyBag );
  1844.    if( FAILED( hResult ) )
  1845.    {
  1846.       CString strErrorMessage;
  1847.       _com_error e( hResult );
  1848.  
  1849.       strErrorMessage.LoadString( IDS_SAVETOPROPERTYBAGFAILED );
  1850.       strErrorMessage += e.ErrorMessage();
  1851.       AfxMessageBox( strErrorMessage );
  1852.       return;
  1853.    }
  1854.  
  1855.    CPropertyBagDlg dlg( pPropertyBagObject );
  1856.  
  1857.    dlg.DoModal();
  1858. }
  1859.  
  1860. void CTestContainer98View::OnUpdateControlSaveToPropertyBag( CCmdUI* pCmdUI )
  1861. {
  1862.    pCmdUI->Enable( m_pSelection != NULL );
  1863. }
  1864.  
  1865. void CTestContainer98View::OnUpdateControlSaveToStream( CCmdUI* pCmdUI )
  1866. {
  1867.    pCmdUI->Enable( m_pSelection != NULL );
  1868. }
  1869.  
  1870. void CTestContainer98View::OnControlInvokeMethods()
  1871. {
  1872.    ASSERT( m_pSelection != NULL );
  1873.  
  1874.    m_pSelection->InvokeMethods();
  1875. }
  1876.  
  1877. void CTestContainer98View::OnUpdateControlInvokeMethods( CCmdUI* pCmdUI )
  1878. {
  1879.    pCmdUI->Enable( m_pSelection != NULL );
  1880. }
  1881.  
  1882. void CTestContainer98View::OnControlLogging()
  1883. {
  1884.    ASSERT( m_pSelection != NULL );
  1885.  
  1886.    m_pSelection->SetLoggingOptions();
  1887. }
  1888.  
  1889. void CTestContainer98View::OnUpdateControlLogging( CCmdUI* pCmdUI )
  1890. {
  1891.    pCmdUI->Enable( m_pSelection != NULL );
  1892. }
  1893.  
  1894. void CTestContainer98View::OnControlActivate()
  1895. {
  1896.    ASSERT( m_pSelection != NULL );
  1897.  
  1898.    m_pSelection->Activate( OLEIVERB_INPLACEACTIVATE, this );
  1899. }
  1900.  
  1901. void CTestContainer98View::OnControlDeactivate()
  1902. {
  1903.    ASSERT( m_pSelection != NULL );
  1904.  
  1905.    m_pSelection->Deactivate();
  1906. }
  1907.  
  1908. void CTestContainer98View::OnControlUIActivate()
  1909. {
  1910.    ASSERT( m_pSelection != NULL );
  1911.  
  1912.    m_pSelection->Activate( OLEIVERB_UIACTIVATE, this );
  1913. }
  1914.  
  1915. void CTestContainer98View::OnControlUIDeactivate()
  1916. {
  1917.    ASSERT( m_pSelection != NULL );
  1918.  
  1919.    m_pSelection->DeactivateUI();
  1920. }
  1921.  
  1922. void CTestContainer98View::OnUpdateControlUIDeactivate( CCmdUI* pCmdUI )
  1923. {
  1924.    pCmdUI->Enable( (m_pSelection != NULL)   && (m_pSelection->IsUIActive()) );
  1925. }
  1926.  
  1927. void CTestContainer98View::OnUpdateControlUIActivate( CCmdUI* pCmdUI )
  1928. {
  1929.    pCmdUI->Enable( (m_pSelection != NULL) && (!m_pSelection->IsUIActive()) );
  1930. }
  1931.  
  1932. void CTestContainer98View::OnUpdateControlActivate( CCmdUI* pCmdUI )
  1933. {
  1934.    pCmdUI->Enable( (m_pSelection != NULL) &&
  1935.       (!m_pSelection->IsInPlaceActive()) );
  1936. }
  1937.  
  1938. void CTestContainer98View::OnUpdateControlDeactivate( CCmdUI* pCmdUI )
  1939. {
  1940.    pCmdUI->Enable( (m_pSelection != NULL) &&
  1941.       (m_pSelection->IsInPlaceActive()) );
  1942. }
  1943.  
  1944. void CTestContainer98View::OnEditBringToFront()
  1945. {
  1946.    POSITION posItem;
  1947.    CTestContainer98Item* pItem;
  1948.  
  1949.    ASSERT( !m_lpSelectedItems.IsEmpty() );
  1950.  
  1951.    posItem = m_lpSelectedItems.GetHeadPosition();
  1952.    while( posItem != NULL )
  1953.    {
  1954.       pItem = m_lpSelectedItems.GetNext( posItem );
  1955.       GetDocument()->BringToFront( pItem );
  1956.    }
  1957.  
  1958.    Invalidate();
  1959. }
  1960.  
  1961. void CTestContainer98View::OnUpdateEditBringToFront( CCmdUI* pCmdUI )
  1962. {
  1963.    pCmdUI->Enable( !m_lpSelectedItems.IsEmpty() );
  1964. }
  1965.  
  1966. void CTestContainer98View::OnEditSendToBack()
  1967. {
  1968.    POSITION posItem;
  1969.    CTestContainer98Item* pItem;
  1970.  
  1971.    ASSERT( !m_lpSelectedItems.IsEmpty() );
  1972.  
  1973.    posItem = m_lpSelectedItems.GetHeadPosition();
  1974.    while( posItem != NULL )
  1975.    {
  1976.       pItem = m_lpSelectedItems.GetNext( posItem );
  1977.       GetDocument()->SendToBack( pItem );
  1978.    }
  1979.  
  1980.    Invalidate();
  1981. }
  1982.  
  1983. void CTestContainer98View::OnUpdateEditSendToBack( CCmdUI* pCmdUI )
  1984. {
  1985.    pCmdUI->Enable( !m_lpSelectedItems.IsEmpty() );
  1986. }
  1987.  
  1988. void CTestContainer98View::OnContextMenu( CWnd* pWnd, CPoint point )
  1989. {
  1990.    CTestContainer98Item* pItemHit;
  1991.    CPoint ptClient;
  1992.    CMenu menu;
  1993.    CMenu* pPopupMenu;
  1994.    DWORD dwHitType;
  1995.  
  1996.    if( pWnd->m_hWnd != m_hWnd )
  1997.    {
  1998.       return;
  1999.    }
  2000.  
  2001.    GetParentFrame()->ActivateFrame();
  2002.  
  2003.    ptClient = point;
  2004.    ScreenToClient( &ptClient );
  2005.  
  2006.    pItemHit = HitTestItems( ptClient, &dwHitType );
  2007.  
  2008.    if( pItemHit == NULL )
  2009.    {
  2010.       menu.LoadMenu( IDR_CONTAINER_CONTEXT );
  2011.       pPopupMenu = menu.GetSubMenu( 0 );
  2012.       pPopupMenu->TrackPopupMenu( TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x,
  2013.          point.y, AfxGetMainWnd(), NULL );
  2014.       menu.DestroyMenu();
  2015.    }
  2016.    else
  2017.    {
  2018.       if( m_lpSelectedItems.Find( pItemHit ) != NULL )
  2019.       {
  2020.          // The item is selected.  Create a popup menu at the current mouse
  2021.          // location, and fill it with the appropriate verbs for the object.
  2022.          menu.LoadMenu( IDR_CONTROL_CONTEXT );
  2023.          pPopupMenu = menu.GetSubMenu( 0 );
  2024.          pPopupMenu->TrackPopupMenu( TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x,
  2025.             point.y, AfxGetMainWnd(), NULL );
  2026.          menu.DestroyMenu();
  2027.       }
  2028.    }
  2029. }
  2030.  
  2031. void CTestContainer98View::OnEditProperties()
  2032. {
  2033.    POSITION posItem;
  2034.    CTestContainer98Item* pItem;
  2035.    CArray< CLSID, CLSID& > aclsidCommonPages;
  2036.    CArray< CLSID, CLSID& > aclsidPages;
  2037.    BOOL tSuccess;
  2038.    int iPage;
  2039.    int iCommonPage;
  2040.    BOOL tFound;
  2041.    CLSID clsidPage;
  2042.  
  2043.    posItem = m_lpSelectedItems.GetHeadPosition();
  2044.    pItem = m_lpSelectedItems.GetNext( posItem );
  2045.    tSuccess = pItem->GetPropertyPageCLSIDs( aclsidCommonPages );
  2046.    if( !tSuccess )
  2047.    {
  2048.       return;
  2049.    }
  2050.    while( posItem != NULL )
  2051.    {
  2052.       pItem = m_lpSelectedItems.GetNext( posItem );
  2053.       aclsidPages.RemoveAll();
  2054.       tSuccess = pItem->GetPropertyPageCLSIDs( aclsidPages );
  2055.       if( !tSuccess )
  2056.       {
  2057.          return;
  2058.       }
  2059.  
  2060.       for( iCommonPage = aclsidCommonPages.GetSize()-1; iCommonPage >= 0;
  2061.          iCommonPage-- )
  2062.       {
  2063.          clsidPage = aclsidCommonPages[iCommonPage];
  2064.          tFound = FALSE;
  2065.          for( iPage = 0; iPage < aclsidPages.GetSize(); iPage++ )
  2066.          {
  2067.             if( IsEqualCLSID( clsidPage, aclsidPages[iPage] ) )
  2068.             {
  2069.                tFound = TRUE;
  2070.             }
  2071.          }
  2072.          if( !tFound )
  2073.          {
  2074.             aclsidCommonPages.RemoveAt( iCommonPage );
  2075.          }
  2076.       }
  2077.    }
  2078.  
  2079.    if( m_lpSelectedItems.GetCount() > 1 )
  2080.    {
  2081.       // Don't display the extended properties page if multiple items are
  2082.       // selected.
  2083.       for( iCommonPage = 0; iCommonPage < aclsidCommonPages.GetSize();
  2084.          iCommonPage++ )
  2085.       {
  2086.          if( IsEqualCLSID( aclsidCommonPages[iCommonPage], __uuidof(
  2087.             TCExtPage ) ) )
  2088.          {
  2089.             aclsidCommonPages.RemoveAt( iCommonPage );
  2090.          }
  2091.       }
  2092.    }
  2093.  
  2094.    if( aclsidCommonPages.GetSize() == 0 )
  2095.    {
  2096.       AfxMessageBox( IDS_NOCOMMONPROPERTIES );
  2097.    }
  2098.    else
  2099.    {
  2100.       USES_CONVERSION;
  2101.       int iObject;
  2102.       IUnknown** ppObjects;
  2103.       CLSID* pclsidCommonPages;
  2104.       CString strCaption;
  2105.  
  2106.       ppObjects = (IUnknown**)_alloca( m_lpSelectedItems.GetCount()*sizeof(
  2107.          IUnknown* ) );
  2108.       iObject = 0;
  2109.       posItem = m_lpSelectedItems.GetHeadPosition();
  2110.       while( posItem != NULL )
  2111.       {
  2112.          pItem = m_lpSelectedItems.GetNext( posItem );
  2113.          ppObjects[iObject] = pItem->m_lpObject;
  2114.          iObject++;
  2115.       }
  2116.  
  2117.       pclsidCommonPages = (CLSID*)_alloca( aclsidCommonPages.GetSize()*sizeof(
  2118.          CLSID ) );
  2119.       for( iPage = 0; iPage < aclsidCommonPages.GetSize(); iPage++ )
  2120.       {
  2121.          pclsidCommonPages[iPage] = aclsidCommonPages[iPage];
  2122.       }
  2123.  
  2124.       if( m_lpSelectedItems.GetCount() > 1 )
  2125.       {
  2126.          strCaption.LoadString( IDS_MULTIPLESELECTION );
  2127.       }
  2128.       else
  2129.       {
  2130.          strCaption = m_pSelection->GetDisplayName();
  2131.       }
  2132.       OleCreatePropertyFrame( m_hWnd, 0, 0, T2COLE( strCaption ),
  2133.          m_lpSelectedItems.GetCount(), ppObjects, aclsidCommonPages.GetSize(),
  2134.          pclsidCommonPages, GetUserDefaultLCID(), 0, NULL );
  2135.  
  2136.       //WINBUG: OleCreatePropertyFrame doesn't return focus to its parent when
  2137.       // it closes
  2138.       SetFocus();
  2139.    }
  2140. }
  2141.  
  2142. void CTestContainer98View::OnUpdateEditProperties( CCmdUI* pCmdUI )
  2143. {
  2144.    pCmdUI->Enable( !m_lpSelectedItems.IsEmpty() );
  2145. }
  2146.  
  2147. void CTestContainer98View::OnEditSelectAll()
  2148. {
  2149.    POSITION posItem;
  2150.    CTestContainer98Item* pItem;
  2151.    CTestContainer98Doc* pDoc;
  2152.  
  2153.    pDoc = GetDocument();
  2154.    posItem = pDoc->GetStartPosition();
  2155.    while( posItem != NULL )
  2156.    {
  2157.       pItem = (CTestContainer98Item*)pDoc->GetNextItem( posItem );
  2158.       SetMultiSelect( pItem, TRUE );
  2159.    }
  2160. }
  2161.  
  2162. void CTestContainer98View::OnEditCopy()
  2163. {
  2164.    IStoragePtr pStorage;
  2165.    HRESULT hResult;
  2166.    POSITION posItem;
  2167.    CTestContainer98Item* pItem;
  2168.    COleStreamFile file;
  2169.    ULONG iItem;
  2170.    CString strStorageName;
  2171.    BSTR bstrStorageName;
  2172.    IStoragePtr pSubStorage;
  2173.    COleDataSource* pDataSource;
  2174.    CLIPFORMAT cf;
  2175.    STGMEDIUM stgmedium;
  2176.    int nSelectedItems;
  2177.  
  2178.    ASSERT( m_lpSelectedItems.GetCount() > 0 );
  2179.  
  2180.    pDataSource = new COleDataSource;
  2181.    try
  2182.    {
  2183.       hResult = StgCreateDocfile( NULL, STGM_CREATE|STGM_READWRITE|
  2184.          STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE, 0, &pStorage );
  2185.       if( FAILED( hResult ) )
  2186.       {
  2187.          AfxThrowOleException( hResult );
  2188.       }
  2189.  
  2190.       if( !file.CreateStream( pStorage, _T( "Contents" ), CFile::modeReadWrite|
  2191.          CFile::shareExclusive|CFile::modeCreate ) )
  2192.       {
  2193.          AfxThrowOleException( E_FAIL );
  2194.       }
  2195.  
  2196.       CArchive ar( &file, CArchive::store );
  2197.  
  2198.       nSelectedItems = m_lpSelectedItems.GetCount();
  2199.       ar<<nSelectedItems;
  2200.  
  2201.       posItem = m_lpSelectedItems.GetHeadPosition();
  2202.       iItem = 0;
  2203.       while( posItem != NULL )
  2204.       {
  2205.          pItem = m_lpSelectedItems.GetNext( posItem );
  2206.          strStorageName.Format( "Control%d", iItem );
  2207.          bstrStorageName = strStorageName.AllocSysString();
  2208.  
  2209.          hResult = pStorage->CreateStorage( bstrStorageName, STGM_READWRITE|
  2210.             STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &pSubStorage );
  2211.          SysFreeString( bstrStorageName );
  2212.          if( FAILED( hResult ) )
  2213.          {
  2214.             AfxThrowOleException( hResult );
  2215.          }
  2216.  
  2217.          pItem->CopyToClipboard( ar, pSubStorage );
  2218.  
  2219.          pSubStorage.Release();
  2220.          iItem++;
  2221.       }
  2222.  
  2223.       stgmedium.tymed = TYMED_ISTORAGE;
  2224.       stgmedium.pstg = pStorage;
  2225.       stgmedium.pstg->AddRef();
  2226.       stgmedium.pUnkForRelease = NULL;
  2227.  
  2228.       cf = CLIPFORMAT( ::RegisterClipboardFormat( _T( "TC98 Controls" ) ) );
  2229.       pDataSource->CacheData( cf, &stgmedium );
  2230.    }
  2231.    catch( COleException* pException )
  2232.    {
  2233.       CString strErrorMessage;
  2234.       _com_error error( pException->m_sc );
  2235.  
  2236.       pException->Delete();
  2237.       delete pDataSource;
  2238.  
  2239.       AfxFormatString1( strErrorMessage, IDS_COPYFAILED,
  2240.          error.ErrorMessage() );
  2241.       AfxMessageBox( strErrorMessage );
  2242.       return;
  2243.    }
  2244.  
  2245.    file.Close();
  2246.  
  2247.    pDataSource->SetClipboard();
  2248. }
  2249.  
  2250. void CTestContainer98View::OnEditPaste()
  2251. {
  2252.    CTestContainer98Item* pItem;
  2253.    CTestContainer98Doc* pDoc;
  2254.    COleDataObject data;
  2255.    CLIPFORMAT cf;
  2256.    STGMEDIUM stgmedium;
  2257.    IStoragePtr pStorage;
  2258.    IStoragePtr pSubStorage;
  2259.    int iItem;
  2260.    int nItems;
  2261.    CString strItemName;
  2262.    BSTR bstrItemName;
  2263.    HRESULT hResult;
  2264.    COleStreamFile file;
  2265.  
  2266.    pDoc = GetDocument();
  2267.  
  2268.    if( !data.AttachClipboard() )
  2269.    {
  2270.       return;
  2271.    }
  2272.  
  2273.    cf = CLIPFORMAT( ::RegisterClipboardFormat( _T( "TC98 Controls" ) ) );
  2274.    if( !data.GetData( cf, &stgmedium ) )
  2275.    {
  2276.       return;
  2277.    }
  2278.  
  2279.    ASSERT( stgmedium.tymed == TYMED_ISTORAGE );
  2280.  
  2281.    pStorage = stgmedium.pstg;
  2282.    ReleaseStgMedium( &stgmedium );
  2283.  
  2284.    if( !file.OpenStream( pStorage, _T( "Contents" ), STGM_READ|
  2285.       STGM_SHARE_EXCLUSIVE ) )
  2286.    {
  2287.       return;
  2288.    }
  2289.  
  2290.    CArchive ar( &file, CArchive::load|CArchive::bNoFlushOnDelete );
  2291.  
  2292.    ClearSelection();
  2293.  
  2294.    ar>>nItems;
  2295.  
  2296.    for( iItem = 0; iItem < nItems; iItem++ )
  2297.    {
  2298.       pItem = NULL;
  2299.       try
  2300.       {
  2301.          strItemName.Format( "Control%d", iItem );
  2302.          bstrItemName = strItemName.AllocSysString();
  2303.          hResult = pStorage->OpenStorage( bstrItemName, NULL, STGM_READWRITE|
  2304.             STGM_SHARE_EXCLUSIVE, NULL, 0, &pSubStorage );
  2305.          SysFreeString( bstrItemName );
  2306.          if( FAILED( hResult ) )
  2307.          {
  2308.             AfxThrowOleException( hResult );
  2309.          }
  2310.  
  2311.          pItem = new CTestContainer98Item( pDoc );
  2312.          if( !pItem->CreateFromClipboard( ar, pSubStorage ) )
  2313.          {
  2314.             AfxThrowOleException( E_FAIL );
  2315.          }
  2316.  
  2317.          pItem->UpdateLink();
  2318.          pItem->InvalidateItem();
  2319.  
  2320.          // Activate the item if it wants to be active all the time.
  2321.          if( pItem->ShouldActivateWhenVisible() )
  2322.          {
  2323.             if( pDoc->GetUserMode() && pItem->IsInvisibleAtRuntime() )
  2324.             {
  2325.                pItem->DoVerb( OLEIVERB_HIDE, this );
  2326.             }
  2327.             else
  2328.             {
  2329.                pItem->DoVerb( OLEIVERB_SHOW, this );
  2330.             }
  2331.          }
  2332.  
  2333.          SetMultiSelect( pItem, TRUE );
  2334.  
  2335.          ASSERT_VALID( pItem );
  2336.       }
  2337.       catch( CException* pException )
  2338.       {
  2339.          pException->Delete();
  2340.  
  2341.          delete pItem;
  2342.       }
  2343.    }
  2344.  
  2345.    ar.Flush();
  2346.    file.Close();
  2347.  
  2348.    pDoc->SetModifiedFlag();
  2349.  
  2350.    Invalidate();
  2351. }
  2352.  
  2353. void CTestContainer98View::OnUpdateEditCopy( CCmdUI* pCmdUI )
  2354. {
  2355.    pCmdUI->Enable( m_lpSelectedItems.GetCount() > 0 );
  2356. }
  2357.  
  2358. void CTestContainer98View::OnUpdateEditPaste( CCmdUI* pCmdUI )
  2359. {
  2360.    pCmdUI->Enable( IsClipboardFormatAvailable( ::RegisterClipboardFormat( _T(
  2361.       "TC98 Controls" ) ) ) );
  2362. }
  2363.  
  2364. void CTestContainer98View::OnEditCut()
  2365. {
  2366.    OnEditCopy();
  2367.    OnEditClear();
  2368. }
  2369.  
  2370. void CTestContainer98View::OnUpdateEditCut( CCmdUI* pCmdUI )
  2371. {
  2372.    pCmdUI->Enable( m_lpSelectedItems.GetCount() > 0 );
  2373. }
  2374.  
  2375. const LPCTSTR VS_SETUP_KEY = _T(
  2376.    "Software\\Microsoft\\VisualStudio\\6.0\\Setup" );
  2377. const LPCTSTR VS_COMMONDIR_VALUENAME = _T( "VsCommonDir" );
  2378.  
  2379. void CTestContainer98View::OnToolsOLEView()
  2380. {
  2381.    HKEY hKey;
  2382.    LONG nResult;
  2383.    DWORD dwType;
  2384.    CString strPath;
  2385.    LPTSTR pszPath;
  2386.    ULONG nDataLength;
  2387.    STARTUPINFO startup;
  2388.    PROCESS_INFORMATION process;
  2389.    BOOL tSuccess;
  2390.  
  2391.    nResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, VS_SETUP_KEY, 0, KEY_READ,
  2392.       &hKey );
  2393.    if( nResult != ERROR_SUCCESS )
  2394.    {
  2395.       return;
  2396.    }
  2397.  
  2398.    nResult = RegQueryValueEx( hKey, VS_COMMONDIR_VALUENAME, NULL, &dwType,
  2399.       NULL, &nDataLength );
  2400.    if( (nResult == ERROR_SUCCESS) && (dwType == REG_SZ) )
  2401.    {
  2402.       pszPath = strPath.GetBuffer( nDataLength/sizeof( TCHAR ) );
  2403.       nResult = RegQueryValueEx( hKey, VS_COMMONDIR_VALUENAME, NULL, &dwType,
  2404.          LPBYTE( pszPath ), &nDataLength );
  2405.       strPath.ReleaseBuffer();
  2406.       strPath += _T( "\\Tools\\OLEView.exe" );
  2407.       if( (nResult == ERROR_SUCCESS) && (dwType == REG_SZ) )
  2408.       {
  2409.          memset( &startup, 0, sizeof( startup ) );
  2410.          startup.cb = sizeof( startup );
  2411.  
  2412.          memset( &process, 0, sizeof( process ) );
  2413.  
  2414.          tSuccess = CreateProcess( strPath, NULL, NULL, NULL, FALSE, 0, NULL,
  2415.             NULL, &startup, &process );
  2416.          if( tSuccess )
  2417.          {
  2418.             // Close the handles that CreateProcess returned so we don't leak
  2419.             // kernel resources.
  2420.             ASSERT( process.hProcess != NULL );
  2421.             CloseHandle( process.hProcess );
  2422.             ASSERT( process.hThread != NULL );
  2423.             CloseHandle( process.hThread );
  2424.          }
  2425.          else
  2426.          {
  2427.             AfxMessageBox( IDS_NOOLEVIEW );
  2428.          }
  2429.       }
  2430.    }
  2431.  
  2432.    RegCloseKey( hKey );
  2433. }
  2434.  
  2435. void CTestContainer98View::OnToolsRegEdit()
  2436. {
  2437.    STARTUPINFO startup;
  2438.    PROCESS_INFORMATION process;
  2439.    BOOL tSuccess;
  2440.    CString strPath;
  2441.    LPTSTR pszPath;
  2442.  
  2443.    pszPath = strPath.GetBuffer( MAX_PATH );
  2444.    GetWindowsDirectory( pszPath, MAX_PATH );
  2445.    strPath.ReleaseBuffer();
  2446.  
  2447.    memset( &startup, 0, sizeof( startup ) );
  2448.    startup.cb = sizeof( startup );
  2449.  
  2450.    memset( &process, 0, sizeof( process ) );
  2451.  
  2452.    tSuccess = CreateProcess( strPath+_T( "\\RegEdit.exe" ), NULL, NULL, NULL,
  2453.       FALSE, 0, NULL, NULL, &startup, &process );
  2454.    if( tSuccess )
  2455.    {
  2456.       // Close the handles that CreateProcess returned so we don't leak
  2457.       // kernel resources.
  2458.       ASSERT( process.hProcess != NULL );
  2459.       CloseHandle( process.hProcess );
  2460.       ASSERT( process.hThread != NULL );
  2461.       CloseHandle( process.hThread );
  2462.    }
  2463. }
  2464.  
  2465. void CTestContainer98View::OnControlSaveToStorage()
  2466. {
  2467.    USES_CONVERSION;
  2468.    HKEY hKey;
  2469.    LONG nResult;
  2470.    DWORD dwType;
  2471.    CString strPath;
  2472.    LPTSTR pszPath;
  2473.    CString strCommandLine;
  2474.    LPTSTR pszCommandLine;
  2475.    ULONG nDataLength;
  2476.    STARTUPINFO startup;
  2477.    PROCESS_INFORMATION process;
  2478.    BOOL tSuccess;
  2479.    HRESULT hResult;
  2480.    IStoragePtr pStorage;
  2481.    CFileDialog dlg( FALSE, _T( "TSG" ), NULL, OFN_HIDEREADONLY|
  2482.       OFN_OVERWRITEPROMPT, _T( "Test Container Storage Files (*.TSG)|*.TSG||" ) );
  2483.  
  2484.    ASSERT( m_pSelection != NULL );
  2485.  
  2486.    nResult = dlg.DoModal();
  2487.    if( nResult != IDOK )
  2488.    {
  2489.       return;
  2490.    }
  2491.  
  2492.    hResult = StgCreateDocfile( T2COLE( dlg.GetPathName() ), STGM_READWRITE|
  2493.       STGM_SHARE_EXCLUSIVE|STGM_CREATE, 0, &pStorage );
  2494.    if( FAILED( hResult ) )
  2495.    {
  2496.       return;
  2497.    }
  2498.  
  2499.    hResult = m_pSelection->SaveToStorage( pStorage );
  2500.    if( FAILED( hResult ) )
  2501.    {
  2502.       CString strErrorMessage;
  2503.       _com_error e( hResult );
  2504.  
  2505.       strErrorMessage.LoadString( IDS_SAVETOSTORAGEFAILED );
  2506.       strErrorMessage += e.ErrorMessage();
  2507.       AfxMessageBox( strErrorMessage );
  2508.       return;
  2509.    }
  2510.  
  2511.    nResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, VS_SETUP_KEY, 0, KEY_READ,
  2512.       &hKey );
  2513.    if( nResult != ERROR_SUCCESS )
  2514.    {
  2515.       return;
  2516.    }
  2517.  
  2518.    pStorage.Release();
  2519.  
  2520.    nResult = RegQueryValueEx( hKey, VS_COMMONDIR_VALUENAME, NULL, &dwType,
  2521.       NULL, &nDataLength );
  2522.    if( (nResult == ERROR_SUCCESS) && (dwType == REG_SZ) )
  2523.    {
  2524.       pszPath = strPath.GetBuffer( nDataLength/sizeof( TCHAR ) );
  2525.       nResult = RegQueryValueEx( hKey, VS_COMMONDIR_VALUENAME, NULL, &dwType,
  2526.          LPBYTE( pszPath ), &nDataLength );
  2527.       strPath.ReleaseBuffer();
  2528.       strPath += _T( "\\Tools\\DFView.exe" );
  2529.       if( (nResult == ERROR_SUCCESS) && (dwType == REG_SZ) )
  2530.       {
  2531.          memset( &startup, 0, sizeof( startup ) );
  2532.          startup.cb = sizeof( startup );
  2533.  
  2534.          memset( &process, 0, sizeof( process ) );
  2535.  
  2536.          strCommandLine.Format( "\"%s\" %s", LPCTSTR( strPath ),
  2537.             dlg.GetPathName() );
  2538.          pszCommandLine = strCommandLine.GetBuffer( 0 );
  2539.          tSuccess = CreateProcess( strPath, pszCommandLine, NULL, NULL, FALSE,
  2540.             0, NULL, NULL, &startup, &process );
  2541.          strCommandLine.ReleaseBuffer();
  2542.          if( tSuccess )
  2543.          {
  2544.             // Close the handles that CreateProcess returned so we don't leak
  2545.             // kernel resources.
  2546.             ASSERT( process.hProcess != NULL );
  2547.             CloseHandle( process.hProcess );
  2548.             ASSERT( process.hThread != NULL );
  2549.             CloseHandle( process.hThread );
  2550.          }
  2551.          else
  2552.          {
  2553.             AfxMessageBox( IDS_NODFVIEW );
  2554.          }
  2555.       }
  2556.    }
  2557.  
  2558.    RegCloseKey( hKey );
  2559. }
  2560.  
  2561. void CTestContainer98View::OnUpdateControlSaveToStorage( CCmdUI* pCmdUI )
  2562. {
  2563.    pCmdUI->Enable( m_lpSelectedItems.GetCount() == 1 );
  2564. }
  2565.  
  2566. void CTestContainer98View::OnEditInsertControlFromStorage()
  2567. {
  2568.    USES_CONVERSION;
  2569.    CTestContainer98Item* pItem;
  2570.    CTestContainer98Doc* pDoc;
  2571.    int nResult;
  2572.    IStoragePtr pStorage;
  2573.    HRESULT hResult;
  2574.    CLSID clsid;
  2575.    CString strMessage;
  2576.    CFileDialog dlg( TRUE, _T( "TSG" ), NULL, OFN_HIDEREADONLY|
  2577.       OFN_OVERWRITEPROMPT, _T( "Test Container Storage Files (*.TSG)|*.TSG||" ) );
  2578.  
  2579.    nResult = dlg.DoModal();
  2580.    if( nResult != IDOK )
  2581.    {
  2582.       return;
  2583.    }
  2584.  
  2585.    hResult = StgOpenStorage( T2COLE( dlg.GetPathName() ), NULL, STGM_READ|
  2586.       STGM_SHARE_DENY_WRITE, NULL, 0, &pStorage );
  2587.    if( FAILED( hResult ) )
  2588.    {
  2589.       _com_error error( hResult );
  2590.  
  2591.       AfxFormatString1( strMessage, IDS_OPENSTORAGEFAILED,
  2592.          error.ErrorMessage() );
  2593.       AfxMessageBox( strMessage );
  2594.       return;
  2595.    }
  2596.  
  2597.    ReadClassStg( pStorage, &clsid );
  2598.  
  2599.    pDoc = GetDocument();
  2600.  
  2601.    pItem = NULL;
  2602.    try
  2603.    {
  2604.       pItem = pDoc->AddControl( clsid, NULL, IID_IStorage, pStorage );
  2605.    }
  2606.    catch( COleException* pException )
  2607.    {
  2608.       _com_error error( pException->m_sc );
  2609.  
  2610.       pException->Delete();
  2611.  
  2612.       AfxFormatString1( strMessage, IDS_LOADCONTROLFAILED,
  2613.          error.ErrorMessage() );
  2614.  
  2615.       AfxMessageBox( strMessage );
  2616.    }
  2617.    catch( CException* pException )
  2618.    {
  2619.       _com_error error( E_FAIL );
  2620.  
  2621.       pException->Delete();
  2622.  
  2623.       AfxFormatString1( strMessage, IDS_LOADCONTROLFAILED,
  2624.          error.ErrorMessage() );
  2625.  
  2626.       AfxMessageBox( strMessage );
  2627.    }
  2628. }
  2629.  
  2630. void CTestContainer98View::OnUpdateEditSelectAll( CCmdUI* pCmdUI )
  2631. {
  2632.    CTestContainer98Doc* pDoc;
  2633.  
  2634.    pDoc = GetDocument();
  2635.    pCmdUI->Enable( pDoc->GetStartPosition() != NULL );
  2636. }
  2637.  
  2638. void CTestContainer98View::OnControlDrawMetaFile()
  2639. {
  2640.    IUnknownPtr pObject;
  2641.    CMetaFileWnd* pWnd;
  2642.    CString strWindowTitle;
  2643.  
  2644.    ASSERT( m_lpSelectedItems.GetCount() == 1 );
  2645.    ASSERT( m_pSelection != NULL );
  2646.  
  2647.    pObject = m_pSelection->m_lpObject;
  2648.  
  2649.    strWindowTitle.LoadString( IDS_METAFILEWINDOWTITLE );
  2650.     pWnd = new CMetaFileWnd;
  2651.    pWnd->Create( NULL, strWindowTitle );
  2652.    pWnd->SetObject( pObject );
  2653.    pWnd->ShowWindow( SW_SHOW );
  2654. }
  2655.  
  2656. void CTestContainer98View::OnUpdateControlDrawMetaFile( CCmdUI* pCmdUI )
  2657. {
  2658.    pCmdUI->Enable( m_lpSelectedItems.GetCount() == 1 );
  2659. }
  2660.