home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / OLEVIEW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  12.2 KB  |  534 lines

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