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

  1. //
  2. //----------------------------------------------------------------------------
  3. // ObjectComponents
  4. // (C) Copyright 1994 by Borland International, All Rights Reserved
  5. //
  6. //   Implementation of TOcView Class
  7. //----------------------------------------------------------------------------
  8. #include <ocf/ocfpch.h>
  9. #include <ocf/ocstorag.h>
  10. #include <ocf/ocview.h>
  11. #include <ocf/ocremvie.h>
  12. #include <ocf/ocapp.h>
  13. #include <ocf/ocpart.h>
  14. #include <ocf/ocdata.h>
  15. #include <ocf/autodefs.h>
  16. #include <osl/locale.h>
  17. #include <osl/geometry.h>
  18.  
  19. DIAG_DECLARE_GROUP(OcRefCount);
  20.  
  21. const char  DocContent[] = "All";
  22.  
  23. TOcView::TOcView(TOcDocument& doc, TRegList* regList, IUnknown* outer)
  24. :
  25.   OcApp(doc.OcApp),
  26.   Win(0),
  27.   OcDocument(doc),
  28.   ActivePart(0),
  29.   LinkFormat(-1),
  30.   RegList(regList),
  31.   OcData(0),
  32.   Options(0),
  33. #if defined(BI_DATA_NEAR)
  34.   WinTitle(*new string),
  35.   Origin(*new TPoint(0,0)),
  36.   Extent(*new TSize(0,0)),
  37.   FormatList(*new TOcFormatList),
  38.   OrgTitle(*new TString)
  39. #else
  40.   Origin(0,0),
  41.   Extent(0,0)
  42. #endif
  43. {
  44.   BContainer  = 0;
  45.   BDocumentI  = 0;
  46.   BDocument   = 0;
  47.   BLDocumentI = 0;
  48.  
  49.   SetOuter(outer);
  50.   AddRef();    // TUnknown defaults to 0, we need 1
  51.   if (regList)
  52.     RegisterClipFormats(*regList);
  53.  
  54.   // Necessary to initialize TOcPart for linking
  55.   //
  56.   OcDocument.SetActiveView(this);
  57.  
  58.   if (SUCCEEDED(OcApp.BOleComponentCreate(&BDocument,
  59.                 (IUnknown*)(IBContainer*)this, cidBOleDocument))) {
  60.     BDocument->QueryInterface(IID_IBDocument, &(LPVOID)BDocumentI);
  61.     Release();
  62.   }
  63.  
  64.   if (SUCCEEDED(OcApp.BOleComponentCreate(&BContainer,
  65.                 (IUnknown*)(IBContainer*)this, cidBOleContainer))) {
  66.     if (regList) {
  67.       const char* progid = regList->Lookup(OcApp.IsOptionSet(amDebug) ?
  68.                                            "debugprogid" : "progid");
  69.       if (progid &&
  70.           SUCCEEDED(BContainer->QueryInterface(IID_IBRootLinkable, &(LPVOID)BLDocumentI))) {
  71.         Release();
  72.         BLDocumentI->Init((TOcView*)this, OleStr(progid));
  73.       }
  74.     }
  75.   }
  76.  
  77.   TRACEX(OcRefCount, 1, "TOcView() @" << (void*)this);
  78. }
  79.  
  80. TOcView::~TOcView()
  81. {
  82.   Shutdown();
  83. #if defined(BI_DATA_NEAR)
  84.   delete &WinTitle;
  85.   delete &FormatList;
  86.   delete &Origin;
  87.   delete &Extent;
  88.   delete &OrgTitle;
  89. #endif
  90. }
  91.  
  92. //
  93. // called from destructor of this class or of derived class to release helpers
  94. //
  95. void
  96. TOcView::Shutdown()
  97. {
  98.   if (BContainer) {
  99.     BContainer->Release();
  100.     BContainer = 0;
  101.   }
  102.   if (BDocument) {
  103.     BDocument->Release();
  104.     BDocument = 0;
  105.   }
  106. }
  107.  
  108. //
  109. // Should only be called by the owner/creator of this object
  110. //
  111. void
  112. TOcView::ReleaseObject()
  113. {
  114.   Release();
  115.   Win = 0;
  116. }
  117.  
  118. //
  119. // Callback from TUnknown's implementation of QueryInterface
  120. //
  121. HRESULT
  122. TOcView::QueryObject(const IID far& iid, void far* far* iface)
  123. {
  124.   PRECONDITION(iface);
  125.   HRESULT hr;
  126.  
  127.   // interfaces
  128.   //
  129.      SUCCEEDED(hr = IBContainer_QueryInterface(this, iid, iface))
  130.   || SUCCEEDED(hr = IBContains_QueryInterface(this, iid, iface))
  131.   || SUCCEEDED(hr = IBDataConsumer_QueryInterface(this, iid, iface))
  132.   || SUCCEEDED(hr = IBDropDest_QueryInterface(this, iid, iface))
  133.   || SUCCEEDED(hr = IBDataNegotiator_QueryInterface(this, iid, iface))
  134.  
  135.   // helpers (BContainer needed for embed/link from file)
  136.   //
  137.   || (BContainer && SUCCEEDED(hr = BContainer->QueryInterface(iid, iface)))
  138.   || (BDocument && SUCCEEDED(hr = BDocument->QueryInterface(iid, iface)))
  139.   ;
  140.  
  141.   // If the QueryInterface failed, try the TOcLinkView
  142.   //
  143.  
  144.   if (hr == HR_NOINTERFACE && iid == IID_IDataObject) {
  145.     TOcLinkView* view = GetDocLink();
  146.     if (view)
  147.       hr = view->QueryInterface(iid, iface);
  148.   }
  149.  
  150.   return hr;
  151. }
  152.  
  153. //----------------------------------------------------------------------------
  154.  
  155. void
  156. TOcView::SetupWindow(HWND hWin, bool embedded)
  157. {
  158.   // Don't register drag&drop target here since it will do QueryInterface
  159.   // in ComponentCreate before the outer is set up. RefCount will be messed
  160.   // up in this case. Keep Win==0 while initing BDocumentI. OcRemView will init
  161.   // later.
  162.   //
  163.   Win = embedded ? 0 : hWin;
  164.  
  165.   // Make sure at least the BDocument gets its container & application ptrs
  166.   // setup
  167.   //
  168.   if (BDocumentI)
  169.     BDocumentI->Init(this);
  170.  
  171.   if (Win)
  172.     Rename();
  173.   Win = hWin;
  174.  
  175.   EvActivate(true);    // default to being the active view on creation
  176. }
  177.  
  178. // Obtain a TOcLinkView representing the whole document
  179. //
  180. TOcLinkView*
  181. TOcView::GetDocLink()
  182. {
  183.   // Ask the document whether an TOcLinkView corresponding to the item name
  184.   // already exists
  185.   //
  186.   TOcLinkView* ocLinkView = OcDocument.GetViews().Find(DocContent);
  187.  
  188.   // If not, Create an TOcLinkView for the linked doc/item
  189.   // the TOcLinkView should remember the moniker
  190.   //
  191.   if (!ocLinkView) {
  192.     ocLinkView = new TOcLinkView(this, RegList);
  193.     OcDocument.GetViews().Add(ocLinkView);
  194.     ocLinkView->SetMoniker(OleStr(DocContent));
  195.     ocLinkView->GetLinkRect();
  196.   }
  197.  
  198.   return ocLinkView;
  199. }
  200.  
  201. void
  202. TOcView::EvResize()
  203. {
  204.   if (BDocumentI)
  205.     BDocumentI->OnResize();
  206. }
  207.  
  208. //
  209. // View is shuting down
  210. //
  211. void
  212. TOcView::EvClose()
  213. {
  214.   // Release the data provider object
  215.   //
  216.   if (OcData) {
  217.     OcData->Disconnect();
  218.     OcData = 0;
  219.   }
  220.  
  221.   if (BContainer && BDocument && BDocumentI) {
  222.     // Unregisters drag target
  223.     //
  224.     BDocumentI->OnClose();
  225.  
  226.     // Unregisters moniker for this container
  227.     //
  228.     if (BLDocumentI)
  229.       BLDocumentI->OnRename(0, 0);
  230.   }
  231. }
  232.  
  233. //
  234. // View is activated/deactivated
  235. //
  236. void
  237. TOcView::EvActivate(bool activate)
  238. {
  239.   // Set the current active document
  240.   //
  241.   if (BDocumentI)
  242.     BDocumentI->OnActivate(activate);
  243.   if (activate)
  244.     OcDocument.SetActiveView(this);
  245. }
  246.  
  247. //
  248. // Returns true if view keeps focus, false if the inplace server got it
  249. //
  250. bool
  251. TOcView::EvSetFocus(bool set)
  252. {
  253.   if (BDocumentI)
  254.     BDocumentI->OnSetFocus(set);
  255.  
  256.   return OcApp.EvSetFocus(set);
  257. }
  258.  
  259. bool
  260. TOcView::EnumLinks(IBLinkInfo far* far* linkInfo)
  261. {
  262.   PRECONDITION(linkInfo);
  263.  
  264.   return BDocumentI ? HRSucceeded(BDocumentI->EnumLinks(linkInfo)) : false;
  265. }
  266.  
  267. bool
  268. TOcView::BrowseLinks()
  269. {
  270.   return BDocumentI ? HRSucceeded(BDocumentI->BrowseLinks()) : false;
  271. }
  272.  
  273. bool
  274. TOcView::UpdateLinks()
  275. {
  276.   return BDocumentI ? HRSucceeded(BDocumentI->UpdateLinks()) : false;
  277. }
  278.  
  279. void
  280. TOcView::Rename()
  281. {
  282.   if (!BLDocumentI || OcDocument.GetName().is_null())
  283.     return;
  284.  
  285.   // update the file moniker
  286.   //
  287.   BLDocumentI->OnRename(0, OleStr(OcDocument.GetName().c_str()));
  288.  
  289.   OcDocument.RenameParts(BLDocumentI);
  290. }
  291.  
  292. //----------------------------------------------------------------------------
  293.  
  294. //
  295. // Return the client rect for the view window
  296. //
  297. TRect
  298. TOcView::GetWindowRect() const
  299. {
  300.   TRect r;
  301.   const_cast<TOcView*>(this)->GetWindowRect(&r);
  302.   return r;
  303. }
  304.  
  305. //
  306. // Scroll this container window a give dx,dy
  307. //
  308. void
  309. TOcView::ScrollWindow(int dx, int dy)
  310. {
  311.   Origin += TPoint(dx, dy);
  312. }
  313.  
  314. void
  315. TOcView::InvalidatePart(TOcPartChangeInfo& changeInfo)
  316. {
  317.   if (changeInfo.GetPart()) {
  318.     if (!ForwardEvent(OC_VIEWPARTINVALID, &changeInfo))
  319.       ::InvalidateRect(GetWindow(), &(changeInfo.GetPart()->GetRect() - *(TSize*)&GetOrigin()), true);
  320.   }
  321. }
  322.  
  323. //
  324. // Activate a given part
  325. //
  326. bool
  327. TOcView::ActivatePart(TOcPart* part)
  328. {
  329.   if (part == ActivePart)
  330.     return true;
  331.  
  332.   if (ActivePart && ActivePart->IsActive()) {
  333.     ActivePart->Activate(false);
  334.     ActivePart = 0;
  335.   }
  336.   if (part) {
  337.     if (!part->IsActive() && !part->Activate(true))
  338.       return false;
  339.     ActivePart = part;
  340.   }
  341.   return true;
  342. }
  343.  
  344. uint32
  345. TOcView::ForwardEvent(int eventId, const void far* param)
  346. {
  347.   return ::SendMessage(GetWindow(), WM_OCEVENT, eventId, (LPARAM)param);
  348. }
  349.  
  350. uint32
  351. TOcView::ForwardEvent(int eventId, uint32 param)
  352. {
  353.   return ::SendMessage(GetWindow(), WM_OCEVENT, eventId, param);
  354. }
  355.  
  356. //----------------------------------------------------------------------------
  357. // IBContains implementation
  358.  
  359. //
  360. // Ask the container to load document named
  361. //
  362. HRESULT _IFUNC
  363. TOcView::Init(LPCOLESTR path)
  364. {
  365.   bool result = (bool)ForwardEvent(OC_VIEWOPENDOC, (const char far*)OleStr(path));
  366.   if (result) {
  367.     // register this document in running object table
  368.     //
  369.  
  370.     OcDocument.SetName(string(OleStr(path)));
  371.     Rename();
  372.   }
  373.  
  374.   return HRFailIfZero(result);
  375. }
  376.  
  377. HRESULT _IFUNC
  378. TOcView::GetPart(IBPart far* far* bpart, LPCOLESTR name)
  379. {
  380.   PRECONDITION(bpart);
  381.  
  382.   for (TOcPartCollectionIter i(OcDocument.GetParts()); i; i++) {
  383.     TOcPart* ocPart = (TOcPart*)i.Current();
  384.     if (ocPart && strcmp(ocPart->GetName(), OleStr(name)) == 0) {
  385.       ocPart->FinishLoading(); // In case the part hasn't been loaded
  386.       if (SUCCEEDED(ocPart->QueryInterface(IID_IBPart, (LPVOID*)bpart))) {
  387.         return HR_NOERROR; // now there is one more refcount on ocPart
  388.       }
  389.     }
  390.   }
  391.  
  392.   // Ask the document whether an TOcLinkView corresponding to the item name
  393.   // already exists
  394.   //
  395.   TOcLinkView* ocLinkView = OcDocument.GetViews().Find(name);
  396.   if (ocLinkView) {
  397.     if (SUCCEEDED(ocLinkView->QueryInterface(IID_IBPart, (LPVOID*)bpart))) {
  398.       return HR_NOERROR; // now there is one more refcount on ocRemView
  399.     }
  400.     else
  401.       return HR_FAIL;
  402.   }
  403.  
  404.   // If not, Create an TOcLinkView for the linked doc/item
  405.   // the TOcLinkView should remember the moniker
  406.   //
  407.   if (!ocLinkView) {
  408.     ocLinkView = new TOcLinkView(this, RegList);
  409.     OcDocument.GetViews().Add(ocLinkView);
  410.   }
  411.  
  412.   ocLinkView->SetMoniker(OleStr(name));
  413.   ocLinkView->GetLinkRect();
  414.   if (SUCCEEDED(ocLinkView->QueryInterface(IID_IBPart, (LPVOID*)bpart)) &&
  415.     ForwardEvent(OC_VIEWSETLINK, ocLinkView)) {
  416.       return HR_NOERROR; // now there is one more refcount on ocRemView
  417.   }
  418.  
  419.   return HR_FAIL;
  420. }
  421.  
  422. //----------------------------------------------------------------------------
  423. // IBDataNegotiator implementation
  424.  
  425. //
  426. // Format count
  427. //
  428. uint _IFUNC
  429. TOcView::CountFormats()
  430. {
  431.   return FormatList.Count();
  432. }
  433.  
  434. //
  435. // Format retrieval
  436. //
  437. HRESULT _IFUNC
  438. TOcView::GetFormat(uint index, TOcFormatInfo far* fmt)
  439. {
  440.   PRECONDITION(fmt);
  441.  
  442.   // Link source is FormatList[0]
  443.   // Link source will be the first format returned if Link is 0
  444.   // Link source will be the last format returned if Link is -1
  445.   //
  446.   index = (index - LinkFormat) % CountFormats();
  447.   FormatList[index]->GetFormatInfo(*fmt);
  448.   return HR_NOERROR;
  449. }
  450.  
  451. //----------------------------------------------------------------------------
  452. // IBWindow implementation
  453.  
  454. HWND _IFUNC
  455. TOcView::GetWindow()
  456. {
  457.   return Win;
  458. }
  459.  
  460. HRESULT _IFUNC
  461. TOcView::GetWindowRect(TRect far* r)
  462. {
  463.   PRECONDITION(r);
  464.  
  465.   ::GetClientRect(GetWindow(), r);
  466.   return HR_NOERROR;
  467. }
  468.  
  469. LPCOLESTR _IFUNC
  470. TOcView::GetWindowTitle()
  471. {
  472.   // Delegate to app's view window to get its title
  473.   //
  474.   OrgTitle = (const char far*)ForwardEvent(OC_VIEWTITLE);
  475.   return (LPCOLESTR)OrgTitle;
  476. }
  477.  
  478. //
  479. // Append server's doc title info to our view's window title
  480. //
  481. void _IFUNC
  482. TOcView::AppendWindowTitle(LPCOLESTR title)
  483. {
  484.   WinTitle = (const char far*)OleStr(GetWindowTitle());
  485.   char in[32];
  486.   ::LoadString(_hInstance, IDS_IN, in, sizeof in);
  487.  
  488.   string newTitle = (const char far*)OleStr(title);
  489.   newTitle += in;
  490.   newTitle += WinTitle;
  491.   ForwardEvent(OC_VIEWSETTITLE, newTitle.c_str());
  492. }
  493.  
  494. HRESULT _IFUNC
  495. TOcView::SetStatusText(LPCOLESTR /*text*/)
  496. {
  497.   return HR_FAIL;
  498. }
  499.  
  500. HRESULT _IFUNC
  501. TOcView::RequestBorderSpace(const TRect far* space)
  502. {
  503.   PRECONDITION(space);
  504.  
  505.   // Let individual views decide this
  506.   //
  507.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWBORDERSPACEREQ, space));
  508. }
  509.  
  510. HRESULT _IFUNC
  511. TOcView::SetBorderSpace(const TRect far* space)
  512. {
  513.   PRECONDITION(space);
  514.  
  515.   // Let individual views do this
  516.   //
  517.   return HRFailIfZero((bool)ForwardEvent(OC_VIEWBORDERSPACESET, space));
  518. }
  519.  
  520. HRESULT _IFUNC
  521. TOcView::InsertContainerMenus(HMENU, TOcMenuWidths far*)
  522. {
  523.   return HR_FAIL;
  524. }
  525.  
  526. HRESULT _IFUNC
  527. TOcView::SetFrameMenu(HMENU)
  528. {
  529.   return HR_FAIL;
  530. }
  531.  
  532. //
  533. // The in-place server is done. Tell the container to restore its normal UI.
  534. //
  535. void _IFUNC
  536. TOcView::RestoreUI()
  537. {
  538.   ForwardEvent(OC_VIEWSETTITLE, WinTitle.c_str());
  539. }
  540.  
  541. HRESULT _IFUNC
  542. TOcView::Accelerator(MSG far*)
  543. {
  544.   return HR_FAIL;
  545. }
  546.  
  547. HRESULT _IFUNC
  548. TOcView::GetAccelerators(HACCEL far*, int far*)
  549. {
  550.   return HR_FAIL;
  551. }
  552.  
  553. //----------------------------------------------------------------------------
  554. // IBDropDest implementation
  555.  
  556. //
  557. // Drop a part onto this view. Creates the part based on initInfo, activating
  558. // it as appropriate
  559. //
  560. HRESULT _IFUNC
  561. TOcView::Drop(TOcInitInfo far* initInfo, TPoint far* where, const TRect far* objPos)
  562. {
  563.   PRECONDITION(initInfo && where && objPos);
  564.  
  565.   initInfo->Container = this;
  566.   TPoint awhere(*where);
  567.   TRect  aobjPos(*objPos);
  568.   TOcDragDrop dd = {
  569.     (TOcInitInfo far*)initInfo, &awhere, &aobjPos
  570.   };
  571.  
  572.   if (PasteNative((TOcInitInfo&)*initInfo, where))
  573.     return HR_NOERROR;
  574.  
  575.   // Make sure that the view will accept this drop
  576.   //
  577.   if (!ForwardEvent(OC_VIEWDROP, &dd))
  578.    return HR_FAIL;
  579.  
  580.   // Create part now that view approved. BDocument calls AddSite on all views.
  581.   //
  582.   try {
  583.     new TOcPart(OcDocument, *dd.InitInfo, aobjPos);
  584.   }
  585.   catch (...) {
  586.     return HR_FAIL;
  587.   }
  588.  
  589.   Rename();
  590.  
  591.   return HR_NOERROR;
  592. }
  593.  
  594. //
  595. // Provide feedback to the users drag action in our container window
  596. //
  597. void _IFUNC
  598. TOcView::DragFeedback(TPoint far* where, const TRect far* objPos, TOcMouseAction /*action*/, uint, HRESULT& hr)
  599. {
  600.   PRECONDITION(where && objPos);
  601.  
  602.   TPoint awhere(*where);
  603.   TRect  aobjPos(*objPos);
  604.   TOcDragDrop dd = { 0, &awhere, &aobjPos };
  605.   hr = HRFailIfZero((int)ForwardEvent(OC_VIEWDRAG, &dd));
  606. }
  607.  
  608. //
  609. // Ask the container view window to scroll itself in a given direction. Asked
  610. // by the server when dragging or working in a clipped site.
  611. //
  612. HRESULT _IFUNC
  613. TOcView::Scroll(TOcScrollDir scrollDir)
  614. {
  615.   // Have the real view do the work here.
  616.   //
  617.   if (!ForwardEvent(OC_VIEWSCROLL, scrollDir))
  618.     return HR_FALSE;
  619.   return HR_NOERROR;
  620. }
  621.  
  622. HRESULT _IFUNC
  623. TOcView::GetScrollRect(TRect far*)
  624. {
  625.   return HR_NOERROR;
  626. }
  627.  
  628. //----------------------------------------------------------------------------
  629. // IBContainer implementation
  630.  
  631. //
  632. // Locate the drop destination object. For default OC, it is just this view.
  633. // Other extensions might have subtargets within the view.
  634. //
  635. HRESULT _IFUNC
  636. TOcView::FindDropDest(TPoint far*, IBDropDest far* far* dropDest)
  637. {
  638.   *dropDest = this;
  639.   return HR_NOERROR;
  640. }
  641.  
  642. HRESULT _IFUNC
  643. TOcView::BringToFront()
  644. {
  645.   // See if we are in an MDI child & if so activate it
  646.   //
  647.   HWND hMdiChild = ::GetParent(GetWindow());
  648.   if (hMdiChild) {
  649.     HWND hMdiClient = ::GetParent(hMdiChild);
  650.     if (hMdiClient) {
  651.       HWND hMdiFrame = ::GetParent(hMdiClient);
  652.       while (::GetParent(hMdiFrame)) {
  653.         hMdiChild = hMdiClient;
  654.         hMdiClient = hMdiFrame;
  655.         hMdiFrame = ::GetParent(hMdiFrame);
  656.       }
  657.       ::SendMessage(hMdiClient, WM_MDIACTIVATE, (WPARAM)hMdiChild, 0);
  658.     }
  659.   }
  660.  
  661.   // Bring our app frame to the top, show it & give it focus. Also make sure
  662.   // that this view is on top & visible
  663.   //
  664.   ::SetWindowPos(OcApp.GetWindow(), HWND_TOP, 0, 0, 0, 0,
  665.                  SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
  666.   ::SetFocus(OcApp.GetWindow());
  667.   ::ShowWindow(GetWindow(), SW_SHOWNORMAL);
  668.   ::SetWindowPos(GetWindow(), HWND_TOP, 0, 0, 0, 0,
  669.                  SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
  670.  
  671.   return HR_NOERROR;
  672. }
  673.  
  674. HRESULT _IFUNC
  675. TOcView::AllowInPlace()
  676. {
  677.   if (IsOptionSet(voNoInPlace))
  678.     return HR_FALSE;
  679.   else
  680.     return HR_NOERROR;
  681. }
  682.  
  683. //----------------------------------------------------------------------------
  684. // Clipboard related
  685.  
  686. //
  687. // Register the clipboard formats supported
  688. //
  689. bool
  690. TOcView::RegisterClipFormats(TRegList& regList)
  691. {
  692.   // Register link source first
  693.   //
  694.   uint cfLinkSource = ::RegisterClipboardFormat("Link Source");
  695.   if (cfLinkSource)
  696.     FormatList.Add(new TOcFormat(cfLinkSource, "%s", "%s",
  697.                                  4 /*BOLE_MED_STREAM*/, true));
  698.  
  699.   char  key[32];
  700.   char  val[128];
  701.   char* buf;
  702.   uint  i = 0;
  703.   bool  succ = true;
  704.  
  705.   while (true) {
  706.     wsprintf(key, "format%d", i);
  707.     buf = const_cast<char*>(regList[key]);
  708.     if (!buf)
  709.       break;
  710.     else {
  711.       // parse the value string
  712.       //
  713.       strcpy(val, buf);
  714.       buf = val;
  715.  
  716.       TOcFormat* format = new TOcFormat;
  717.  
  718.       for (int i = 0; i < 3; i++) {
  719.         char* current = strchr(buf, ',');
  720.         if (!current) {
  721.           succ = false;
  722.           break; // error
  723.         }
  724.  
  725.         *current = 0;
  726.         switch (i) {
  727.           case 0: // Format id or name
  728.             if (isdigit(*buf)) {
  729.               uint id = atoi(buf);
  730.               format->SetFormatId(id);
  731.               format->SetFormatName(id - 1, OcApp);
  732.             }
  733.             else { // register the user defined clipboard format
  734.               uint cf = ::RegisterClipboardFormat(buf);
  735.               if (cf == cfLinkSource)
  736.                 format->SetLinkable();
  737.  
  738.               format->SetFormatId(cf);
  739.               format->SetFormatName(buf, OcApp);
  740.             }
  741.             break;
  742.  
  743.           case 1: // Aspect
  744.             format->SetAspect((uint)atoi(buf));
  745.             break;
  746.  
  747.           case 2:
  748.             format->SetMedium((uint)atoi(buf)); // Storage medium
  749.             format->SetDirection((uint)atoi(current+1)); // Direction
  750.             break;
  751.         } // switch
  752.  
  753.         buf = current + 1;
  754.       } // for
  755.  
  756.       if (succ)
  757.         FormatList.Add(format); // Add to the format list
  758.       else
  759.         delete format;
  760.     } // else
  761.  
  762.     i++;
  763.   } // while
  764.  
  765.   return succ;
  766. }
  767.  
  768. bool
  769. TOcView::BrowseClipboard(TOcInitInfo& initInfo)
  770. {
  771.   return OcApp.BrowseClipboard(initInfo);
  772. }
  773.  
  774. //
  775. // Paste native data into the container
  776. //
  777. bool
  778. TOcView::PasteNative(TOcInitInfo& init, TPoint far* where)
  779. {
  780.   bool result = false;
  781.   if ((init.Where == iwHandle) && (init.How == ihEmbed)) { // could be native data
  782.     TOcFormat* format = FormatList.Find(init.Handle.DataFormat);
  783.     if (!format) {
  784.       return false; // not my native data
  785.     }
  786.  
  787.     TOcFormatData formatData(*format, 0, init.Handle.Data, true, where);
  788.     result = (bool)ForwardEvent(OC_VIEWCLIPDATA, &formatData);
  789.     if (result)
  790.       init.ReleaseDataObject();
  791.   }
  792.  
  793.   return result;
  794. }
  795.  
  796. bool
  797. TOcView::Paste(bool linking)
  798. {
  799.   LinkFormat = linking ? 0 : -1;
  800.   TOcInitInfo init(this);
  801.   bool result = OcApp.Paste(init);
  802.  
  803.   if (result) {
  804.     result = PasteNative(init);
  805.     if (!result)
  806.       result = (bool)ForwardEvent(OC_VIEWPASTEOBJECT, &init);
  807.   }
  808.  
  809.   return result;
  810. }
  811.  
  812. //-----------------------------------------------------------------------------
  813. // TOcFormat
  814. //
  815.  
  816. TOcFormat::TOcFormat()
  817. {
  818.   char fstr[] = "%s";
  819.  
  820.   Id = 0;
  821.   RegName[0] = 0;
  822.   strcpy(Name, fstr);
  823.   strcpy(ResultName, fstr);
  824.   Medium     = ocrNull;
  825.   IsLinkable = false;
  826.   Aspect     = 1;  // content
  827.   Direction  = 1;  // get
  828. }
  829.  
  830. TOcFormat::TOcFormat(uint id, char far* name, char far* resultName,
  831.                      uint medium, bool isLinkable,
  832.                      uint aspect, uint direction)
  833. {
  834.   Id         = (WORD)id;
  835.   Medium     = (ocrMedium)medium;
  836.   IsLinkable = isLinkable;
  837.   Aspect     = aspect;
  838.   Direction  = direction;
  839.  
  840.   RegName[0] = 0;
  841.   strcpy(Name, name);
  842.   strcpy(ResultName, resultName);
  843. }
  844.  
  845. void
  846. TOcFormat::operator =(const TOcFormatInfo& f)
  847. {
  848.   Id = f.Id;
  849.   strcpy(Name, OleStr(f.Name));
  850.   strcpy(ResultName, OleStr(f.ResultName));
  851.   Medium = f.Medium;
  852.   IsLinkable = f.IsLinkable;
  853. }
  854.  
  855. void
  856. TOcFormat::GetFormatInfo(TOcFormatInfo far& f)
  857. {
  858.   f.Id = uint16(Id);
  859. #if defined(BI_OLECHAR_WIDE)
  860. //  lstrcpyW(f.Name, OleStr(Name));
  861.   memcpy(f.Name, (LPCWSTR)OleStr(Name), (strlen(Name)+1)*2);
  862. // lstrcpyW(f.ResultName, OleStr(ResultName));
  863.   memcpy(f.ResultName, (LPCWSTR)OleStr(ResultName), (strlen(ResultName)+1)*2);
  864. #else
  865.   strncpy(f.Name, Name, sizeof Name);
  866.   strncpy(f.ResultName, ResultName, sizeof ResultName);
  867. #endif
  868.   f.Medium = (ocrMedium)Medium;
  869.   f.IsLinkable = (BOOL)IsLinkable;
  870. }
  871.  
  872. void
  873. TOcFormat::SetFormatName(char far* name, TOcApp& ocApp)
  874. {
  875.   TOcFormatName* formatName = ocApp.GetNameList()[name];
  876.   if (!formatName)
  877.     return;
  878.  
  879.   strcpy(RegName, name);
  880.   strcpy(Name, formatName->GetName());
  881.   strcpy(ResultName, formatName->GetResultName());
  882. }
  883.  
  884. void
  885. TOcFormat::SetFormatName(uint id, TOcApp& ocApp)
  886. {
  887.   TOcFormatName* formatName = ocApp.GetNameList()[id];
  888.   if (!formatName)
  889.     return;
  890.  
  891.   strcpy(Name, formatName->GetName());
  892.   strcpy(ResultName, formatName->GetResultName());
  893. }
  894.  
  895.  
  896. //----------------------------------------------------------------------------
  897. // TOcFormatList
  898. //
  899.  
  900. TOcFormatList::TOcFormatList()
  901.   : TICVectorImp<TOcFormat>(10, 0)
  902. {
  903. }
  904.  
  905. TOcFormatList::~TOcFormatList()
  906. {
  907.   Clear();
  908. }
  909.  
  910. TOcFormat*
  911. TOcFormatList::Find(uint const id) const
  912. {
  913.   for (TOcFormatListIter j(*this); j; j++) {
  914.     TOcFormat* format = (TOcFormat*)j.Current();
  915.     if (format && (format->GetFormatId() == id)) {
  916.       return format;
  917.     }
  918.   }
  919.  
  920.   return 0;
  921. }
  922.  
  923.  
  924. //----------------------------------------------------------------------------
  925. // TOcScaleFactor
  926. //
  927.  
  928. TOcScaleFactor::TOcScaleFactor()
  929. :
  930.   SiteSize(1, 1),
  931.   PartSize(1, 1)
  932. {
  933. }
  934.  
  935. TOcScaleFactor::TOcScaleFactor(const TRect& siteRect, const TSize& partSize)
  936. {
  937.   SiteSize.cx = siteRect.Width();
  938.   SiteSize.cy = siteRect.Height();
  939.  
  940.   PartSize = partSize;
  941. }
  942.  
  943. TOcScaleFactor::TOcScaleFactor(const TOcScaleInfo far& scale)
  944. {
  945.   *this = scale;
  946. }
  947.  
  948. //
  949. // Assign a BOle structure to this scale factor
  950. //
  951. TOcScaleFactor&
  952. TOcScaleFactor::operator =(const TOcScaleInfo far& scaleInfo)
  953. {
  954.   SiteSize.cx = (int)scaleInfo.xN;
  955.   SiteSize.cy = (int)scaleInfo.yN;
  956.   PartSize.cx = (int)scaleInfo.xD;
  957.   PartSize.cy = (int)scaleInfo.yD;
  958.  
  959.   return *this;
  960. }
  961.  
  962. //
  963. // Assign one TOcScaleFactor to another
  964. //
  965. TOcScaleFactor&
  966. TOcScaleFactor::operator =(const TOcScaleFactor& scaleFactor)
  967. {
  968.   SiteSize = scaleFactor.SiteSize;
  969.   PartSize = scaleFactor.PartSize;
  970.  
  971.   return *this;
  972. }
  973.  
  974. //
  975. // Copy a BOle scale factor structure
  976. //
  977. void
  978. TOcScaleFactor::GetScaleFactor(TOcScaleInfo far& scaleInfo) const
  979. {
  980.   scaleInfo.xN = SiteSize.cx;
  981.   scaleInfo.yN = SiteSize.cy;
  982.   scaleInfo.xD = PartSize.cx;
  983.   scaleInfo.yD = PartSize.cy;
  984. }
  985.  
  986. //
  987. // Whether there is zoom factor
  988. //
  989. bool
  990. TOcScaleFactor::IsZoomed()
  991. {
  992.   return SiteSize != PartSize;
  993. }
  994.  
  995. //
  996. // Change the scaling factor
  997. //
  998. void
  999. TOcScaleFactor::SetScale(uint16 percent)
  1000. {
  1001.   PartSize.cx = PartSize.cy = 100;
  1002.   SiteSize.cx = SiteSize.cy = percent;
  1003. }
  1004.  
  1005. //
  1006. // Get the scale percentage
  1007. //
  1008. uint16
  1009. TOcScaleFactor::GetScale()
  1010. {
  1011.   return (uint16)(((uint32)SiteSize.cx * 100 + (PartSize.cx >> 1)) / PartSize.cx);
  1012. }
  1013.  
  1014. //
  1015. // Set scaling factor to 1
  1016. //
  1017. void
  1018. TOcScaleFactor::Reset()
  1019. {
  1020.   PartSize.cx = PartSize.cy = 1;
  1021.   SiteSize.cx = SiteSize.cy = 1;
  1022. }
  1023.  
  1024.