home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OCFSRC.PAK / OCREMVIE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-29  |  25.4 KB  |  1,047 lines

  1. //
  2. //----------------------------------------------------------------------------
  3. // ObjectComponents
  4. // (C) Copyright 1994 by Borland International, All Rights Reserved
  5. //
  6. //   Implementation of TOcRemView Class
  7. //----------------------------------------------------------------------------
  8. #include <ocf/ocfpch.h>
  9. #include <ocf/ocremvie.h>
  10. #include <ocf/ocapp.h>
  11. #include <ocf/ocstorag.h>
  12.  
  13. DIAG_DEFINE_GROUP(OcRemView, true, 2);
  14. DIAG_DECLARE_GROUP(OcRefCount);
  15.  
  16. const char  RemViewStreamName[] = "OcRemoteView";
  17.  
  18. TOcRemView::TOcRemView(TOcDocument& doc, TRegList* regList, IUnknown* outer)
  19. :
  20.   BSiteI(0), BContainerI(0), BLSiteI(0),
  21.   State(Hidden),
  22.   Kind(DontKnow),
  23.   TOcView(doc, regList, outer)
  24. {
  25.   // Create a site for this remote view
  26.   //
  27.   if (SUCCEEDED(OcApp.BOleComponentCreate(&BSite, (IUnknown*)(IBContainer*)this,
  28.       OcApp.IsOptionSet(amExeModule)? cidBOleSite : cidBOleInProcSite))) {
  29.  
  30.     if (SUCCEEDED(BSite->QueryInterface(IID_IBSite, &(LPVOID)BSiteI)))
  31.       Release();
  32.  
  33.     // Connect the part and the site
  34.     //
  35.     if (BSiteI) {
  36.       const char* progid = regList->Lookup(OcApp.IsOptionSet(amDebug) ?
  37.                                            "debugprogid" : "progid");
  38.       BSiteI->Init((IBDataProvider2*)this, this, OleStr(progid), true);
  39.     }
  40.  
  41.     if (SUCCEEDED(BSite->QueryInterface(IID_IBContainer, &(LPVOID)BContainerI)))
  42.       Release();
  43.  
  44.     if (SUCCEEDED(BSite->QueryInterface(IID_IBLinkable,&(LPVOID)BLSiteI)))
  45.       BLSiteI->Release();   // avoid deadlock
  46.  
  47.     if (SUCCEEDED(BSite->QueryInterface(IID_IBApplication, &(LPVOID)BAppI)))
  48.       BAppI->Release();     // avoid deadlock
  49.   }
  50.   TRACEX(OcRefCount, 1, "TOcRemView() @" << (void*)this);
  51. }
  52.  
  53. TOcRemView::~TOcRemView()
  54. {
  55.   // Make sure running object is unregistered
  56.   //
  57.   if (Kind == LoadFromFile && State != Closing)
  58.     EvClose();
  59.  
  60.   // Disconnect the TOleView with this
  61.   //
  62.   ForwardEvent(OC_VIEWCLOSE);
  63.  
  64.   // Release all helpers, but first call base class to release helpers
  65.   // BEFORE BSite is released
  66.   //
  67.   Shutdown();
  68.  
  69.   if (BSite) {
  70.     BSite->Release(); // Causes OcAppShutDown if last TOcRemView
  71.     BSite = 0;
  72.   }
  73. }
  74.  
  75. //
  76. // Should only be called by the owner/creator of this object
  77. //
  78. void
  79. TOcRemView::ReleaseObject()
  80. {
  81.   AddRef();   // cancel release, view holds a pointer but not a ref count
  82.   TOcView::ReleaseObject();
  83. }
  84.  
  85. //
  86. //
  87. //
  88. HRESULT
  89. TOcRemView::QueryObject(const IID far& iid, void far* far* iface)
  90. {
  91.   PRECONDITION(iface);
  92.   HRESULT hr;
  93.  
  94.   // interfaces
  95.   //
  96.      SUCCEEDED(hr = IBPart2_QueryInterface(this, iid, iface))
  97.   || SUCCEEDED(hr = IBDataProvider2_QueryInterface(this, iid, iface))
  98.  
  99.   // helpers
  100.   //
  101.   || (BSite && SUCCEEDED(hr = BSite->QueryInterface(iid, iface)))
  102.  
  103.   // base classes
  104.   //
  105.   || SUCCEEDED(hr = TOcView::QueryObject(iid, iface))
  106.   ;
  107.  
  108.   return hr;
  109. }
  110.  
  111.  
  112. ulong _IFUNC
  113. TOcRemView::AddRef()
  114. {
  115.   return GetOuter()->AddRef();
  116. }
  117.  
  118. ulong _IFUNC
  119. TOcRemView::Release()
  120. {
  121.   return GetOuter()->Release();
  122. }
  123.  
  124. HRESULT _IFUNC
  125. TOcRemView::QueryInterface(const GUID far& iid, void far*far* iface)
  126. {
  127.   return GetOuter()->QueryInterface(iid, iface);
  128. }
  129.  
  130. //----------------------------------------------------------------------------
  131. // IBDropDest forwarding to base
  132. //
  133. void _IFUNC
  134. TOcRemView::DragFeedback(TPoint far* p, const TRect far* r, TOcMouseAction a,
  135.                          uint cf, HRESULT& hr)
  136. {
  137.   TOcView::DragFeedback(p, r, a, cf, hr);
  138. }
  139.  
  140. //----------------------------------------------------------------------------
  141. // IBContainer override
  142. //
  143.  
  144. //
  145. // Check option flag to see if in place activation is allowed
  146. //
  147. HRESULT _IFUNC
  148. TOcRemView::AllowInPlace()
  149. {
  150.   if (IsOptionSet(voNoInPlace))
  151.     return HR_FALSE;
  152.   else if (IsOptionSet(voNoNestedInPlace) && State != OpenEditing)
  153.     return HR_FALSE;
  154.   else
  155.     return HR_NOERROR;
  156. }
  157.  
  158. //----------------------------------------------------------------------------
  159. // IBSite pass-thrus
  160.  
  161. //
  162. // Invalidate the site within the active view
  163. //
  164. void
  165. TOcRemView::Invalidate(TOcInvalidate invalid)
  166. {
  167.   if (BSiteI)
  168.     BSiteI->Invalidate(invalid);
  169. }
  170.  
  171. //
  172. // Disconnect from the client site
  173. //
  174. void
  175. TOcRemView::Disconnect()
  176. {
  177.   TRACEX(OcRemView, 1, "Disconnect() on " << (void*)this);
  178.  
  179.   if (BSiteI)
  180.     BSiteI->Disconnect();
  181. }
  182.  
  183. //
  184. // set focus to the inplace server
  185. //
  186. bool
  187. TOcRemView::EvSetFocus(bool set)
  188. {
  189.   BSiteI->OnSetFocus(set);
  190.   return TOcView::EvSetFocus(set);
  191. }
  192.  
  193.  
  194. //----------------------------------------------------------------------------
  195. // IBDocument pass-thrus
  196.  
  197. void
  198. TOcRemView::EvClose()
  199. {
  200.   TRACEX(OcRemView, 1, "EvClose() on " << (void*)this);
  201.  
  202.   if (BSite && BLSiteI)
  203.     BLSiteI->OnRename(0, 0);
  204.  
  205.   OcDocument.Close();  // Disconnect from the parts, if any
  206.   TOcView::EvClose();
  207. }
  208.  
  209. //
  210. // Update monikers with new name
  211. //
  212. void
  213. TOcRemView::Rename()
  214. {
  215.   PRECONDITION(BLSiteI);
  216.  
  217.   TOcView::Rename();
  218.  
  219.   // Update the part's moniker
  220.   //
  221. //  BLSiteI->OnRename(BLDocumentI, OleStr(DefaultStreamName));
  222. }
  223.  
  224. //
  225. // Get the window text of the container
  226. //
  227. TString
  228. TOcRemView::GetContainerTitle()
  229. {
  230.   if (BContainerI)
  231.     return BContainerI->GetWindowTitle();
  232.   return "";
  233. }
  234.  
  235. //
  236. //  Get the initial size and position from the app
  237. //
  238. void
  239. TOcRemView::GetInitialRect(bool selection)
  240. {
  241.   TOcPartSize ps(selection);
  242.  
  243.   // See if the container has already provided a site size, & if so provide it
  244.   // as a default size to the server object.
  245.   //
  246.   bool haveSite = false;
  247.   if (BSiteI)
  248.     haveSite = SUCCEEDED(BSiteI->GetSiteRect(&ps.PartRect, 0)) && !ps.PartRect.IsEmpty();
  249.  
  250.   // Let the server app provide an initial server extent if it wants to.
  251.   //
  252.   if (!ForwardEvent(OC_VIEWPARTSIZE, &ps)) {
  253.  
  254.     // The server has not requested a specific size. If the container has
  255.     // already provided a site size, use it. Otherwise pick an arbitrary
  256.     // non-zero size.
  257.     //
  258.     if (!haveSite) {
  259.       HDC dc = ::GetDC(0);
  260.  
  261.       // a 3" x 2" extent for server
  262.       //
  263.       ps.PartRect = TRect(0, 0,
  264.                           ::GetDeviceCaps(dc, LOGPIXELSX)*3,
  265.                           ::GetDeviceCaps(dc, LOGPIXELSY)*2);
  266.       ReleaseDC(0, dc);
  267.     }
  268.   }
  269.   Extent = ps.PartRect.Size();
  270.   Origin = ps.PartRect.TopLeft();
  271. }
  272.  
  273. //
  274. // Save remote view specific information to compound file
  275. //
  276. bool
  277. TOcRemView::Save(IStorage* storageI)
  278. {
  279.   TOcStorage Storage(storageI);
  280.  
  281.   // Create/open a stream in our storage to save part information
  282.   //
  283.   STATSTG  statstg;
  284.   if (!SUCCEEDED(Storage.Stat(&statstg, STATFLAG_NONAME)))
  285.     return false;
  286.  
  287.   TOcStream  stream(Storage, ::RemViewStreamName, true, statstg.grfMode);
  288.  
  289.   // Write TOcRemView data into stream
  290.   //
  291.   ulong count;
  292.   if (!SUCCEEDED(stream.Write(&Origin, sizeof(TPoint), &count)))
  293.     return false;
  294.  
  295.   if (!SUCCEEDED(stream.Write(&Extent, sizeof(TSize), &count)))
  296.     return false;
  297.  
  298.   return true;
  299. }
  300.  
  301. //
  302. // Load remote view specific information
  303. //
  304. bool
  305. TOcRemView::Load(IStorage* storageI)
  306. {
  307.   TOcStorage Storage(storageI);
  308.  
  309.   // Open a stream with oc part information
  310.   //
  311.   STATSTG statstg;
  312.   if (!HRSucceeded(Storage.Stat(&statstg, STATFLAG_NONAME)))
  313.     return false;
  314.  
  315.   try {
  316.     TOcStream  stream(Storage, ::RemViewStreamName, false, statstg.grfMode);
  317.  
  318.     // Read TOcPart data from stream. Server part info will be read in as
  319.     // needed after Init()
  320.     //
  321.     ulong count;
  322.     if (!HRSucceeded(stream.Read(&Origin, sizeof(TPoint), &count)))
  323.       return false;
  324.  
  325.     if (!HRSucceeded(stream.Read(&Extent, sizeof(TSize), &count)))
  326.       return false;
  327.   }
  328.   catch (TXObjComp&) {
  329.     // There is no remote view related info saved.
  330.     // This happens when saving the document while running as a stand alone
  331.     // app. But subsequently, a embed from file is executed.
  332.   }
  333.  
  334.   return true;
  335. }
  336.  
  337. //----------------------------------------------------------------------------
  338. // IBContains
  339.  
  340. //
  341. // This is called when we want to create a part from data saved
  342. // in the storage named "path"
  343. //
  344. HRESULT _IFUNC
  345. TOcRemView::Init(LPCOLESTR path)
  346. {
  347.   PRECONDITION(path);
  348.  
  349.   GetInitialRect();
  350.  
  351.   // Assume for now that we are created to load our object from a file. Kind
  352.   // will get changed later to Link if we are asked to Open()
  353.   //
  354.   Kind = LoadFromFile;
  355.  
  356.   // Read object's data from storage
  357.   //
  358.   if (!ForwardEvent(OC_VIEWOPENDOC, (const char far*)OleStr(path)))
  359.     return HR_FAIL;
  360.  
  361.   // Pretend we are open editing to make sure that the doc server is attached
  362.   // to a child window in case this is a link.
  363.   //
  364.   State = OpenEditing;
  365.   ForwardEvent(OC_VIEWATTACHWINDOW, true);
  366.  
  367.   // If embed from file, we had to call BDocumentI->Init() to initialize
  368.   // IBApplication, but we do not want to register the drop target, therefore,
  369.   // we use a 0 for the window handle.
  370.   //
  371.   HWND oldWin = Win;
  372.   Win = 0;
  373.   BDocumentI->Init(this);
  374.   Win = oldWin;
  375.  
  376.   // Register this document in running object table
  377.   //
  378.   OcDocument.SetName(string(OleStr(path)));
  379.   return HR_NOERROR;
  380. }
  381.  
  382. HRESULT _IFUNC
  383. TOcRemView::GetPart(IBPart far* far* parti, LPCOLESTR moniker)
  384. {
  385.   if (Kind == LoadFromFile)
  386.     Kind = Link;          // must be a link, not a transient load
  387.  
  388.   return TOcView::GetPart(parti, moniker);
  389. }
  390.  
  391. //----------------------------------------------------------------------------
  392. // IBContainer implementation
  393.  
  394. //
  395. // Show the container window
  396. //
  397. HRESULT _IFUNC
  398. TOcRemView::BringToFront()
  399. {
  400.   TOcView::BringToFront();
  401.   return HR_NOERROR;
  402. }
  403.  
  404. //----------------------------------------------------------------------------
  405. // IDataNegotiator implementation
  406.  
  407. uint _IFUNC
  408. TOcRemView::CountFormats()
  409. {
  410.   return TOcView::CountFormats();
  411. }
  412.  
  413. HRESULT _IFUNC
  414. TOcRemView::GetFormat(uint index, TOcFormatInfo far* fmt)
  415. {
  416.   PRECONDITION(fmt);
  417.  
  418.   return TOcView::GetFormat(index, fmt);
  419. }
  420.  
  421.  
  422. //----------------------------------------------------------------------------
  423. // IBDataNegotiator implementation
  424.  
  425. //
  426. // Request native data for pasting into client application.
  427. // This is only called at paste time (not at copy time).
  428. //
  429. HANDLE _IFUNC
  430. TOcRemView::GetFormatData(TOcFormatInfo far* fmt)
  431. {
  432.   PRECONDITION(fmt);
  433.  
  434.   TOcFormat* format = FormatList.Find(fmt->Id);
  435.   if (!format)
  436.     return 0;
  437.  
  438.   TOcFormatData formatData(*format);
  439.   if (ForwardEvent(OC_VIEWCLIPDATA, &formatData))
  440.     return formatData.Handle;
  441.   else
  442.     return 0;
  443. }
  444.  
  445. //
  446. // Request native data for pasting into client application.
  447. // This is only called at paste time (not at copy time).
  448. //
  449. HRESULT _IFUNC
  450. TOcRemView::SetFormatData(TOcFormatInfo far* fmt, HANDLE data, bool /*release*/)
  451. {
  452.   PRECONDITION(fmt);
  453.   PRECONDITION(data);
  454.  
  455.   TOcFormat* format = FormatList.Find(fmt->Id);
  456.   if (!format)
  457.     return 0;
  458.  
  459.   TOcFormatData formatData(*format, 0, data);
  460.   return HRFailIfZero((bool)(ForwardEvent(OC_VIEWSETDATA, &formatData)));
  461. }
  462.  
  463. #if defined(BI_PLAT_WIN16)
  464.   extern "C" HRGN FAR PASCAL ::GetClipRgn(HDC);  // GDI.173
  465. #endif
  466.  
  467. //
  468. // Render the view in the DC provided. May be a MetaFile
  469. // Packup all the args & forward message to real view to paint
  470. //
  471. HRESULT _IFUNC
  472. TOcRemView::Draw(HDC dc, const RECTL far*  pos, const RECTL far* clip,
  473.                  TOcAspect aspect, TOcDraw bd)
  474. {
  475.   PRECONDITION(dc);
  476.   bool metafile = ::GetDeviceCaps(dc, TECHNOLOGY) == DT_METAFILE;
  477.  
  478.   // Rely on the BOle shading
  479.   //
  480.   if (bd == drShadingOnly)
  481.     return HR_NOERROR;
  482.  
  483.   TRect p((int)pos->left, (int)pos->top, (int)pos->right, (int)pos->bottom);
  484.   TRect c((int)clip->left, (int)clip->top, (int)clip->right, (int)clip->bottom);
  485.  
  486.   TPoint oldViewOrg;
  487.   TPoint oldWinOrg;
  488.   TSize  oldViewExt;
  489.   TSize  oldWinExt;
  490.   int    oldMapMode;
  491.   HRGN   hRgn;
  492.  
  493.   if (metafile) {
  494.     p.SetEmpty();
  495.     ::SetMapMode(dc, MM_ANISOTROPIC);
  496.  
  497.     ::SetWindowExtEx(dc, Extent.cx, Extent.cy, 0);
  498.     ::SetWindowOrgEx(dc, 0, 0, 0);
  499.   }
  500.   else if (!OcApp.IsOptionSet(amExeModule)) {
  501.     if (p.Width() != Extent.cx || p.Height() != Extent.cy) {
  502.       TOcScaleFactor scaleFactor(p, Extent);
  503.       ForwardEvent(OC_VIEWSETSCALE, &scaleFactor);
  504.     }
  505. #if defined(BI_PLAT_WIN16)
  506.     hRgn = ::GetClipRgn(dc);
  507. #else
  508.     hRgn = ::CreateRectRgn(0, 0, 0, 0);
  509.     ::GetClipRgn(dc, hRgn);
  510. #endif
  511.     ::LPtoDP(dc, (TPoint*)&p, 2);
  512.     ::LPtoDP(dc, (TPoint*)&c, 2);
  513.     ::IntersectClipRect(dc, c.left, c.top, c.right, c.bottom);
  514.  
  515.     ::SetViewportOrgEx(dc, p.left, p.top, &oldViewOrg);
  516.     ::GetWindowOrgEx(dc, &oldWinOrg);
  517.     ::GetWindowExtEx(dc, &oldWinExt);
  518.     ::GetViewportExtEx(dc, &oldViewExt);
  519.     oldMapMode  = ::GetMapMode(dc);
  520.   }
  521.  
  522.   p.Normalize();
  523.   c.Normalize();
  524.  
  525.   TOcViewPaint vp = { dc, &p, &c, (TOcAspect)aspect, false, 0, 0 };
  526.   bool result = (bool)ForwardEvent(OC_VIEWPAINT, &vp);
  527.  
  528.   // Restore the dc attributes
  529.   //
  530.   if (!metafile && !OcApp.IsOptionSet(amExeModule)) {
  531.     ::SetMapMode(dc, oldMapMode);
  532.     ::SetViewportOrgEx(dc, oldViewOrg.x, oldViewOrg.y, 0);
  533.     ::SetWindowOrgEx(dc, oldWinOrg.x, oldWinOrg.y, 0);
  534.     ::SetViewportExtEx(dc, oldViewExt.cx, oldViewExt.cy, 0);
  535.     ::SetWindowExtEx(dc, oldWinExt.cx, oldWinExt.cy, 0);
  536.     ::SelectClipRgn(dc, hRgn);
  537. #if !defined(BI_PLAT_WIN16)
  538.     ::DeleteObject(hRgn);
  539. #endif
  540.   }
  541.  
  542.   return HRFailIfZero(result);
  543. }
  544.  
  545. //
  546. // Return the 'size' of the document that this view in on
  547. //
  548. HRESULT _IFUNC
  549. TOcRemView::GetPartSize(TSize far* size)
  550. {
  551.   *size = Extent;
  552.   return HR_NOERROR;
  553. }
  554.  
  555. //
  556. // Save the document that we are a view on
  557. //
  558. HRESULT _IFUNC
  559. TOcRemView::Save(IStorage* storage, BOOL sameAsLoad, BOOL remember)
  560. {
  561.   PRECONDITION(storage);
  562.  
  563.   TOcSaveLoad ocSave(storage, ToBool(sameAsLoad), ToBool(remember));
  564.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWSAVEPART, &ocSave));
  565. }
  566.  
  567. //----------------------------------------------------------------------------
  568. // IBPart implementation
  569.  
  570. //
  571. // Load the associated document and activate the remote view
  572. //
  573. HRESULT _IFUNC
  574. TOcRemView::Init(IBSite far*, TOcInitInfo far* initInfo)
  575. {
  576.   PRECONDITION(initInfo);
  577.  
  578.   // Now we know that we are a normal embedding
  579.   //
  580.   Kind = Embedding;
  581.  
  582.   // If existing document, notify the app to read it in.
  583.   //
  584.   if (initInfo->Where == iwStorage) {
  585.     TOcSaveLoad ocLoad(initInfo->Storage, true, true);
  586.     if (!ForwardEvent(OC_VIEWLOADPART, &ocLoad))
  587.       return HR_FAIL;
  588.   }
  589.   else if (initInfo->Where == iwNew)
  590.     GetInitialRect();
  591.  
  592.   // Show & activate this embedded object
  593.   //
  594.   Show(true);
  595.   Activate(true);
  596.  
  597.   return HR_OK;
  598. }
  599.  
  600. //
  601. // Close the remote view window, & if canShutDown is true, try to close the
  602. // server app too
  603. //
  604. HRESULT _IFUNC
  605. TOcRemView::Close()
  606. {
  607.   TRACEX(OcRemView, 1, "Close() on " << (void*)this <<
  608.          " Closing:" << (State==Closing) << " Win:" << hex << (uint)Win);
  609.  
  610.   // Keep DLL server in memory until its ref count goes to 0
  611.   //
  612.   if (State != Closing && OcApp.IsOptionSet(amExeMode)) {
  613.     EvClose();
  614.   }
  615.  
  616.   // Remember that we are closing so that we don't do Close() again
  617.   //
  618.   State = Closing;
  619.  
  620.   return HR_NOERROR;
  621. }
  622.  
  623. //
  624. // Query to determine if this server view can open in place
  625. //
  626. HRESULT _IFUNC
  627. TOcRemView::CanOpenInPlace()
  628. {
  629.   if (IsOptionSet(voNoInPlaceServer))
  630.     return HR_FALSE;    // Force server to open edit
  631.   else
  632.     return HR_NOERROR;  // allow in place activation
  633. }
  634.  
  635. //
  636. // Set a new position for our document within its container
  637. //
  638. HRESULT _IFUNC
  639. TOcRemView::SetPartPos(TRect far* r)
  640. {
  641.   Origin = *(POINT*)&r->left;
  642.  
  643.   TOcScaleInfo scale;
  644.   CHECK(BSiteI);
  645.   BSiteI->GetZoom(&scale);
  646.   TOcScaleFactor scaleFactor(scale);
  647.  
  648.   // No scaling
  649.   //
  650.   if (scale.xN == 1 && scale.yN == 1) {
  651.     scaleFactor.SiteSize.cx = scaleFactor.PartSize.cx = r->right - r->left;
  652.     scaleFactor.SiteSize.cy = scaleFactor.PartSize.cy = r->bottom - r->top;
  653.   }
  654.  
  655.   ::MoveWindow(GetWindow(), r->left, r->top,
  656.                scaleFactor.SiteSize.cx, scaleFactor.SiteSize.cy, true);
  657.  
  658.   ForwardEvent(OC_VIEWSETSCALE, &scaleFactor);
  659.  
  660.   return HR_NOERROR;
  661. }
  662.  
  663. HRESULT _IFUNC
  664. TOcRemView::SetPartSize(TSize far* size)
  665. {
  666.   Extent = *size;
  667.   return HR_NOERROR;
  668. }
  669.  
  670. //
  671. // Activate this view
  672. //
  673. HRESULT _IFUNC
  674. TOcRemView::Activate(bool activate)
  675. {
  676.   if (activate && GetWindow())
  677.     ::SetFocus(GetWindow());
  678.   return HR_NOERROR;
  679. }
  680.  
  681. //
  682. // Show/Hide the server view window
  683. //
  684. HRESULT _IFUNC
  685. TOcRemView::Show(bool show)
  686. {
  687.   if (GetWindow())
  688.     ::ShowWindow(GetWindow(), show ? SW_SHOW : SW_HIDE);
  689.   return HR_NOERROR;
  690. }
  691.  
  692. //
  693. // Start or end open editing
  694. // Work with the window Z-order and parenting
  695. //
  696. HRESULT _IFUNC
  697. TOcRemView::Open(bool open)
  698. {
  699.   if (open) {
  700.     // Just show the window, if it's already active
  701.     //
  702.     if (State == InPlaceActive) {
  703.       HWND contWin = BAppI->GetWindow();
  704.       ::BringWindowToTop(contWin);
  705.     }
  706.     else {
  707.       State = OpenEditing;    // we now transition into open edit state
  708.       if (Kind == LoadFromFile)
  709.         Kind = Link;          // must be a link, not a transient load
  710.  
  711.       // Register drag&drop target
  712.       //
  713.       BDocumentI->Init(this);
  714.  
  715.       // Forward event to app to let it attach the window to an appropriate
  716.       // frame
  717.       //
  718.       ForwardEvent(OC_VIEWATTACHWINDOW, true);
  719.       BringToFront();
  720.  
  721.       // Build up open edit caption in the form "<menuname> in <containername>"
  722.       //
  723.       if (RegList) {
  724.         string newTitle = (*RegList)["menuname"];
  725.         char in[32];
  726.         ::LoadString(_hInstance, IDS_IN, in, sizeof in);
  727.         newTitle += in;
  728.         LPCOLESTR str = BContainerI->GetWindowTitle();
  729.         if (str)
  730.           newTitle += OleStr(str);
  731.         ForwardEvent(OC_VIEWSETTITLE, newTitle.c_str());
  732.       }
  733.     }
  734.   }
  735.   else {
  736.     // Unregister drag&drop target
  737.     //
  738.     BDocumentI->OnClose();
  739.  
  740.     // Reparent back to the real parent
  741.     //
  742.     ForwardEvent(OC_VIEWATTACHWINDOW, (uint32)false);
  743.   }
  744.   return HR_NOERROR;
  745. }
  746.  
  747. //
  748. // Enumerate the verbs for our document
  749. //
  750. HRESULT _IFUNC
  751. TOcRemView::EnumVerbs(TOcVerb far*)
  752. {
  753.   return HR_FAIL;  // Not called on BOle parts
  754. }
  755.  
  756. //
  757. // Perform a verb on our document
  758. //
  759. HRESULT _IFUNC
  760. TOcRemView::DoVerb(uint verb)
  761. {
  762.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWDOVERB, verb));
  763. }
  764.  
  765. //
  766. // Open or close this view as an in-place edit session. If hWndParent is 0,
  767. // then in-place is closing
  768. //
  769. HWND _IFUNC
  770. TOcRemView::OpenInPlace(HWND hWndParent)
  771. {
  772.   if (hWndParent) {
  773.     State = InPlaceActive;  // transition into in-place-active state
  774.  
  775.     // Register drag&drop target
  776.     //
  777.     BDocumentI->Init(this);
  778.  
  779.     ::SetParent(GetWindow(), hWndParent);
  780.   }
  781.   else {
  782.     State = Hidden;  // transition back into normal, hidden state
  783.     BDocumentI->OnClose();
  784.  
  785.     // Deactivate in-place active object, if any
  786.     //
  787.     if (ActivePart)
  788.       ActivePart->Activate(false);
  789.  
  790.     // Set back to real parent and don't show it
  791.     //
  792.     if (!ForwardEvent(OC_VIEWATTACHWINDOW, (uint32)false)) {
  793.       Show(false);
  794.       ::SetParent(GetWindow(), OcApp.GetWindow());
  795.     }
  796.   }
  797.   return GetWindow();
  798. }
  799.  
  800. //
  801. // Insert the server's menus into the shared menubar
  802. //
  803. HRESULT _IFUNC
  804. TOcRemView::InsertMenus(HMENU hMenu, TOcMenuWidths far* omw)
  805. {
  806.   PRECONDITION(omw && hMenu);
  807.  
  808.   TOcMenuDescr md;
  809.   md.HMenu = hMenu;
  810.   for (int i = 0; i < 6; i++) {
  811.     md.Width[i] = (int)omw->Width[i];
  812.     i++;
  813.     md.Width[i] = 0;  // make sure the server's are zeroed
  814.     omw->Width[i] = 0;
  815.   }
  816.  
  817.   if (!(bool)ForwardEvent(OC_VIEWINSMENUS, &md))
  818.     return HR_FAIL;
  819.  
  820.   for (i = 0; i < 6; i++)
  821.     omw->Width[i] = md.Width[i];
  822.  
  823.   return HR_NOERROR;
  824. }
  825.  
  826. //
  827. // Retrieve rectangle info about the toolbars
  828. //
  829. static void
  830. sGetTBRects(TOcToolBarInfo far& tbi,
  831.             TRect& ttbr, TRect& ltbr, TRect& btbr, TRect& rtbr, TRect& border)
  832. {
  833.   if (tbi.HLeftTB)
  834.     ::GetWindowRect(tbi.HLeftTB, <br);
  835.   else
  836.     ltbr.Set(0,0,0,0);
  837.   if (tbi.HTopTB)
  838.     ::GetWindowRect(tbi.HTopTB, &ttbr);
  839.   else
  840.     ttbr.Set(0,0,0,0);
  841.   if (tbi.HRightTB)
  842.     ::GetWindowRect(tbi.HRightTB, &rtbr);
  843.   else
  844.     rtbr.Set(0,0,0,0);
  845.   if (tbi.HBottomTB)
  846.     ::GetWindowRect(tbi.HBottomTB, &btbr);
  847.   else
  848.     btbr.Set(0,0,0,0);
  849.   border.Set(ltbr.Width() ? ltbr.Width()-1 : 0,
  850.              ttbr.Height() ? ttbr.Height()-1 : 0,
  851.              rtbr.Width() ? rtbr.Width()-1 : 0,
  852.              btbr.Height() ? btbr.Height()-1 : 0);
  853. }
  854.  
  855. //
  856. // Actually parent & position the toolbars in the container frame.
  857. // Assume all the toolbars have WS_BORDER style & overlaps accordingly
  858. //
  859. static void
  860. sAdjustTBPos(TOcToolBarInfo far& tbi, const TRect& contFrameR, bool setParent,
  861.              const TRect& ttbr, const TRect& ltbr,
  862.              const TRect& btbr, const TRect& rtbr,
  863.              const TRect& border)
  864. {
  865.   if (tbi.HLeftTB) {
  866.     ::MoveWindow(tbi.HLeftTB, -1, -1+border.top, ltbr.Width(),
  867.                  contFrameR.Height()+2-border.top-border.bottom, true);
  868.     if (setParent) {
  869.       ::SetParent(tbi.HLeftTB, tbi.HFrame);
  870.       ::ShowWindow(tbi.HLeftTB, SW_NORMAL);
  871.     }
  872.   }
  873.   if (tbi.HTopTB) {
  874.     ::MoveWindow(tbi.HTopTB, -1, -1, contFrameR.Width()+2, ttbr.Height(),
  875.                  true);
  876.     if (setParent) {
  877.       ::SetParent(tbi.HTopTB, tbi.HFrame);
  878.       ::ShowWindow(tbi.HTopTB, SW_NORMAL);
  879.     }
  880.   }
  881.   if (tbi.HRightTB) {
  882.     ::MoveWindow(tbi.HRightTB, contFrameR.right-rtbr.Width()+1, -1+border.top,
  883.                  rtbr.Width(), contFrameR.Height()+2-border.top-border.bottom,
  884.                  true);
  885.     if (setParent) {
  886.       ::SetParent(tbi.HRightTB, tbi.HFrame);
  887.       ::ShowWindow(tbi.HRightTB, SW_NORMAL);
  888.     }
  889.   }
  890.   if (tbi.HBottomTB) {
  891.     ::MoveWindow(tbi.HBottomTB, -1, contFrameR.bottom-btbr.Height()+1,
  892.                  contFrameR.Width()+2, btbr.Height(), true);
  893.     if (setParent) {
  894.       ::SetParent(tbi.HBottomTB, tbi.HFrame);
  895.       ::ShowWindow(tbi.HBottomTB, SW_NORMAL);
  896.     }
  897.   }
  898. }
  899.  
  900. //
  901. // Show or hide the tool windows used by our view
  902. //
  903. HRESULT _IFUNC
  904. TOcRemView::ShowTools(bool show)
  905. {
  906.   TOcToolBarInfo far& tbi = ToolBarInfo;
  907.   tbi.Show = show;
  908.   tbi.HTopTB = tbi.HLeftTB = tbi.HBottomTB = tbi.HRightTB = 0;
  909.   if (show)
  910.     tbi.HFrame = BAppI->GetWindow();  // Container's frame
  911.   else
  912.     tbi.HFrame = OcApp.GetWindow();   // This server's frame
  913.  
  914.   // Let the view create/destroy its toolbars & fill them in for us to work
  915.   // with. View may also change the HFrame for special purposes
  916.   //
  917.   if (!ForwardEvent(OC_VIEWSHOWTOOLS, &tbi))
  918.     return HR_FAIL;
  919.  
  920.   // Assist view in showing toobars by negotiating, parenting to the container
  921.   // frame & showing the provided toolbars
  922.   //
  923.   if (show) {
  924.     TRect ltbr;
  925.     TRect ttbr;
  926.     TRect rtbr;
  927.     TRect btbr;
  928.     TRect border;
  929.     sGetTBRects(tbi, ltbr, ttbr, rtbr, btbr, border);
  930.  
  931.     // Request the desired border space from the container. Scale back requests
  932.     // as needed if container denies requests.
  933.     //
  934.     for (int i = 0; i < 3; i++) {
  935.       if (!SUCCEEDED(BAppI->RequestBorderSpace(&border))) {
  936.         switch (i) {
  937.           case 0:
  938.             border.bottom = 0;
  939.             tbi.HBottomTB = 0;
  940.             break;
  941.           case 1:
  942.             border.right = 0;
  943.             tbi.HRightTB = 0;
  944.             break;
  945.           case 2:
  946.             border.left = 0;
  947.             tbi.HLeftTB = 0;
  948.         }
  949.       }
  950.       else
  951.         break;
  952.     }
  953.     if (i == 3 || !SUCCEEDED(BAppI->SetBorderSpace(&border)))
  954.       return HR_FAIL;  // don't know why it failed. Give up
  955.  
  956.     TRect contFrameR;
  957.     BAppI->GetWindowRect(&contFrameR);
  958.     sAdjustTBPos(tbi, contFrameR, true, ltbr, ttbr, rtbr, btbr, border);
  959.   }
  960.   // Assist view in hiding toobars by reparenting them to frame (defaults to
  961.   // this server) & hiding them
  962.   //
  963.   else {
  964.     if (tbi.HLeftTB) {
  965.       ::SetParent(tbi.HLeftTB, tbi.HFrame);
  966.       ::ShowWindow(tbi.HLeftTB, SW_HIDE);
  967.     }
  968.     if (tbi.HTopTB) {
  969.       ::SetParent(tbi.HTopTB, tbi.HFrame);
  970.       ::ShowWindow(tbi.HTopTB, SW_HIDE);
  971.     }
  972.     if (tbi.HRightTB) {
  973.       ::SetParent(tbi.HRightTB, tbi.HFrame);
  974.       ::ShowWindow(tbi.HRightTB, SW_HIDE);
  975.     }
  976.     if (tbi.HBottomTB) {
  977.       ::SetParent(tbi.HBottomTB, tbi.HFrame);
  978.       ::ShowWindow(tbi.HBottomTB, SW_HIDE);
  979.     }
  980.   }
  981.   return HR_NOERROR;
  982. }
  983.  
  984. //
  985. // A container window has resized. Perform any necessary adjustment of our
  986. // tools.
  987. //
  988. void _IFUNC
  989. TOcRemView::FrameResized(const TRect far* contFrameR, bool isMainFrame)
  990. {
  991.   if (!isMainFrame)
  992.     return;
  993.  
  994.   TRect ltbr;
  995.   TRect ttbr;
  996.   TRect rtbr;
  997.   TRect btbr;
  998.   TRect border;
  999.   sGetTBRects(ToolBarInfo, ltbr, ttbr, rtbr, btbr, border);
  1000.   sAdjustTBPos(ToolBarInfo, *contFrameR, false, ltbr, ttbr, rtbr, btbr, border);
  1001. }
  1002.  
  1003. //
  1004. // Let the server provide drag feedback
  1005. //
  1006. HRESULT _IFUNC
  1007. TOcRemView::DragFeedback(TPoint far* where, bool /*nearScroll*/)
  1008. {
  1009.   PRECONDITION(where);
  1010.  
  1011.   TPoint awhere(*where);
  1012.   TOcDragDrop dd = { 0, &awhere, 0 };
  1013.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWDRAG, &dd));
  1014. }
  1015.  
  1016. //
  1017. // Optional palette query for
  1018. //
  1019. HRESULT _IFUNC
  1020. TOcRemView::GetPalette(LOGPALETTE far* far* palette)
  1021. {
  1022.   PRECONDITION(palette);
  1023.  
  1024.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWGETPALETTE, palette));
  1025. }
  1026.  
  1027. HRESULT _IFUNC
  1028. TOcRemView::SetHost(IBContainer far*)
  1029. {
  1030.   return HR_FAIL;  // Not called on BOle parts.
  1031. }
  1032.  
  1033. HRESULT _IFUNC
  1034. TOcRemView::DoQueryInterface(const IID far& iid, void far* far* iface)
  1035. {
  1036.   PRECONDITION(iface);
  1037.  
  1038.   return TOcView::QueryInterface(iid, iface);  // Unused on server side
  1039. }
  1040.  
  1041. LPOLESTR _IFUNC
  1042. TOcRemView::GetName(TOcPartName)
  1043. {
  1044.   return 0;  // not called on BOle parts
  1045. }
  1046.  
  1047.