home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / OLEVIEW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  12.7 KB  |  570 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.6  $
  6. //
  7. // Implementation of TOleView. Doc/View view derived from TOleWindow that
  8. // supports OLE 2 using OCF TOcView & TOcRemView
  9. //----------------------------------------------------------------------------
  10. #define INC_OLE2
  11. #include <owl/pch.h>
  12. #if !defined(OWL_WINDOW_H)
  13. # include <owl/window.h>
  14. #endif
  15. #if !defined(OWL_GDIOBJEC_H)
  16. # include <owl/gdiobjec.h>
  17. #endif
  18. #if !defined(OWL_SCROLLER_H)
  19. # include <owl/scroller.h>
  20. #endif
  21. #if !defined(OWL_DOCMANAG_H)
  22. # include <owl/docmanag.h>
  23. #endif
  24. #if !defined(OWL_DOCVIEW_RH)
  25. # include <owl/docview.rh>
  26. #endif
  27. #if !defined(OWL_OLEVIEW_RH)
  28. # include <owl/oleview.rh>
  29. #endif
  30. #if !defined(OWL_OLEFRAME_H)
  31. # include <owl/oleframe.h>
  32. #endif
  33. #if !defined(OWL_OLEVIEW_H)
  34. # include <owl/oleview.h>
  35. #endif
  36. #if !defined(OWL_OLEDOC_H)
  37. # include <owl/oledoc.h>
  38. #endif
  39.  
  40. OWL_DIAGINFO;
  41.  
  42. //----------------------------------------------------------------------------
  43. // TOleView
  44. //
  45.  
  46. DEFINE_RESPONSE_TABLE1(TOleView, TOleWindow)
  47.   EV_VN_ISWINDOW,
  48.  
  49.   // Container specific messages
  50.   //
  51.   EV_VN_INVALIDATE,
  52.   EV_VN_DOCOPENED,
  53.   EV_VN_DOCCLOSED,
  54.   EV_OC_VIEWPARTINVALID,
  55.  
  56.   // Server specific messages
  57.   //
  58.   EV_OC_VIEWSAVEPART,
  59.   EV_OC_VIEWLOADPART,
  60.   EV_OC_VIEWINSMENUS,
  61.   EV_OC_VIEWCLOSE,
  62.   EV_OC_VIEWOPENDOC,
  63.   EV_OC_VIEWATTACHWINDOW,
  64.   EV_OC_VIEWSETLINK,
  65.   EV_OC_VIEWBREAKLINK,
  66.   EV_OC_VIEWGETITEMNAME,
  67. END_RESPONSE_TABLE;
  68.  
  69. //
  70. //
  71. //
  72. TOleView::TOleView(TDocument& doc, TWindow* parent)
  73. :
  74.   TView(doc),
  75.   TOleWindow(parent, doc.GetDocManager().GetApplication())
  76. {
  77.   Destroying = false;
  78.   TOleDocument* oleDoc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
  79.   CHECK(oleDoc);
  80.   OcDoc = oleDoc->GetOcDoc(); // Let OleWindow member point to it for accessor
  81. }
  82.  
  83. //
  84. //
  85. //
  86. TOleView::~TOleView()
  87. {
  88.   Destroying = true;
  89.   if (IsRemote())
  90.     Destroy();  // Make sure that derived TWindow shutdown virtuals get called
  91.   OcDoc = 0;    // We don't own it, don't let TOleWindow delete it
  92. }
  93.  
  94. //
  95. // Override TOleWindow's version to pass info to TOleDocument & provide a
  96. // second chance to find the RegLink.
  97. //
  98. TOcView*
  99. TOleView::CreateOcView(TRegLink* link, bool isRemote, IUnknown* outer)
  100. {
  101.   // Assume an embedded document until we find out later if we are a link
  102.   // or a load-from-file
  103.   //
  104.   if (isRemote)
  105.     GetDocument().SetEmbedded(true);
  106.  
  107.   return TOleWindow::CreateOcView(link ? link : GetDocument().GetTemplate(),
  108.                                   isRemote, outer);
  109. }
  110.  
  111. //
  112. // Override TView's GetViewMenu to make an on-the-fly decision about which
  113. // menu to use: normal, or embedded.
  114. //
  115. TMenuDescr*
  116. TOleView::GetViewMenu()
  117. {
  118.   if (TView::GetViewMenu())
  119.     return TView::GetViewMenu();
  120.  
  121.   if (IsRemote() && GetModule()->FindResource(IDM_OLEVIEWEMBED, RT_MENU))
  122.     SetViewMenu(new TMenuDescr(IDM_OLEVIEWEMBED, GetModule()));
  123.   else
  124.     SetViewMenu(new TMenuDescr(IDM_OLEVIEW, GetModule()));
  125.  
  126.   return TView::GetViewMenu();
  127. }
  128.  
  129. //
  130. // Does a given THandle belong to this view? Yes if it is us, or a child of us
  131. //
  132. bool
  133. TOleView::VnIsWindow(THandle hWnd)
  134. {
  135.   return hWnd == GetHandle() || IsChild(hWnd);
  136. }
  137.  
  138. //
  139. // Intercept CanClose() to interpose OpenEdit semantics
  140. // Bypasses TOleWindow in order to get Doc query involved
  141. //
  142. bool
  143. TOleView::CanClose()
  144. {
  145.   // We don't want to close the view for DLL servers
  146.   //
  147.   if (IsOpenEditing() && !OcApp->IsOptionSet(amExeMode)) {
  148.     TOleFrame* olefr = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), TOleFrame);
  149.     CHECK(olefr);
  150.     olefr->ShowWindow(SW_HIDE);
  151.     TOleWindow::OleShutDown();
  152.     return false;
  153.   }
  154.  
  155.   // Say yes if there are more than one TOleView's attached to the document
  156.   //
  157.   if (OtherViewExists() || GetOcRemView())
  158.     return true;
  159.  
  160.   if (Doc->CanClose()) {
  161.     if (OcDoc)
  162.       OcDoc->Close();
  163.     return true;
  164.   }
  165.   return false;
  166. }
  167.  
  168. //
  169. //  Check if other TOleView already exists
  170. //
  171. bool
  172. TOleView::OtherViewExists()
  173. {
  174.   TView* curView = GetDocument().GetViewList();
  175.   while (curView) {
  176.     TOleLinkView* oleLinkView = TYPESAFE_DOWNCAST(curView, TOleLinkView);
  177.     if (!oleLinkView && curView != this)
  178.       return true;
  179.  
  180.     curView = curView->GetNextView();
  181.   }
  182.  
  183.   return false;
  184. }
  185.  
  186. //
  187. // Perform normal CleanupWindow, plus let the OcView object know we have closed
  188. //
  189. void
  190. TOleView::CleanupWindow()
  191. {
  192.   if (!OtherViewExists()) {
  193.  
  194.     TOleWindow::CleanupWindow();
  195.  
  196.     // Delete the TOleView now rather wait until ~TOleFrame if its parent
  197.     // is TRemViewBucket
  198.     //
  199.     TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
  200.                                             TOleFrame);
  201.     if (mainWindow && mainWindow->GetRemViewBucket() == Parent && !Destroying)
  202.       GetApplication()->Condemn(this);
  203.   }
  204. }
  205.  
  206. //
  207. // Shut down the associated OCF partners if possible
  208. //
  209. bool
  210. TOleView::OleShutDown()
  211. {
  212.   // if dll server open edit return
  213.   if (OcApp->IsOptionSet(amExeMode) || !IsOpenEditing())
  214.       TOleWindow::OleShutDown();
  215.   else {
  216.       TOleWindow::OleShutDown();
  217.       if (OcDoc && !OtherViewExists())
  218.         OcDoc->Close();
  219.   }
  220.   return true;
  221. }
  222.  
  223.  
  224. //
  225. //  Invalidate the view region specified by rect
  226. //
  227. bool
  228. TOleView::VnInvalidate(TRect& rect)
  229. {
  230.   InvalidateRect(rect, true);
  231.  
  232.   return true;
  233. }
  234.  
  235. //
  236. //  The associated doc is opened
  237. //
  238. bool
  239. TOleView::VnDocOpened(int /*omode*/)
  240. {
  241.   DragPart = 0;
  242.   Pos.SetNull();
  243.   Scale.Reset();
  244.   return true;
  245. }
  246.  
  247. //
  248. //  The associated doc is closed
  249. //
  250. bool
  251. TOleView::VnDocClosed(int /*omode*/)
  252. {
  253.   OcDoc = 0;
  254.   return true;
  255. }
  256.  
  257. //
  258. // TOcRemView is going away, disconnect TOleWindow with it so we don't use it
  259. // later. In some cases we also need to delete the document.
  260. //
  261. bool
  262. TOleView::EvOcViewClose()
  263. {
  264.   TOcRemView* ocRemView = GetOcRemView();
  265.  
  266.   // When TOcRemView gets shut down in the Embed From File case,
  267.   // we need to cleanup the document and view right away. Otherwise,
  268.   // the document and view will be shut down as part of the frame shut down
  269.   // process.
  270.   //
  271.   if (ocRemView && ocRemView->GetKind() == TOcRemView::LoadFromFile) {
  272.     OcView = 0;   // OcView is going away, so don't mess with it
  273.     OcDoc = 0;    // OleDoc will delete OcDoc, so don't mess with it
  274.     delete &GetDocument();
  275.   }
  276.   else {
  277.     TOleWindow::EvOcViewClose();
  278.   }
  279.  
  280.   return true;
  281. }
  282.  
  283. //
  284. // Ask server to save itself in the IStorage
  285. //
  286. bool
  287. TOleView::EvOcViewSavePart(TOcSaveLoad far& ocSave)
  288. {
  289.   PRECONDITION(ocSave.StorageI);
  290.  
  291.   TOleDocument* doc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
  292.   if (!doc)
  293.     return false;
  294.  
  295.   doc->SetStorage(ocSave.StorageI, (ocSave.SameAsLoad || ocSave.Remember));
  296.  
  297.   bool status;
  298.   if (ocSave.SaveSelection) {
  299.     status = doc->CommitSelection(*this, ocSave.UserData);
  300.   }
  301.   else {
  302.     // Save view remote view info such as origin and extent
  303.     //
  304.     TOcRemView* ocRemView = GetOcRemView();
  305.     if (ocRemView)
  306.       ocRemView->Save(ocSave.StorageI);
  307.  
  308.     status = doc->Commit(true);
  309.   }
  310.  
  311.   // Restore the original storage
  312.   //
  313.   if (!ocSave.SameAsLoad && !ocSave.Remember)
  314.     doc->RestoreStorage();
  315.  
  316.   return status;
  317. }
  318.  
  319. //
  320. // Ask server to load itself from the IStorage
  321. //
  322. bool
  323. TOleView::EvOcViewLoadPart(TOcSaveLoad far& ocLoad)
  324. {
  325.   PRECONDITION(ocLoad.StorageI);
  326.  
  327.   TOleDocument* doc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
  328.   doc->SetStorage(ocLoad.StorageI);
  329.  
  330.   // Load view remote view info such as origin and extent
  331.   //
  332.   CHECK(GetOcRemView());
  333.   GetOcRemView()->Load(ocLoad.StorageI);
  334.  
  335.   bool status = GetDocument().Open(doc->GetOpenMode());
  336.  
  337.   if (!ocLoad.Remember)
  338.     doc->SetStorage(0);
  339.  
  340.   return status;
  341. }
  342.  
  343. //
  344. // Ask container to open an existing document
  345. // Used for linking from embedding
  346. //
  347. bool
  348. TOleView::EvOcViewOpenDoc(const char far* path)
  349. {
  350.   TOleDocument* oleDoc = TYPESAFE_DOWNCAST(&GetDocument(), TOleDocument);
  351.   CHECK(oleDoc && GetOcDoc());
  352.  
  353.   oleDoc->SetEmbedded(false); // must really be a link or load-from-file
  354.   oleDoc->SetStorage(0);      // release the current storage
  355.   oleDoc->SetDocPath(path);
  356.   oleDoc->InitDoc();
  357.   oleDoc->Open(ofRead, path);
  358.  
  359.   string newName(oleDoc->GetDocPath());
  360.   GetOcDoc()->SetName(newName);
  361.   Invalidate();
  362.   return true;
  363. }
  364.  
  365. //
  366. // Insert server menu into the composite one
  367. //
  368. bool
  369. TOleView::EvOcViewInsMenus(TOcMenuDescr far& sharedMenu)
  370. {
  371.   // Recreate a temporary composite menu for frame and child
  372.   //
  373.   TMenuDescr compMenuDesc; // empty menudescr
  374.   if (GetViewMenu()) {
  375.     compMenuDesc.Merge(*GetViewMenu());
  376.     compMenuDesc.Merge(TMenuDescr(0,  -1, 0, -1, 0, -1, 0));
  377.   }
  378.  
  379.   TMenuDescr shMenuDescr(sharedMenu.HMenu,
  380.                          sharedMenu.Width[0],
  381.                          sharedMenu.Width[1],
  382.                          sharedMenu.Width[2],
  383.                          sharedMenu.Width[3],
  384.                          sharedMenu.Width[4],
  385.                          sharedMenu.Width[5]);
  386.   shMenuDescr.Merge(compMenuDesc);
  387.  
  388.   for (int i = 0; i < 6; i++)
  389.     sharedMenu.Width[i] = shMenuDescr.GetGroupCount(i);
  390.  
  391.   return true;
  392. }
  393.  
  394. //
  395. // Notify the active view of part data changes
  396. //
  397. bool
  398. TOleView::EvOcViewPartInvalid(TOcPartChangeInfo& changeInfo)
  399. {
  400.   if (changeInfo.IsDataChange())
  401.     GetDocument().SetDirty(true);
  402.  
  403.   // Reflect the change in part in other (non-active) views
  404.   //
  405.   TRect rect(changeInfo.GetPart()->GetRect());
  406.   rect.right++;
  407.   rect.bottom++;
  408.   TOleClientDC dc(*this);
  409.   dc.LPtoDP((TPoint*)&rect, 2);
  410.  
  411.   GetDocument().NotifyViews(vnInvalidate, (long)&rect, 0);
  412.  
  413.   // Notify container if this is an intermediate container
  414.   //
  415.   InvalidatePart((TOcInvalidate)changeInfo.GetType());
  416.  
  417.   return true;  // stop further processing by OCF
  418. }
  419.  
  420. //
  421. // Attach this view back to its owl parent for either open editing, or
  422. // mearly inplace de-activating
  423. //
  424. bool
  425. TOleView::EvOcViewAttachWindow(bool attach)
  426. {
  427.   TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
  428.                                             TOleFrame);
  429.   if (!mainWindow)
  430.     return false;  // server app is shutting down
  431.  
  432.   // There won't be any TOcRemView if we're reestablishing the link
  433.   //
  434.   if (attach) {
  435.     if (IsOpenEditing()) {
  436.       // Get the normal app notify handler to set up the parent for us
  437.       // knowing that we are now open editing
  438.       //
  439.       if (mainWindow->GetRemViewBucket() == Parent) {
  440.         GetDocument().GetDocManager().PostEvent(dnCreate, *this);
  441.       }
  442.     }
  443.   }
  444.   else {
  445.     if (IsOpenEditing() && Parent != mainWindow)
  446.       Parent->PostMessage(WM_CLOSE);
  447.     SetParent(mainWindow->GetRemViewBucket());  // simple reparent
  448.   }
  449.   return true;
  450. }
  451.  
  452. //
  453. // Find the item name for whole doc or selection
  454. //
  455. bool
  456. TOleView::EvOcViewGetItemName(TOcItemName& item)
  457. {
  458.   if (item.Selection) {
  459.     if (DragPart) {
  460.       item.Name = DragPart->GetName();
  461.       return true;
  462.     }
  463.   }
  464.   else {
  465.     item.Name = "Content"; // item name representing the whole document
  466.     return true;
  467.   }
  468.   return false;
  469. }
  470.  
  471. //----------------------------------------------------------------------------
  472. // Linking Spport
  473. //
  474.  
  475. //
  476. // Establish link with whole doc or selection
  477. //
  478. bool
  479. TOleView::EvOcViewSetLink(TOcLinkView& /*view*/)
  480. {
  481.   return false;
  482. }
  483.  
  484. //
  485. // Break link with whole doc or selection
  486. //
  487. bool
  488. TOleView::EvOcViewBreakLink(TOcLinkView& view)
  489. {
  490.   // Find the link view with the moniker
  491.   //
  492.   TView* target = GetDocument().QueryViews(vnLinkView, (long)&view, this);
  493.  
  494.   // Delete a linked view to this document
  495.   //
  496.   delete target;
  497.   return true;
  498. }
  499.  
  500. //----------------------------------------------------------------------------
  501. // TOleLinkView
  502. //
  503.  
  504. DEFINE_RESPONSE_TABLE(TOleLinkView)
  505.   EV_VN_LINKVIEW,
  506.   EV_VN_LINKMONIKER,
  507. END_RESPONSE_TABLE;
  508.  
  509. //
  510. //
  511. //
  512. TOleLinkView::TOleLinkView(TDocument& doc, TOcLinkView& view)
  513. :
  514.   TView(doc),
  515.   OcLinkView(view)
  516. {
  517.     view.AddRef();
  518. }
  519.  
  520. //
  521. //
  522. //
  523. TOleLinkView::~TOleLinkView()
  524. {
  525.   OcLinkView.Release();
  526. }
  527.  
  528. //
  529. // See if a TOleLinkView is associated with this TOcRemView
  530. //
  531. bool
  532. TOleLinkView::VnLinkView(TOcLinkView& view)
  533. {
  534.   if (&OcLinkView == &view)
  535.     return true;
  536.  
  537.   return false;
  538. }
  539.  
  540. //
  541. // See if a TOleLinkView is associated with this TOcRemView
  542. //
  543. bool
  544. TOleLinkView::VnLinkMoniker(TString& moniker)
  545. {
  546.   if ((char*)OcLinkView.GetMoniker() == (char*)moniker)
  547.     return true;
  548.  
  549.   return false;
  550. }
  551.  
  552. //
  553. // Update all links to this view
  554. //
  555. bool
  556. TOleLinkView::UpdateLinks()
  557. {
  558.   OcLinkView.Invalidate(invView);
  559.   return true;
  560. }
  561.  
  562. //
  563. // Get the moniker corresponding to this view
  564. //
  565. TString&
  566. TOleLinkView::GetMoniker()
  567. {
  568.   return OcLinkView.GetMoniker();
  569. }
  570.