home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / OLEWINDO.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  38KB  |  1,672 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1994 by Borland International, All Rights Reserved
  4. //
  5. //   Implementation of TOleWindow. Window class that supports Ole2
  6. //   container & server 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/uihandle.h>
  13. #include <owl/scroller.h>
  14. #include <ocf/ocdoc.h>
  15. #include <ocf/ocview.h>
  16. #include <owl/docview.rh>
  17. #include <owl/oleview.rh>
  18. #include <owl/oleframe.h>
  19. #include <owl/olewindo.h>
  20. #include <owl/oledlg.h>
  21.  
  22. //----------------------------------------------------------------------------
  23. // Size of rectangle in two clks must occur to be a doubleClick
  24. //
  25. #if !defined(BI_PLAT_WIN32)
  26.   TSize DblClkDelta(3, 3);
  27. #else
  28.   TSize DblClkDelta(GetSystemMetrics(SM_CXDOUBLECLK)/2,
  29.                     GetSystemMetrics(SM_CYDOUBLECLK)/2);
  30. #endif
  31.  
  32.  
  33. //----------------------------------------------------------------------------
  34. // TOleClientDC
  35. //
  36.  
  37. TOleClientDC::TOleClientDC(TOleWindow& win, bool scale)
  38. :
  39.   TClientDC(win)
  40. {
  41.   win.SetupDC(*this, scale);
  42. }
  43.  
  44. //----------------------------------------------------------------------------
  45. // TOleWindow
  46. //
  47.  
  48. DEFINE_RESPONSE_TABLE1(TOleWindow, TWindow)
  49.   EV_WM_PAINT,
  50.   EV_WM_LBUTTONDOWN,
  51.   EV_WM_RBUTTONDOWN,
  52.   EV_WM_LBUTTONDBLCLK,
  53.   EV_WM_MOUSEMOVE,
  54.   EV_WM_LBUTTONUP,
  55.   EV_WM_SIZE,
  56.   EV_WM_MDIACTIVATE,
  57.   EV_WM_MOUSEACTIVATE,
  58.   EV_WM_SETFOCUS,
  59.   EV_WM_SETCURSOR,
  60.   EV_WM_DROPFILES,
  61.   EV_WM_VSCROLL,
  62.   EV_WM_HSCROLL,
  63.   EV_WM_MENUSELECT,
  64.  
  65.   EV_COMMAND_ENABLE(CM_FILECLOSE, CeFileClose),
  66.  
  67.   EV_COMMAND(CM_EDITDELETE, CmEditDelete),
  68.   EV_COMMAND_ENABLE(CM_EDITDELETE, CeEditDelete),
  69.   EV_COMMAND(CM_EDITCUT, CmEditCut),
  70.   EV_COMMAND_ENABLE(CM_EDITCUT, CeEditCut),
  71.   EV_COMMAND(CM_EDITCOPY, CmEditCopy),
  72.   EV_COMMAND_ENABLE(CM_EDITCOPY, CeEditCopy),
  73.   EV_COMMAND(CM_EDITPASTE, CmEditPaste),
  74.   EV_COMMAND_ENABLE(CM_EDITPASTE, CeEditPaste),
  75.   EV_COMMAND(CM_EDITPASTESPECIAL, CmEditPasteSpecial),
  76.   EV_COMMAND_ENABLE(CM_EDITPASTESPECIAL, CeEditPasteSpecial),
  77.   EV_COMMAND(CM_EDITPASTELINK, CmEditPasteLink),
  78.   EV_COMMAND_ENABLE(CM_EDITPASTELINK, CeEditPasteLink),
  79.   EV_COMMAND(CM_EDITINSERTOBJECT, CmEditInsertObject),
  80.   EV_COMMAND_ENABLE(CM_EDITINSERTOBJECT, CeEditInsertObject),
  81.   EV_COMMAND_ENABLE(CM_EDITLINKS, CeEditLinks),
  82.   EV_COMMAND(CM_EDITLINKS, CmEditLinks),
  83.   EV_COMMAND_ENABLE(CM_EDITOBJECT, CeEditObject),
  84.   EV_COMMAND_ENABLE(CM_EDITCONVERT, CeEditConvert),
  85.   EV_COMMAND(CM_EDITCONVERT, CmEditConvert),
  86.   EV_COMMAND_ENABLE(CM_EDITSHOWOBJECTS, CeEditShowObjects),
  87.   EV_COMMAND(CM_EDITSHOWOBJECTS, CmEditShowObjects),
  88.  
  89.   EV_MESSAGE(WM_OCEVENT, EvOcEvent),
  90. //  EV_OC_VIEWDISCARDUNDO,  //!CQ not processing this yet...
  91.  
  92.   // Container specific messages
  93.   //
  94.   EV_OC_VIEWPARTINVALID,
  95.   EV_OC_VIEWTITLE,
  96.   EV_OC_VIEWSETTITLE,
  97.   EV_OC_VIEWBORDERSPACEREQ,
  98.   EV_OC_VIEWBORDERSPACESET,
  99.   EV_OC_VIEWDROP,
  100.   EV_OC_VIEWDRAG,
  101.   EV_OC_VIEWSCROLL,
  102.   EV_OC_VIEWGETSCALE,
  103.   EV_OC_VIEWGETSITERECT,
  104.   EV_OC_VIEWSETSITERECT,
  105.   EV_OC_VIEWPARTACTIVATE,
  106.   EV_OC_VIEWPASTEOBJECT,
  107.  
  108.   // Server specific messages
  109.   //
  110.   EV_OC_VIEWPAINT,
  111.   EV_OC_VIEWSAVEPART,
  112.   EV_OC_VIEWLOADPART,
  113.   EV_OC_VIEWINSMENUS,
  114.   EV_OC_VIEWSHOWTOOLS,
  115.   EV_OC_VIEWGETPALETTE,
  116.   EV_OC_VIEWCLIPDATA,
  117.   EV_OC_VIEWSETDATA,
  118.   EV_OC_VIEWCLOSE,
  119.   EV_OC_VIEWPARTSIZE,
  120.   EV_OC_VIEWOPENDOC,
  121.   EV_OC_VIEWATTACHWINDOW,
  122.   EV_OC_VIEWSETSCALE,
  123.   EV_OC_VIEWGETITEMNAME,
  124.   EV_OC_VIEWSETLINK,
  125.   EV_OC_VIEWBREAKLINK,
  126.   EV_OC_VIEWDOVERB,
  127. END_RESPONSE_TABLE;
  128.  
  129. TOleWindow::TOleWindow(TWindow* parent, TModule* module)
  130. :
  131.   TWindow(parent, 0, module),
  132.   Pos(0, 0, 0, 0),
  133.   Remote(false),
  134.   ShowObjects(false)
  135. {
  136.   // Derived class will need to create a OcDocument object to hold the ole
  137.   // parts that we create and a OcView to provide ole services
  138.   //
  139.   OcApp  = 0;
  140.   OcDoc  = 0;
  141.   OcView = 0;
  142.  
  143.   Init();
  144. }
  145.  
  146. void
  147. TOleWindow::Init()
  148. {
  149.   // Clip children to not paint on in-place servers, & clip siblings to not
  150.   // paint on floating tool palettes
  151.   //
  152.   Attr.Style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  153.  
  154.   Attr.AccelTable = IDA_OLEVIEW;
  155.   DragHit   = TUIHandle::Outside;
  156.   DragPart  = 0;
  157.   DragDC    = 0;
  158.  
  159.   // Minimum part size
  160.   //
  161.   HDC dc = GetDC(0);
  162.   MinWidth  = GetDeviceCaps(dc, LOGPIXELSX) / 4;
  163.   MinHeight = GetDeviceCaps(dc, LOGPIXELSY) / 4;
  164.   ReleaseDC(0, dc);
  165.  
  166.  
  167.   // Snag the OcApp from the TOleFrame object for quick reference
  168.   //
  169.   TOleFrame* olefr = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), TOleFrame);
  170.   CHECK(olefr);
  171.   OcApp = olefr->GetOcApp();
  172.   OcApp->AddRef();
  173. }
  174.  
  175. TOleWindow::~TOleWindow()
  176. {
  177.   // Let the OC objects go. They will delete themselves when they can
  178.   // If it's a remote view, then the last release is called by the container.
  179.   //
  180.   if (OcDoc)
  181.     OcDoc->Close();           // close all the embedded parts first
  182.   if (OcView && !IsRemote()) {
  183.     OcView->ReleaseObject();  // use ReleaseObject here to tell it we are gone
  184.     OcView = 0;
  185.   }
  186.  
  187.   delete OcDoc;
  188.   if (OcApp) {
  189.     OcApp->Release();
  190.     OcApp = 0;
  191.   }
  192. }
  193.  
  194. //
  195. // Perform normal SetupWindow, plus let the OcView object know our HWND so that
  196. // it can talk to us.
  197. //
  198. void
  199. TOleWindow::SetupWindow()
  200. {
  201.   if (!OcView)
  202.     CreateOcView(0, false, 0);  // don't have much context by this time
  203.   CHECK(OcView);
  204.   TWindow::SetupWindow();
  205.   OcView->SetupWindow(*this, IsRemote());
  206. }
  207.  
  208. //
  209. // Called to perform the actual setting up of the OcView member
  210. // Derived class needs to construct the TOcView/TOcRemView here & return it
  211. //
  212. TOcView*
  213. TOleWindow::CreateOcView(TRegLink* link, bool isRemote, IUnknown* outer)
  214. {
  215.   if (!OcDoc)
  216.     OcDoc = new TOcDocument(*GetOcApp());
  217.  
  218.   if (!OcView) {
  219.     TRegList* regList = link ? &link->GetRegList() : 0;
  220.  
  221.     // Create a remote view on the server document if it embeded, else make a
  222.     // normal, container view
  223.     //
  224.     if (isRemote)
  225.       OcView = new TOcRemView(*GetOcDoc(), regList, outer);
  226.     else
  227.       OcView = new TOcView(*GetOcDoc(), regList, outer);
  228.  
  229.     Remote = isRemote;
  230.   }
  231.   return OcView;
  232. }
  233.  
  234. //
  235. // Handle the command enabling for a range of command IDs for verbs
  236. //
  237. void
  238. TOleWindow::EvCommandEnable(TCommandEnabler& commandEnabler)
  239. {
  240.   if (CM_EDITFIRSTVERB <= commandEnabler.Id && commandEnabler.Id <= CM_EDITLASTVERB) {
  241.     CeEditVerbs(commandEnabler);
  242.   }
  243.   else if (IsRemote()) {
  244.     // Get the focus, in case it is a child that should receive the cmds
  245.     // fall back to this window in case the Ole menu bar stole focus!
  246.     //
  247.     HWND  hCmdTarget = ::GetFocus();
  248.     if (hCmdTarget != HWindow && !IsChild(hCmdTarget))
  249.       hCmdTarget = HWindow;
  250.  
  251.     RouteCommandEnable(hCmdTarget, commandEnabler);
  252.   }
  253.   else {
  254.     TWindow::EvCommandEnable(commandEnabler);
  255.   }
  256. }
  257.  
  258. //
  259. // processing a range of command IDs for verbs
  260. //
  261. LRESULT
  262. TOleWindow::EvCommand(uint id, HWND hWndCtl, uint notifyCode)
  263. {
  264.   if (hWndCtl == 0) {
  265.     if (CM_EDITFIRSTVERB <= id && id <= CM_EDITLASTVERB) {
  266.       EvDoVerb(id - CM_EDITFIRSTVERB);
  267.       return 0;
  268.     }
  269.   }
  270.   return TWindow::EvCommand(id, hWndCtl, notifyCode);
  271. }
  272.  
  273. //
  274. // Intercept CanClose() to interpose OpenEdit semantics. Ole 2 servers don't
  275. // prompt the user on close--just save & close.
  276. //
  277. bool
  278. TOleWindow::CanClose()
  279. {
  280.   // We don't want to close the view for DLL servers
  281.   //
  282.   if (IsOpenEditing() && !OcApp->IsOptionSet(amExeMode)) {
  283.     TOleFrame* olefr = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), TOleFrame);
  284.     CHECK(olefr);
  285.     olefr->ShowWindow(SW_HIDE);
  286.     OleShutDown();
  287.     return false;
  288.   }
  289.  
  290.   if (GetOcRemView() || TWindow::CanClose()) {
  291.     if (OcDoc)
  292.       OcDoc->Close();
  293.     return true;
  294.   }
  295.   return false;
  296. }
  297.  
  298. //
  299. // Notify part
  300. //
  301. void
  302. TOleWindow::InvalidatePart(TOcInvalidate invalid)
  303. {
  304.   if (GetOcRemView())
  305.     GetOcRemView()->Invalidate(invalid);
  306. }
  307.  
  308. //
  309. // Is the window in Open-Edit mode
  310. //
  311. bool
  312. TOleWindow::IsOpenEditing() const
  313. {
  314.   TOcRemView* ocRemView = const_cast<TOleWindow*>(this)->GetOcRemView();
  315.   return ocRemView && ocRemView->GetState() == TOcRemView::OpenEditing;
  316. }
  317.  
  318. //
  319. // Handles the file File>Close menu option for server app
  320. //
  321. void
  322. TOleWindow::CeFileClose(TCommandEnabler& ce)
  323. {
  324.   // if open editing server, reflect the container's name in "close" option
  325.   //
  326.   if (IsOpenEditing()) {
  327.     string optName = GetModule()->LoadString(IDS_CLOSESERVER);
  328.     TString title = GetOcRemView()->GetContainerTitle();
  329.     if (title.Length() > 0)
  330.       optName += title;
  331.     ce.SetText(optName.c_str());
  332.   }
  333. }
  334.  
  335. //
  336. //
  337. //
  338. void
  339. TOleWindow::CeEditInsertObject(TCommandEnabler& ce)
  340. {
  341.   ce.Enable(OcApp && OcView);
  342. }
  343.  
  344. //
  345. // Get the insertion point for the embedded object in device units.
  346. // Currently we're using only the top left point for position, size is
  347. // redundant.
  348. //
  349. void
  350. TOleWindow::GetInsertPosition(TRect& rect)
  351. {
  352.   TOleClientDC dc(*this);
  353.  
  354.   // Default insertion point is at 0.5" away from current viewport origin
  355.   //
  356.   rect.left  = dc.GetDeviceCaps(LOGPIXELSX) / 2;  // in pixels
  357.   rect.top = dc.GetDeviceCaps(LOGPIXELSY) / 2;    // in pixels
  358.  
  359.   // Adjust the position of embedded object to be in pixels and reflect the
  360.   // zoom factor.
  361.   //
  362.   dc.LPtoDP((TPoint*)&rect, 1);
  363.  
  364.   // No size yet.
  365.   //
  366.   rect.right = rect.left;
  367.   rect.bottom = rect.top;
  368. }
  369.  
  370. //
  371. // Insert an OLE object into the view
  372. //
  373. void
  374. TOleWindow::CmEditInsertObject()
  375. {
  376.   PRECONDITION(OcView);
  377.   TOcInitInfo initInfo(OcView);
  378.  
  379.   if (OcApp->Browse(initInfo)) {
  380.     TRect rect;
  381.     GetInsertPosition(rect);
  382.     SetSelection(new TOcPart(*GetOcDoc(), initInfo, rect));
  383.  
  384.     OcView->Rename();
  385.     InvalidatePart(invView);
  386.   }
  387. }
  388.  
  389. void
  390. TOleWindow::CeEditDelete(TCommandEnabler& ce)
  391. {
  392.   ce.Enable(DragPart != 0);
  393. }
  394.  
  395. void
  396. TOleWindow::CmEditDelete()
  397. {
  398.   if (!DragPart)
  399.     return;
  400.  
  401.   TOcPartChangeInfo changeInfo(DragPart, invData|invView);
  402.   EvOcViewPartInvalid(changeInfo);
  403.  
  404.   DragPart->Delete();
  405.   DragPart = 0;
  406. }
  407.  
  408. void
  409. TOleWindow::CeEditCut(TCommandEnabler& ce)
  410. {
  411.   ce.Enable(DragPart != 0);
  412. }
  413.  
  414. void
  415. TOleWindow::CmEditCut()
  416. {
  417.   DragPart->Detach();
  418.   OcApp->Copy(DragPart);
  419.   SetSelection(0);
  420. }
  421.  
  422. void
  423. TOleWindow::CeEditCopy(TCommandEnabler& ce)
  424. {
  425.   ce.Enable(DragPart != 0);
  426. }
  427.  
  428. void
  429. TOleWindow::CmEditCopy()
  430. {
  431.   if (DragPart)
  432.     OcApp->Copy(DragPart);
  433. }
  434.  
  435. void
  436. TOleWindow::CeEditPasteLink(TCommandEnabler& ce)
  437. {
  438.   PRECONDITION(OcApp && OcView);
  439.   ce.Enable(OcApp->EnableEditMenu(meEnablePasteLink, OcView));
  440. }
  441.  
  442. void
  443. TOleWindow::CmEditPasteLink()
  444. {
  445.    OcView->Paste(true);
  446. }
  447.  
  448. void
  449. TOleWindow::CeEditPaste(TCommandEnabler& ce)
  450. {
  451.   PRECONDITION(OcApp && OcView);
  452.   ce.Enable(OcApp->EnableEditMenu(meEnablePaste, OcView));
  453. }
  454.  
  455. void
  456. TOleWindow::CmEditPaste()
  457. {
  458.    OcView->Paste(false);
  459.    InvalidatePart(invView);
  460. }
  461.  
  462. void
  463. TOleWindow::CeEditPasteSpecial(TCommandEnabler& ce)
  464. {
  465.   PRECONDITION(OcApp && OcView);
  466.   ce.Enable(OcApp->EnableEditMenu(meEnableBrowseClipboard, OcView));
  467. }
  468.  
  469. void
  470. TOleWindow::CmEditPasteSpecial()
  471. {
  472.   TOcInitInfo initInfo(GetOcView());
  473.  
  474.   if (GetOcView()->BrowseClipboard(initInfo)) {
  475.     if (!OcView->PasteNative(initInfo)) { // Not native data
  476.       EvOcViewPasteObject(initInfo);
  477.     }
  478.     InvalidatePart(invView);
  479.   }
  480. }
  481.  
  482. //
  483. // Append the object menu and enable it
  484. //
  485. void
  486. TOleWindow::CeEditObject(TCommandEnabler& ce)
  487. {
  488.   // Downcast to get at submenu item
  489.   //
  490.   TMenuItemEnabler* me = TYPESAFE_DOWNCAST(&ce, TMenuItemEnabler);
  491.   if (!me)
  492.     return;
  493.  
  494.   int verbPos = me->GetPosition(); // remember the verb menu position
  495.   TMenu editMenu(me->GetMenu());
  496.  
  497.   string optName = GetModule()->LoadString(IDS_EDITOBJECT);
  498.   if (!DragPart) {
  499.     // Remove the verb menu, if any
  500.     //
  501.     if (editMenu.GetSubMenu(verbPos)) {
  502.       editMenu.DeleteMenu(verbPos, MF_BYPOSITION);
  503.       editMenu.InsertMenu(verbPos, MF_GRAYED | MF_BYPOSITION | MF_STRING,
  504.             CM_EDITOBJECT, optName.c_str());
  505.     }
  506.     ce.Enable(false);
  507.     return;
  508.   }
  509.  
  510.   // Add verb menu
  511.   //
  512.   TOcVerb ocVerb;
  513.   TMenu* verbMenu = CreateVerbPopup(ocVerb);
  514.   string newMenuName(OleStr(ocVerb.TypeName));
  515.   newMenuName += ' ';
  516.   newMenuName += optName;
  517.   editMenu.ModifyMenu(verbPos, MF_ENABLED | MF_BYPOSITION | MF_POPUP,
  518.                       (uint)verbMenu->GetHandle(), newMenuName.c_str());
  519.   delete verbMenu;
  520.   ce.Enable(true);
  521. }
  522.  
  523. //
  524. // Command enabler for "Edit" "Convert..." option
  525. //
  526. void
  527. TOleWindow::CeEditConvert(TCommandEnabler& ce)
  528. {
  529.   ce.Enable(DragPart != 0);
  530. }
  531.  
  532. void
  533. TOleWindow::CmEditConvert()
  534. {
  535.   OcApp->Convert(DragPart, false);
  536. }
  537.  
  538. //
  539. // Command enabler for "Edit" "Links..." option
  540. //
  541. void
  542. TOleWindow::CeEditLinks(TCommandEnabler& ce)
  543. {
  544.   PRECONDITION(OcApp && OcView);
  545.   ce.Enable(OcApp->EnableEditMenu(meEnableBrowseLinks, OcView));
  546. }
  547.  
  548. void
  549. TOleWindow::CmEditLinks()
  550. {
  551.   PRECONDITION(OcView);
  552.   OcView->BrowseLinks();
  553. }
  554.  
  555. void
  556. TOleWindow::CeEditVerbs(TCommandEnabler& ce)
  557. {
  558.   ce.Enable(DragPart != 0);
  559. }
  560.  
  561. void
  562. TOleWindow::CmEditShowObjects()
  563. {
  564.   ShowObjects = !ShowObjects;
  565.   Invalidate();
  566. }
  567.  
  568. void
  569. TOleWindow::CeEditShowObjects(TCommandEnabler& ce)
  570. {
  571.   ce.SetCheck(ShowObjects ? TCommandEnabler::Checked : TCommandEnabler::Unchecked);
  572. }
  573.  
  574. //
  575. // Has in-place active part?
  576. //
  577. bool
  578. TOleWindow::HasActivePart()
  579. {
  580.   return OcView->GetActivePart() != 0;
  581. }
  582.  
  583. //
  584. // Change cursor shape if within an embedded object
  585. //
  586. bool
  587. TOleWindow::EvSetCursor(HWND wnd, uint hitTest, uint mouseMsg)
  588. {
  589.   TPoint pt;
  590.   GetCursorPos(pt);
  591.   ScreenToClient(pt);
  592.   TOcPart* p = OcView->GetActivePart();
  593.  
  594.   if (hitTest == HTCLIENT) {
  595.     if (p) {   // there is an activated part
  596.       TUIHandle handle(p->GetRect(), TUIHandle::Framed);
  597.       if (handle.HitTest(pt) == TUIHandle::MidCenter) {
  598.         return false; // let the inplace server set its cursor shape
  599.       }
  600.       else {   // use arrow cursor
  601.         ::SetCursor(::LoadCursor(0, IDC_ARROW));
  602.         return true;
  603.       }
  604.     }
  605.   }
  606.  
  607.   // Set cursor for resize when cursor over inactive part
  608.   //
  609.   if (!p && DragPart) {
  610.     TRect rect(DragPart->GetRect());
  611.     TOleClientDC dc(*this);
  612.     dc.LPtoDP((TPoint*)&rect, 2);
  613.  
  614.     TUIHandle handle(rect, TUIHandle::HandlesIn | TUIHandle::Grapples |
  615.                      TUIHandle::Framed);
  616.  
  617.     if (handle.HitTest(pt) != TUIHandle::Outside)
  618.       ::SetCursor(::LoadCursor(0, TResId(handle.GetCursorId(handle.HitTest(pt)))));
  619.     else
  620.       ::SetCursor(::LoadCursor(0, IDC_ARROW));
  621.  
  622.     return true;
  623.   }
  624.  
  625.   return ShowCursor(wnd, hitTest, mouseMsg);
  626. }
  627.  
  628. //
  629. // Show cursor when it's not in an embedded object
  630. //
  631. bool
  632. TOleWindow::ShowCursor(HWND /*wnd*/, uint /*hitTest*/, uint /*mouseMsg*/)
  633. {
  634.   ::SetCursor(::LoadCursor(0, IDC_ARROW));
  635.   return true;
  636. }
  637.  
  638. //
  639. // Accept dropped file from file manager
  640. //
  641. void
  642. TOleWindow::EvDropFiles(TDropInfo dropInfo)
  643. {
  644.   int fileCount = dropInfo.DragQueryFileCount();
  645.   for (int index = 0; index < fileCount; index++) {
  646.     int fileLength = dropInfo.DragQueryFileNameLen(index)+1;
  647.     OLECHAR* filePath = new OLECHAR[fileLength];
  648.     dropInfo.DragQueryFile(index, OleStr(filePath), fileLength);
  649.  
  650.     TOcInitInfo initInfo(ihEmbed, iwFile, OcView);
  651.     initInfo.Path = filePath;
  652.  
  653.     TRect rect;
  654.     GetInsertPosition(rect);
  655.     SetSelection(new TOcPart(*GetOcDoc(), initInfo, rect));
  656.  
  657.     OcView->Rename();
  658.     InvalidatePart(invView);
  659.  
  660.     delete [] filePath;
  661.   }
  662.   dropInfo.DragFinish();
  663. }
  664.  
  665. //
  666. // Handle left double-click message
  667. //
  668. void
  669. TOleWindow::EvLButtonDblClk(uint modKeys, TPoint& point)
  670. {
  671.   PRECONDITION(GetOcDoc() && GetOcView());
  672.   TOleClientDC dc(*this);
  673.   dc.DPtoLP(&point);
  674.  
  675.   TOcPart* p = GetOcDoc()->GetParts().Locate(point);
  676.  
  677.   if (modKeys & MK_CONTROL) {
  678.     if (p)
  679.       p->Open(true);  // Ctrl key forces open editing
  680.   }
  681.   else {
  682.     SetSelection(p);
  683.  
  684.     if (p && p == GetOcView()->GetActivePart()) { // resync the active flag
  685.       p->Activate(false);
  686.     }
  687.  
  688.     GetOcView()->ActivatePart(p); // In-place activation
  689.   }
  690. }
  691.  
  692. //
  693. // Set new selection, clear/set handles around objects
  694. //
  695. void
  696. TOleWindow::SetSelection(TOcPart* part)
  697. {
  698.   if (part == DragPart)
  699.     return;
  700.  
  701.   // Invalidate old part
  702.   //
  703.   TOcPartChangeInfo changeInfo(DragPart, invView);
  704.   if (DragPart) {
  705.     DragPart->Select(false);
  706.     DragPart->Activate(false);
  707.     EvOcViewPartInvalid(changeInfo);
  708.   }
  709.  
  710.   DragPart = part;
  711.   changeInfo.SetPart(DragPart);
  712.   if (DragPart) {
  713.     part->Select(true); // select this one
  714.     EvOcViewPartInvalid(changeInfo);
  715.   }
  716. }
  717.  
  718. //
  719. // Create popup menu
  720. //
  721. void
  722. TOleWindow::EvRButtonDown(uint, TPoint& point)
  723. {
  724.   PRECONDITION(GetOcDoc());
  725.  
  726.   // Perform hit test on parts...
  727.   //
  728.   TPoint oldPoint = point;
  729.   TOleClientDC dc(*this);
  730.   dc.DPtoLP(&point);
  731.  
  732.   TOcPart* p = GetOcDoc()->GetParts().Locate(point);
  733.   SetSelection(p);
  734.  
  735.   if (DragPart) {
  736.     // Create popup menu
  737.     //
  738.     TMenu menu(GetModule()->LoadMenu(IDM_OLEPOPUP), AutoDelete);
  739.     TPopupMenu popMenu(menu.GetSubMenu(0));
  740.  
  741.     if (popMenu.GetHandle()) {
  742.       TOcVerb ocVerb;
  743.       TMenu* verbMenu = CreateVerbPopup(ocVerb);
  744.  
  745.       string optName = GetModule()->LoadString(IDS_EDITOBJECT);
  746.       string newMenuName(OleStr(ocVerb.TypeName));
  747.       newMenuName += ' ';
  748.       newMenuName += optName;
  749.       popMenu.ModifyMenu(CM_EDITOBJECT, MF_ENABLED | MF_BYCOMMAND | MF_POPUP,
  750.                          (uint)verbMenu->GetHandle(), newMenuName.c_str());
  751.       delete verbMenu;
  752.  
  753.       // Add the verb menu
  754.       //
  755.       ClientToScreen(oldPoint);
  756.  
  757.       // Route commands through main window
  758.       //
  759.       popMenu.TrackPopupMenu(TPM_RIGHTBUTTON, oldPoint, 0, *this);
  760.     }
  761.   }
  762. }
  763.  
  764. //
  765. // Deactivate active embedded object if any
  766. //
  767. bool
  768. TOleWindow::Deactivate()
  769. {
  770.   // Deactivate active part, if any
  771.   //
  772.   if (DragPart && DragPart->IsActive()) {
  773.     SetSelection(0);
  774.     return true;
  775.   }
  776.   else
  777.     return false;
  778. }
  779.  
  780. //
  781. // Select embedded object, point is in logical units
  782. //
  783. bool
  784. TOleWindow::Select(uint, TPoint& point)
  785. {
  786.   PRECONDITION(GetOcDoc());
  787.  
  788.   // If the point is not on the current selection, perform hit test on parts
  789.   // to find & select one
  790.   //
  791.   if (!DragPart || !DragPart->IsVisible(TRect(point, TSize(1,1))))
  792.     SetSelection(GetOcDoc()->GetParts().Locate(point));
  793.  
  794.   // If a part is now selected, manipulate it.
  795.   //
  796.   if (DragPart) {
  797.     DragRect = DragPart->GetRect();
  798.     DragRect.right++;
  799.     DragRect.bottom++;
  800.     if (DragPart->IsSelected()) {
  801.       TUIHandle handle(DragRect, TUIHandle::HandlesIn | TUIHandle::Grapples |
  802.                        TUIHandle::Framed);
  803.       DragHit = handle.HitTest(point);
  804.     }
  805.     else {
  806.       DragHit = TUIHandle::MidCenter;
  807.     }
  808.  
  809.     if (!DragDC)
  810.       DragDC = new TOleClientDC(*this);
  811.     DragDC->DrawFocusRect(DragRect);
  812.  
  813.     DragStart = DragPt = point;
  814.     SetCapture();
  815.  
  816.     return true;
  817.   }
  818.  
  819.   return false;
  820. }
  821.  
  822. //
  823. // Check if any embedded object is selected
  824. //
  825. void
  826. TOleWindow::EvLButtonDown(uint modKeys, TPoint& point)
  827. {
  828.   // Deactivating in-place active object, if any
  829.   //
  830.   if (Deactivate())
  831.     return;
  832.  
  833.   // Convert the point to logical unit
  834.   //
  835.   if (!DragDC)
  836.     DragDC = new TOleClientDC(*this);
  837.  
  838.   DragDC->DPtoLP(&point);
  839.   Select(modKeys, point);
  840. }
  841.  
  842. //
  843. // Is the logical point within the client area?
  844. //
  845. bool
  846. TOleWindow::InClient(TDC& dc, TPoint& point)
  847. {
  848.   TRect logicalRect = GetClientRect();
  849.  
  850.   dc.DPtoLP((TPoint*)&logicalRect, 2);
  851.   return logicalRect.Contains(point);
  852. }
  853.  
  854. //
  855. //
  856. //
  857. void
  858. TOleWindow::EvMouseMove(uint modKeys, TPoint& point)
  859. {
  860.   if (!DragDC)
  861.     return;
  862.  
  863.   // Convert the point to logical unit
  864.   //
  865.   DragDC->DPtoLP(&point);
  866.  
  867.   // A MidCenter hit is a move
  868.   //
  869.   if (DragHit == TUIHandle::MidCenter) {
  870.     DragDC->DrawFocusRect(DragRect);   // erase old rect
  871.  
  872.     // Account for case when the hand is a little shaky and a double click for
  873.     // open editing generates a move msg. as a side-effect
  874.     //
  875.     bool force = ((modKeys & MK_CONTROL) || (::GetKeyState(VK_MENU)&0x8000)) &&
  876.                   (abs(point.x-DragStart.x) > DblClkDelta.cx ||
  877.                    abs(point.y-DragStart.y) > DblClkDelta.cy);
  878.  
  879.     // Start drag & drop if point is outside client, or Ctrl or Alt is pressed
  880.     //
  881.     if (DragPart && (!InClient(*DragDC, point) || force)) {
  882.       TOcDropAction outAction;
  883.       OcApp->Drag(DragPart, daDropCopy | daDropMove | daDropLink, outAction);
  884.  
  885.       TOcPartChangeInfo changeInfo(DragPart, invView | invData);
  886.       EvOcViewPartInvalid(changeInfo);
  887.       DragHit = TUIHandle::Outside;
  888.       ReleaseCapture();
  889.  
  890.       // Delete the dragged part since it was dragged out
  891.       //
  892.       if (outAction == daDropMove) {
  893.         DragPart->Delete();
  894.         DragPart = 0;
  895.       }
  896.     }
  897.     else {
  898.       TPoint delta = point - DragPt;
  899.       DragRect.Offset(delta.x, delta.y);
  900.       DragDC->DrawFocusRect(DragRect);   // draw new rect
  901.     }
  902.   }
  903.   // All other non-outside hits are resizes
  904.   //
  905.   else if (DragHit != TUIHandle::Outside) { // handle
  906.     DragDC->DrawFocusRect(DragRect);   // erase old rect
  907.     int dl = (DragHit%3) == 0 ? point.x - DragPt.x : 0;
  908.     int dr = (DragHit%3) == 2 ? point.x - DragPt.x : 0;
  909.     int dt = (DragHit/3) == 0 ? point.y - DragPt.y : 0;
  910.     int db = (DragHit/3) == 2 ? point.y - DragPt.y : 0;
  911.  
  912.     // maintain minimum part size
  913.     //
  914.     if ((DragRect.Width() + dr - dl) >= MinWidth) {
  915.       DragRect.left += dl;
  916.       DragRect.right += dr;
  917.     }
  918.     if ((DragRect.Height() + db - dt) >= MinHeight) {
  919.       DragRect.top  += dt;
  920.       DragRect.bottom += db;
  921.     }
  922.  
  923.     DragDC->DrawFocusRect(DragRect);   // draw new rect
  924.   }
  925.  
  926.   DragPt = point;
  927. }
  928.  
  929. void
  930. TOleWindow::EvLButtonUp(uint /*modKeys*/, TPoint& /*point*/)
  931. {
  932.   if (DragPart) {
  933.     TOcPartChangeInfo changeInfo(DragPart, invView | invData);
  934.  
  935.     // All non-outside hits are moves or resizes
  936.     //
  937.     if (DragHit != TUIHandle::Outside) {
  938.       EvOcViewPartInvalid(changeInfo);
  939.       DragPart->SetPos(DragRect.TopLeft());
  940.       if (DragHit != TUIHandle::MidCenter)
  941.         DragPart->SetSize(DragRect.Size());  // A MidCenter hit is a move only
  942.       EvOcViewPartInvalid(changeInfo);
  943.     }
  944.     InvalidatePart(invView);
  945.  
  946.     DragHit = TUIHandle::Outside;
  947.     ReleaseCapture();
  948.   }
  949.  
  950.   if (DragDC) {
  951.     delete DragDC;
  952.     DragDC = 0;
  953.     DragRect.SetNull();
  954.   }
  955. }
  956.  
  957. //
  958. // Let OcView know that the view window has changed sizes
  959. //
  960. void
  961. TOleWindow::EvSize(uint sizeType, TSize& size)
  962. {
  963.   TWindow::EvSize(sizeType, size);
  964.   OcView->EvResize();
  965. }
  966.  
  967. //
  968. // Handle message forwarded from our mdi child frame (if any) to let OcView
  969. // know that the view window has changed size
  970. //
  971. void
  972. TOleWindow::EvMDIActivate(HWND hWndActivated, HWND /*hWndDeactivated*/)
  973. {
  974.   OcView->EvActivate(hWndActivated == *Parent);
  975. }
  976.  
  977. uint
  978. TOleWindow::EvMouseActivate(HWND topParent, uint /*hitCode*/, uint /*msg*/)
  979. {
  980.   if (topParent)
  981.     ForwardMessage(topParent);
  982.  
  983.   return MA_ACTIVATE;
  984. }
  985.  
  986. //
  987. // May need to pass focus to an in-place server if there is one
  988. //
  989. void
  990. TOleWindow::EvSetFocus(HWND hWndLostFocus)
  991. {
  992.   TWindow::EvSetFocus(hWndLostFocus);
  993.   OcView->EvSetFocus(true); // Maybe active part (if any) wants focus
  994. }
  995.  
  996. //
  997. // response method for an incoming WM_VSCROLL message
  998. //
  999. void
  1000. TOleWindow::EvHScroll(uint scrollCode, uint thumbPos, HWND hWndCtl)
  1001. {
  1002.   TWindow::EvHScroll(scrollCode, thumbPos, hWndCtl);
  1003.  
  1004.   InvalidatePart(invView);
  1005. }
  1006.  
  1007. //
  1008. // response method for an incoming WM_VSCROLL message
  1009. //
  1010. void
  1011. TOleWindow::EvVScroll(uint scrollCode, uint thumbPos, HWND hWndCtl)
  1012. {
  1013.   TWindow::EvVScroll(scrollCode, thumbPos, hWndCtl);
  1014.  
  1015.   InvalidatePart(invView);
  1016. }
  1017.  
  1018. //
  1019. // Handle WM_MENUSELECT to provide hint text in the container's status bar
  1020. // based on the menu item id. Treat popup items seperatly and ask them for
  1021. // their ids. Similar to code in TDecoratedFrame.
  1022. //
  1023. void
  1024. TOleWindow::EvMenuSelect(uint menuItemId, uint flags, HMENU hMenu)
  1025. {
  1026.  
  1027.   if (GetOcRemView()) {
  1028.     if (flags == 0xFFFF && hMenu == 0) {  // menu closing
  1029.       GetOcRemView()->SetContainerStatusText("");
  1030.       return;
  1031.     }
  1032.     else if (flags & MF_POPUP) {
  1033.       TMenu popupMenu(hMenu);
  1034.       int   count = popupMenu.GetMenuItemCount();
  1035.       for (int pos = 0;
  1036.            pos < count && popupMenu.GetSubMenu(pos) != HMENU(menuItemId);
  1037.            pos++)
  1038.         ;
  1039.       menuItemId = popupMenu.GetMenuItemID(pos);
  1040.     }
  1041.     else if (flags & (MF_SEPARATOR | MF_MENUBREAK | MF_MENUBARBREAK)
  1042.       || (menuItemId >= IDW_FIRSTMDICHILD && menuItemId < IDW_FIRSTMDICHILD+9)) {
  1043.       menuItemId = 0;  // display an empty help message
  1044.     }
  1045.     string text = GetModule()->LoadString(menuItemId);
  1046.     GetOcRemView()->SetContainerStatusText(text.c_str());
  1047.   }
  1048.   else
  1049.     TWindow::EvMenuSelect(menuItemId, flags, hMenu);
  1050. }
  1051.  
  1052. //
  1053. // Handle & sub-dispatch the OC event message.
  1054. //
  1055. LRESULT
  1056. TOleWindow::EvOcEvent(WPARAM wParam, LPARAM lParam)
  1057. {
  1058.   TEventHandler::TEventInfo eventInfo(WM_OCEVENT, wParam);
  1059.   if (Find(eventInfo))
  1060.     return Dispatch(eventInfo, wParam, lParam);
  1061.   return 0;
  1062. }
  1063.  
  1064. //
  1065. // Return our frame's title
  1066. //
  1067. const char far*
  1068. TOleWindow::EvOcViewTitle()
  1069. {
  1070.   char title[128];
  1071.   Parent->GetWindowText(title, sizeof title);
  1072.   ContainerName = title;
  1073.  
  1074.   return ContainerName.c_str();
  1075. }
  1076.  
  1077. //
  1078. // Set our frame's title
  1079. //
  1080. void
  1081. TOleWindow::EvOcViewSetTitle(const char far* title)
  1082. {
  1083.   Parent->SetWindowText(title);
  1084. }
  1085.  
  1086. //
  1087. // Can the server put toolbars in our view? Say no--make him use the app frame
  1088. //
  1089. bool
  1090. TOleWindow::EvOcViewBorderSpaceReq(TRect far* /*space*/)
  1091. {
  1092.   return false;
  1093. }
  1094.  
  1095. //
  1096. // Can the server put toolbars in our view? Say no--make him use the app frame
  1097. //
  1098. bool
  1099. TOleWindow::EvOcViewBorderSpaceSet(TRect far* /*space*/)
  1100. {
  1101.   return false;
  1102. }
  1103.  
  1104. //
  1105. // Can the indicated ole object be dropped here? Say yes to everything as a
  1106. // default
  1107. //
  1108. bool
  1109. TOleWindow::EvOcViewDrop(TOcDragDrop far& /*ddInfo*/)
  1110. {
  1111.   return true;    // ok to drop anything, we can take it...
  1112. }
  1113.  
  1114. //
  1115. // Provide drag UI feedback
  1116. //
  1117. bool
  1118. TOleWindow::EvOcViewDrag(TOcDragDrop far& ddInfo)
  1119. {
  1120.   TClientDC dc(*this);
  1121.   TPen pen(TColor(128, 128, 128), 4, PS_DOT);
  1122.   dc.SelectObject(pen);
  1123.   dc.SelectStockObject(HOLLOW_BRUSH);
  1124.   dc.SetROP2(R2_NOTXORPEN);
  1125.  
  1126.   dc.Rectangle(*ddInfo.Pos);
  1127.   return true;
  1128. }
  1129.  
  1130. //
  1131. // Scroll our view window. Update any internal state as needed. This is called
  1132. // when the server is sizing, or a drop interaction is near the edge
  1133. //
  1134. bool
  1135. TOleWindow::EvOcViewScroll(TOcScrollDir /*scrollDir*/)
  1136. {
  1137.   return false;
  1138. }
  1139.  
  1140. //
  1141. // Convert the part rect into device units
  1142. //
  1143. bool
  1144. TOleWindow::EvOcViewGetSiteRect(TRect far* rect)
  1145. {
  1146.   TOleClientDC dc(*this);
  1147.  
  1148.   return dc.LPtoDP((TPoint*)rect, 2);
  1149. }
  1150.  
  1151. //
  1152. // Convert the part rect into logical units
  1153. //
  1154. bool
  1155. TOleWindow::EvOcViewSetSiteRect(TRect far* rect)
  1156. {
  1157.   TOleClientDC dc(*this);
  1158.  
  1159.   return dc.DPtoLP((TPoint*)rect, 2);
  1160. }
  1161.  
  1162. //
  1163. // Handle the scaling for server app
  1164. //
  1165. bool
  1166. TOleWindow::EvOcViewGetScale(TOcScaleFactor& scaleFactor)
  1167. {
  1168.   scaleFactor = Scale;
  1169.   return true;
  1170. }
  1171.  
  1172. //
  1173. // Handle the scaling for server app
  1174. //
  1175. bool
  1176. TOleWindow::EvOcViewPartActivate(TOcPart& ocPart)
  1177. {
  1178.   SetSelection(&ocPart);
  1179.   return true;
  1180. }
  1181.  
  1182. //
  1183. // Handle the scaling for server app
  1184. //
  1185. bool
  1186. TOleWindow::EvOcViewPasteObject(TOcInitInfo& init)
  1187. {
  1188.   TRect rect;
  1189.   GetInsertPosition(rect);
  1190.   new TOcPart(*GetOcDoc(), init, rect);
  1191.   init.ReleaseDataObject();
  1192.   return true;
  1193. }
  1194.  
  1195. //
  1196. // Ask server to paint itself in the position and dc provided
  1197. //
  1198. bool
  1199. TOleWindow::EvOcViewPaint(TOcViewPaint far& vp)
  1200. {
  1201.   // paint according to the view paint structure
  1202.   //
  1203.   TDC dc(vp.DC);
  1204.   Pos = *vp.Pos;
  1205.  
  1206.   // Paint embedded objects
  1207.   //
  1208.  
  1209.   bool metafile = dc.GetDeviceCaps(TECHNOLOGY) == DT_METAFILE;
  1210.   SetupDC(dc, !metafile);
  1211.  
  1212.   if (vp.Moniker) {
  1213.     PaintLink(dc, true, Pos, *vp.Moniker);
  1214.   }
  1215.   else if (vp.PaintSelection) {
  1216.     PaintSelection(dc, true, Pos, vp.UserData);
  1217.   }
  1218.   else {
  1219.     Paint(dc, true, Pos);
  1220.     PaintParts(dc, true, Pos, metafile);
  1221.   }
  1222.  
  1223.   Pos.SetNull();
  1224.  
  1225.   return true;
  1226. }
  1227.  
  1228. //
  1229. // TOcRemView is going away, disconnect TOleWindow with it so we don't use it
  1230. // later. If this is a remote view, then close the doc too.
  1231. //
  1232. bool
  1233. TOleWindow::EvOcViewClose()
  1234. {
  1235.   if (IsRemote() && OcDoc)
  1236.     OcDoc->Close();
  1237.  
  1238.   OcView = 0;
  1239.   return true;
  1240. }
  1241.  
  1242. //
  1243. // Ask server to save itself in the IStorage
  1244. //
  1245. bool
  1246. TOleWindow::EvOcViewSavePart(TOcSaveLoad far& /*ocSave*/)
  1247. {
  1248.   return true;
  1249. }
  1250.  
  1251. //
  1252. // Ask server to load itself from the IStorage
  1253. //
  1254. bool
  1255. TOleWindow::EvOcViewLoadPart(TOcSaveLoad far& /*ocLoad*/)
  1256. {
  1257.   return true;
  1258. }
  1259.  
  1260. //
  1261. // Let container know about the server view size in pixels
  1262. //
  1263. bool
  1264. TOleWindow::EvOcViewPartSize(TOcPartSize far& /*size*/)
  1265. {
  1266.   return false;
  1267. }
  1268.  
  1269. //
  1270. // Ask container to open an existing document
  1271. // Used for linking from embedding
  1272. //
  1273. bool
  1274. TOleWindow::EvOcViewOpenDoc(const char far* /*path*/)
  1275. {
  1276.   return true;
  1277. }
  1278.  
  1279. //
  1280. // Insert server menu into the composite one
  1281. //
  1282. bool
  1283. TOleWindow::EvOcViewInsMenus(TOcMenuDescr far& /*sharedMenu*/)
  1284. {
  1285.   return false;
  1286. }
  1287.  
  1288. //
  1289. // Request for server to put up its toolbar. This implementation assume that
  1290. // this server is single use, and the MainWindow's ToolBar is ours to snarf
  1291. //
  1292. bool
  1293. TOleWindow::EvOcViewShowTools(TOcToolBarInfo far& tbi)
  1294. {
  1295.   TWindow* mainWindow = GetApplication()->GetMainWindow();
  1296.   CHECK(mainWindow);
  1297.   TWindow* toolBar = mainWindow->ChildWithId(IDW_TOOLBAR);
  1298.   if (!toolBar)
  1299.     return false;
  1300.   tbi.HTopTB = (HWND)*toolBar;
  1301.   return true;
  1302. }
  1303.  
  1304. //
  1305. // Get server's color palette
  1306. //
  1307. bool
  1308. TOleWindow::EvOcViewGetPalette(LOGPALETTE far* far* /*palette*/)
  1309. {
  1310.   return false;
  1311. }
  1312.  
  1313. //
  1314. // Ask server to provide data according to the format in a handle
  1315. //
  1316. bool
  1317. TOleWindow::EvOcViewClipData(TOcFormatData far& /*format*/)
  1318. {
  1319.   return false;
  1320. }
  1321.  
  1322. //
  1323. // Set format data into server
  1324. //
  1325. bool
  1326. TOleWindow::EvOcViewSetData(TOcFormatData far& /*format*/)
  1327. {
  1328.   return false;
  1329. }
  1330.  
  1331. //
  1332. // Paint the embedded objects
  1333. //
  1334. bool
  1335. TOleWindow::PaintParts(TDC& dc, bool, TRect&, bool metafile)
  1336. {
  1337.   if (!GetOcDoc())
  1338.     return false;
  1339.  
  1340.   TRect clientRect;
  1341.   TRect logicalRect = GetClientRect();
  1342.  
  1343.   if (IsRemote()) {
  1344.     clientRect = GetWindowRect();
  1345.     clientRect.Offset(-clientRect.left, -clientRect.top);
  1346.   }
  1347.   else {
  1348.     clientRect = logicalRect;
  1349.   }
  1350.  
  1351.   TPoint scrollPos(0, 0);
  1352.  
  1353.   if (!metafile) {
  1354.     dc.DPtoLP((TPoint*)&logicalRect, 2);
  1355.   }
  1356.   else {
  1357.     if (Scroller) {
  1358.       scrollPos.x = (int)Scroller->XPos;
  1359.       scrollPos.y = (int)Scroller->YPos;
  1360.     }
  1361.   }
  1362.  
  1363.   for (TOcPartCollectionIter i(GetOcDoc()->GetParts()); i; i++) {
  1364.     TOcPart& p = *i.Current();
  1365.     if (p.IsVisible(logicalRect) || metafile) {
  1366.       TRect r = p.GetRect();
  1367.       r.Offset(-scrollPos.x, -scrollPos.y);
  1368.       p.Draw(dc, r, clientRect, asDefault);
  1369.  
  1370.       if (metafile)
  1371.         continue;
  1372.  
  1373.       // Paint selection
  1374.       //
  1375.       if ((p.IsSelected() || ShowObjects) && r.Width() > 0 && r.Height() > 0) {
  1376.         uint handleStyle = p.IsLink() ? TUIHandle::DashFramed : TUIHandle::Framed;
  1377.         if (p.IsSelected())
  1378.           handleStyle |= TUIHandle::Grapples;
  1379.         TUIHandle(r, handleStyle).Paint(dc);
  1380.       }
  1381.     }
  1382.   }
  1383.   return true;
  1384. }
  1385.  
  1386. //
  1387. // Change the scaling factor
  1388. //
  1389. void
  1390. TOleWindow::SetScale(uint16 percent)
  1391. {
  1392.   Scale.SetScale(percent);
  1393.   Invalidate();
  1394. }
  1395.  
  1396. //
  1397. // Get the logical unit per inch for document
  1398. //
  1399. void
  1400. TOleWindow::GetLogPerUnit(TSize& logPerUnit)
  1401. {
  1402.   TScreenDC dc;
  1403.  
  1404.   logPerUnit.cx = dc.GetDeviceCaps(LOGPIXELSX);
  1405.   logPerUnit.cy = dc.GetDeviceCaps(LOGPIXELSY);
  1406. }
  1407.  
  1408. //
  1409. // Setup the dc before painting
  1410. //
  1411. void
  1412. TOleWindow::SetupDC(TDC& dc, bool scale)
  1413. {
  1414.   dc.SetMapMode(MM_ANISOTROPIC);
  1415.  
  1416.   // Setup window and viewport origin according to scroll amount
  1417.   //
  1418.   TPoint scrollPos(0, 0);
  1419.   if (Scroller) {
  1420.     scrollPos.x = (int)Scroller->XPos;
  1421.     scrollPos.y = (int)Scroller->YPos;
  1422.   }
  1423.  
  1424.   if (!scale) {
  1425.     dc.SetWindowOrg(scrollPos);
  1426.     return;
  1427.   }
  1428.  
  1429.   // Don't scale the scrolling amount
  1430.   //
  1431.   if (Scale.SiteSize.cx)
  1432.     scrollPos.x = (int)(((uint32)scrollPos.x * Scale.PartSize.cx +
  1433.                         Scale.SiteSize.cx/2) / Scale.SiteSize.cx);
  1434.   if (Scale.SiteSize.cy)
  1435.     scrollPos.y = (int)(((uint32)scrollPos.y * Scale.PartSize.cy +
  1436.                         Scale.SiteSize.cy/2) / Scale.SiteSize.cy);
  1437.   dc.SetWindowOrg(scrollPos);
  1438.  
  1439.   dc.SetViewportOrg(Pos.TopLeft());
  1440.  
  1441.   // set the window and viewport extaccording to zoom factor
  1442.   //
  1443.   TSize ext;
  1444.   GetLogPerUnit(ext);
  1445.   dc.SetWindowExt(ext);
  1446.  
  1447.   ext.cx = dc.GetDeviceCaps(LOGPIXELSX);
  1448.   ext.cy = dc.GetDeviceCaps(LOGPIXELSY);
  1449.  
  1450.   if (Scale.PartSize.cx)
  1451.     ext.cx = (int)(((uint32)ext.cx * Scale.SiteSize.cx + Scale.PartSize.cx/2) /
  1452.                    Scale.PartSize.cx);
  1453.   if (Scale.PartSize.cy)
  1454.     ext.cy = (int)(((uint32)ext.cy * Scale.SiteSize.cy + Scale.PartSize.cy/2) /
  1455.                    Scale.PartSize.cy);
  1456.   dc.SetViewportExt(ext);
  1457. }
  1458.  
  1459. //
  1460. // response method for an incoming WM_PAINT message
  1461. //
  1462. void
  1463. TOleWindow::EvPaint()
  1464. {
  1465.   if (IsFlagSet(wfAlias))
  1466.     DefaultProcessing();  // use application-defined wndproc
  1467.  
  1468.   else {
  1469.     TPaintDC dc(*this);
  1470.     TRect&   rect = *(TRect*)&dc.Ps.rcPaint;
  1471.  
  1472.     if (Scroller)
  1473.       Scroller->BeginView(dc, rect);
  1474.  
  1475.     bool metafile = dc.GetDeviceCaps(TECHNOLOGY) == DT_METAFILE;
  1476.     SetupDC(dc, !metafile);
  1477.     Paint(dc, dc.Ps.fErase, rect);
  1478.     PaintParts(dc, dc.Ps.fErase, rect, metafile);
  1479.  
  1480.     if (Scroller)
  1481.       Scroller->EndView();
  1482.   }
  1483. }
  1484.  
  1485. //
  1486. // Notify the active view of part data changes
  1487. //
  1488. bool
  1489. TOleWindow::EvOcViewPartInvalid(TOcPartChangeInfo& changeInfo)
  1490. {
  1491.   // Our document is now dirty...
  1492.  
  1493.   // Reflect the change in part in other (non-active) views
  1494.   //
  1495.   TRect rect(changeInfo.GetPart()->GetRect());
  1496.   rect.right++;
  1497.   rect.bottom++;
  1498.   TOleClientDC dc(*this);
  1499.   dc.LPtoDP((TPoint*)&rect, 2);
  1500.  
  1501.   InvalidateRect(rect);  // Multiview support to be done in derived classes
  1502.  
  1503.   // Notify container if this is an intermediate container
  1504.   //
  1505.   InvalidatePart((TOcInvalidate)changeInfo.GetType());
  1506.  
  1507.   return true; // stop further processing by OCF
  1508. }
  1509.  
  1510. //
  1511. //
  1512. //
  1513. TPopupMenu*
  1514. TOleWindow::CreateVerbPopup(const TOcVerb& ocVerb)
  1515. {
  1516.   TPopupMenu* verbMenu = new TPopupMenu(NoAutoDelete);
  1517.   while (DragPart->EnumVerbs(ocVerb)) {
  1518.     verbMenu->AppendMenu(MF_STRING|MF_ENABLED,
  1519.                          (uint)CM_EDITFIRSTVERB + ocVerb.VerbIndex,
  1520.                          (const char far*)OleStr(ocVerb.VerbName));
  1521.   }
  1522.  
  1523.   verbMenu->AppendMenu(MF_SEPARATOR, 0, 0);
  1524.   string optName = GetModule()->LoadString(IDS_EDITCONVERT);
  1525.   verbMenu->AppendMenu(MF_STRING, CM_EDITCONVERT, optName.c_str());
  1526.  
  1527.   return verbMenu;
  1528. }
  1529.  
  1530. //
  1531. // Execute a verb pertaining to the selected object
  1532. //
  1533. void
  1534. TOleWindow::EvDoVerb(uint whichVerb)
  1535. {
  1536.   DragPart->DoVerb(whichVerb);
  1537. }
  1538.  
  1539. //
  1540. // Attach this view back to its owl parent for either open editing, or
  1541. // mearly inplace de-activating
  1542. //
  1543. bool
  1544. TOleWindow::EvOcViewAttachWindow(bool attach)
  1545. {
  1546.   TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
  1547.                                             TOleFrame);
  1548.   if (!mainWindow)
  1549.     return false;  // server app is shutting down
  1550.  
  1551.   if (attach) {
  1552.     if (IsOpenEditing()) {
  1553.       // Derived class needs to managed setting up frame differently, like
  1554.       // for MDI etc.
  1555.       //
  1556.       mainWindow->SetClientWindow(this);
  1557.     }
  1558.   }
  1559.   else {
  1560.     if (IsOpenEditing() && Parent != mainWindow)
  1561.       Parent->PostMessage(WM_CLOSE);
  1562.     SetParent(mainWindow->GetRemViewBucket());  // simple reparent
  1563.   }
  1564.   return true;
  1565. }
  1566.  
  1567. //
  1568. // Perform the action indentified by verb
  1569. //
  1570. bool
  1571. TOleWindow::EvOcViewDoVerb(uint /*verb*/)
  1572. {
  1573.   return false;
  1574. }
  1575.  
  1576.  
  1577. //
  1578. // Shut down the associated OCF partners if possible
  1579. //
  1580. bool
  1581. TOleWindow::OleShutDown()
  1582. {
  1583.   if (IsRemote()) {
  1584.     TOcRemView* ocRemView = GetOcRemView();
  1585.     if (IsOpenEditing())
  1586.       ocRemView->Disconnect();
  1587.   }
  1588.   else {
  1589.     if (OcView)
  1590.       OcView->EvClose();
  1591.   }
  1592.   return true;
  1593. }
  1594.  
  1595. //
  1596. // Perform normal CleanupWindow, plus let the OcView object know we have closed
  1597. //
  1598. void
  1599. TOleWindow::CleanupWindow()
  1600. {
  1601.   TOleFrame* mainWindow = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(),
  1602.                                             TOleFrame);
  1603.  
  1604.   if (mainWindow)
  1605.     mainWindow->OleViewClosing(true);
  1606.   OleShutDown();
  1607.   if (mainWindow)
  1608.     mainWindow->OleViewClosing(false);
  1609.   TWindow::CleanupWindow();
  1610. }
  1611.  
  1612. static void
  1613. DoIdleAction(TWindow* win, void* idleCount)
  1614. {
  1615.   win->IdleAction(*(long*)idleCount);
  1616. }
  1617.  
  1618. //
  1619. // TOleWindow processes idle action occurs once per block of messages
  1620. //
  1621. bool
  1622. TOleWindow::IdleAction(long idleCount)
  1623. {
  1624.   if (idleCount == 0) {
  1625.     // give child windows an opportunity to do any idle processing
  1626.     //
  1627.     ForEach(DoIdleAction, &idleCount);
  1628.   }
  1629.   return false;  // we don't need any more time for now
  1630. }
  1631.  
  1632. //
  1633. // Handle the scaling for server app
  1634. //
  1635. bool
  1636. TOleWindow::EvOcViewSetScale(TOcScaleFactor& scaleFactor)
  1637. {
  1638.   Scale = scaleFactor;
  1639.   return true;
  1640. }
  1641.  
  1642. //
  1643. // Find the item name for whole doc or selection
  1644. //
  1645. bool
  1646. TOleWindow::EvOcViewGetItemName(TOcItemName& /*item*/)
  1647. {
  1648.   return false;
  1649. }
  1650.  
  1651. //----------------------------------------------------------------------------
  1652. // Linking Spport
  1653. //
  1654.  
  1655. //
  1656. // Establish link with whole doc or selection
  1657. //
  1658. bool
  1659. TOleWindow::EvOcViewSetLink(TOcLinkView& /*view*/)
  1660. {
  1661.   return false;
  1662. }
  1663.  
  1664. //
  1665. // Break link with whole doc or selection
  1666. //
  1667. bool
  1668. TOleWindow::EvOcViewBreakLink(TOcLinkView& /*view*/)
  1669. {
  1670.   return false;
  1671. }
  1672.