Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2301 lines
62 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ctr.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: Implements the Ole Container object for the future splash
  8. // Animation control.
  9. //
  10. // Copyright (c) 1998-1999 Microsoft Corporation
  11. //
  12. // Author: nickball Created 02/10/98
  13. //
  14. //+----------------------------------------------------------------------------
  15. #include "cmmaster.h"
  16. /*
  17. #define STRICT
  18. */
  19. // macros used to reduce verbiage in RECT handling.
  20. #define WIDTH(r) (r.right - r.left)
  21. #define HEIGHT(r) (r.bottom - r.top)
  22. // max size for LoadString.
  23. // string constants
  24. const WCHAR g_awchHostName[] = L"ICM FS OC Container";
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: LinkToOle32
  28. //
  29. // Synopsis: Initializes the specified Ole32Linkage by linking to the DLL
  30. // specified in pszOle32 and retrieving the proc address for the
  31. // functions that we need to call
  32. //
  33. // Arguments: pOle32Link - ptr to Ole32LinkagStruct
  34. // pszOl32 - ptr DLL name string
  35. //
  36. // Returns: TRUE if SUCCESS
  37. // FALSE otherwise.
  38. //
  39. // History: nickball Created 8/14/97
  40. //
  41. //----------------------------------------------------------------------------
  42. BOOL LinkToOle32(
  43. Ole32LinkageStruct *pOle32Link,
  44. LPCSTR pszOle32)
  45. {
  46. MYDBGASSERT(pOle32Link);
  47. MYDBGASSERT(pszOle32);
  48. LPCSTR apszOle32[] = {
  49. "OleInitialize",
  50. "OleUninitialize",
  51. "OleSetContainedObject",
  52. "CoCreateInstance",
  53. NULL
  54. };
  55. MYDBGASSERT(sizeof(pOle32Link->apvPfnOle32)/sizeof(pOle32Link->apvPfnOle32[0])==sizeof(apszOle32)/sizeof(apszOle32[0]));
  56. ZeroMemory(pOle32Link, sizeof(Ole32LinkageStruct));
  57. return (LinkToDll(&pOle32Link->hInstOle32,
  58. pszOle32,
  59. apszOle32,
  60. pOle32Link->apvPfnOle32));
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Function: UnlinkFromOle32
  65. //
  66. // Synopsis: The reverse of LinkToOle32().
  67. //
  68. // Arguments: pOle32Link - ptr to Ole32LinkagStruct
  69. //
  70. // Returns: Nothing
  71. //
  72. // History: nickball Created 8/14/97
  73. //
  74. //----------------------------------------------------------------------------
  75. void UnlinkFromOle32(Ole32LinkageStruct *pOle32Link)
  76. {
  77. MYDBGASSERT(pOle32Link);
  78. if (pOle32Link->hInstOle32)
  79. {
  80. FreeLibrary(pOle32Link->hInstOle32);
  81. }
  82. ZeroMemory(pOle32Link, sizeof(Ole32LinkageStruct));
  83. }
  84. VOID CleanupCtr(LPICMOCCtr pCtr)
  85. {
  86. if (pCtr)
  87. {
  88. pCtr->ShutDown();
  89. pCtr->Release();
  90. }
  91. }
  92. // move (translate) the rectangle by (dx, dy)
  93. inline VOID MoveRect(LPRECT prc, int dx, int dy)
  94. {
  95. prc->left += dx;
  96. prc->right += dx;
  97. prc->top += dy;
  98. prc->bottom += dy;
  99. }
  100. const ULONG MAX_STATUS_TEXT = MAX_PATH;
  101. //+--------------------------------------------------------------------------
  102. //
  103. // Member: CDynamicOleAut::CDynamicOleAut
  104. //
  105. // Synopsis: ctor for the Dynamic OleAut class
  106. //
  107. // Arguments: None
  108. //
  109. //----------------------------------------------------------------------------
  110. CDynamicOleAut::CDynamicOleAut()
  111. {
  112. //
  113. // Setup OLEAUT32 linkage
  114. //
  115. LPCSTR apszOleAut[] = {
  116. "VariantClear",
  117. "VariantCopy",
  118. "VariantInit",
  119. "VariantChangeType",
  120. "SysAllocString",
  121. "SysFreeString",
  122. NULL
  123. };
  124. MYDBGASSERT(sizeof(m_OleAutLink.apvPfnOleAut)/sizeof(m_OleAutLink.apvPfnOleAut[0]) ==
  125. sizeof(apszOleAut)/sizeof(apszOleAut[0]));
  126. ZeroMemory(&m_OleAutLink, sizeof(m_OleAutLink));
  127. //
  128. // Do the link, but make it obvious if it fails
  129. //
  130. if (!LinkToDll(&m_OleAutLink.hInstOleAut, "OLEAUT32.DLL",
  131. apszOleAut, m_OleAutLink.apvPfnOleAut))
  132. {
  133. if (m_OleAutLink.hInstOleAut)
  134. {
  135. FreeLibrary(m_OleAutLink.hInstOleAut);
  136. }
  137. ZeroMemory(&m_OleAutLink, sizeof(m_OleAutLink));
  138. }
  139. MYDBGASSERT(m_OleAutLink.hInstOleAut);
  140. }
  141. //+--------------------------------------------------------------------------
  142. //
  143. // Member: CDynamicOleAut::~CDynamicOleAut
  144. //
  145. // Synopsis: dtor for the Dynamic OleAut class
  146. //
  147. // Arguments: None
  148. //
  149. //----------------------------------------------------------------------------
  150. CDynamicOleAut::~CDynamicOleAut()
  151. {
  152. if (m_OleAutLink.hInstOleAut)
  153. {
  154. FreeLibrary(m_OleAutLink.hInstOleAut);
  155. }
  156. }
  157. //+--------------------------------------------------------------------------
  158. //
  159. // Member: CDynamicOleAut::DynVariantClear
  160. //
  161. // Synopsis: Wrapper for VariantClear in OLEAUT32.DLL
  162. //
  163. // Arguments: See OLEAUT32.DLL documentation
  164. //
  165. //----------------------------------------------------------------------------
  166. HRESULT
  167. CDynamicOleAut::DynVariantClear(VARIANTARG FAR* pVar)
  168. {
  169. if (NULL == m_OleAutLink.hInstOleAut || NULL == m_OleAutLink.pfnVariantClear)
  170. {
  171. return E_FAIL;
  172. }
  173. return m_OleAutLink.pfnVariantClear(pVar);
  174. }
  175. //+--------------------------------------------------------------------------
  176. //
  177. // Member: CDynamicOleAut::DynVariantCopy
  178. //
  179. // Synopsis: Wrapper for VariantCopy in OLEAUT32.DLL
  180. //
  181. // Arguments: See OLEAUT32.DLL documentation
  182. //
  183. //----------------------------------------------------------------------------
  184. HRESULT
  185. CDynamicOleAut::DynVariantCopy(
  186. VARIANTARG FAR* pVar1,
  187. VARIANTARG FAR* pVar2)
  188. {
  189. if (NULL == m_OleAutLink.hInstOleAut || NULL == m_OleAutLink.pfnVariantCopy)
  190. {
  191. return E_FAIL;
  192. }
  193. return m_OleAutLink.pfnVariantCopy(pVar1, pVar2);
  194. }
  195. //+--------------------------------------------------------------------------
  196. //
  197. // Member: CDynamicOleAut::DynVariantInit
  198. //
  199. // Synopsis: Wrapper for VariantInit in OLEAUT32.DLL
  200. //
  201. // Arguments: See OLEAUT32.DLL documentation
  202. //
  203. //----------------------------------------------------------------------------
  204. VOID
  205. CDynamicOleAut::DynVariantInit(VARIANTARG FAR* pVar)
  206. {
  207. if (m_OleAutLink.hInstOleAut && m_OleAutLink.pfnVariantInit)
  208. {
  209. m_OleAutLink.pfnVariantInit(pVar);
  210. }
  211. }
  212. //+--------------------------------------------------------------------------
  213. //
  214. // Member: CDynamicOleAut::DynVariantChangeType
  215. //
  216. // Synopsis: Wrapper for VariantChangeType in OLEAUT32.DLL
  217. //
  218. // Arguments: See OLEAUT32.DLL documentation
  219. //
  220. //----------------------------------------------------------------------------
  221. HRESULT
  222. CDynamicOleAut::DynVariantChangeType(
  223. VARIANTARG FAR* pVar1,
  224. VARIANTARG FAR* pVar2,
  225. unsigned short wFlags,
  226. VARTYPE vt)
  227. {
  228. if (NULL == m_OleAutLink.hInstOleAut || NULL == m_OleAutLink.pfnVariantChangeType)
  229. {
  230. return E_FAIL;
  231. }
  232. return m_OleAutLink.pfnVariantChangeType(pVar1, pVar2, wFlags, vt);
  233. }
  234. //+--------------------------------------------------------------------------
  235. //
  236. // Member: CDynamicOleAut::DynSysAllocString
  237. //
  238. // Synopsis: Wrapper for SysAllocString in OLEAUT32.DLL
  239. //
  240. // Arguments: See OLEAUT32.DLL documentation
  241. //
  242. //----------------------------------------------------------------------------
  243. BSTR
  244. CDynamicOleAut::DynSysAllocString(OLECHAR FAR* sz)
  245. {
  246. if (NULL == m_OleAutLink.hInstOleAut || NULL == m_OleAutLink.pfnSysAllocString)
  247. {
  248. return NULL;
  249. }
  250. return m_OleAutLink.pfnSysAllocString(sz);
  251. }
  252. //+--------------------------------------------------------------------------
  253. //
  254. // Member: CDynamicOleAut::DynSysFreeString
  255. //
  256. // Synopsis: Wrapper for SysFreeString in OLEAUT32.DLL
  257. //
  258. // Arguments: See OLEAUT32.DLL documentation
  259. //
  260. //----------------------------------------------------------------------------
  261. VOID
  262. CDynamicOleAut::DynSysFreeString(BSTR bstr)
  263. {
  264. if (m_OleAutLink.hInstOleAut && m_OleAutLink.pfnSysFreeString)
  265. {
  266. m_OleAutLink.pfnSysFreeString(bstr);
  267. }
  268. }
  269. //+--------------------------------------------------------------------------
  270. //
  271. // Member: CDynamicOleAut::Initialized
  272. //
  273. // Synopsis: Simple query to report if linkage is valid
  274. //
  275. // Arguments: None
  276. //
  277. //----------------------------------------------------------------------------
  278. BOOL
  279. CDynamicOleAut::Initialized()
  280. {
  281. return (NULL != m_OleAutLink.hInstOleAut);
  282. }
  283. //+--------------------------------------------------------------------------
  284. //
  285. // Member: CICMOCCtr::CICMOCCtr
  286. //
  287. // Synopsis: ctor for the OLE Controls container class.
  288. //
  289. // Arguments: [hWnd] -- hWnd for the main browser
  290. //
  291. //----------------------------------------------------------------------------
  292. #pragma warning(disable:4355) // this used in initialization list
  293. CICMOCCtr::CICMOCCtr(const HWND hWndMainDlg, const HWND hWndFrame) :
  294. m_hWndMainDlg(hWndMainDlg),
  295. m_hWndFrame(hWndFrame),
  296. m_CS(this),
  297. m_AS(this),
  298. m_IPF(this),
  299. m_IPS(this),
  300. m_OCtr(this),
  301. m_PB(this),
  302. m_pActiveObj(0),
  303. m_Ref(1),
  304. m_pUnk(0),
  305. m_pOC(0),
  306. m_pVO(0),
  307. m_pOO(0),
  308. m_pIPO(0),
  309. m_pDisp(0),
  310. m_state(OS_PASSIVE),
  311. m_dwMiscStatus(0),
  312. m_fModelessEnabled(TRUE)
  313. {
  314. ::memset(&m_rcToolSpace, 0, sizeof m_rcToolSpace);
  315. InitPixelsPerInch(); // initialize the HIMETRIC routines
  316. // init all the state mappings to -1
  317. for (INT i = PS_Interactive; i < PS_Last; i++)
  318. {
  319. m_alStateMappings[i] = -1;
  320. }
  321. }
  322. #pragma warning(default:4355)
  323. CICMOCCtr::~CICMOCCtr(VOID)
  324. {
  325. }
  326. //+---------------------------------------------------------------------------
  327. //
  328. // Member: CICMOCCtr::HasLinkage
  329. //
  330. // Synopsis: Initialize - verify that we have a link to OLEAUT32.DLL
  331. //
  332. //----------------------------------------------------------------------------
  333. BOOL
  334. CICMOCCtr::Initialized(VOID)
  335. {
  336. return m_DOA.Initialized();
  337. }
  338. //+---------------------------------------------------------------------------
  339. //
  340. // Member: CICMOCCtr::ShutDown
  341. //
  342. // Synopsis: cleanup all the OLE stuff.
  343. //
  344. //----------------------------------------------------------------------------
  345. VOID
  346. CICMOCCtr::ShutDown(VOID)
  347. {
  348. if (m_pOC)
  349. m_pOC->Release();
  350. if (m_pIPO)
  351. {
  352. MYDBGASSERT(m_state == OS_UIACTIVE || m_state == OS_INPLACE);
  353. if (m_state == OS_UIACTIVE)
  354. {
  355. m_pIPO->UIDeactivate();
  356. // m_state = OS_INPLACE; // for documentation purposes
  357. if (m_pActiveObj)
  358. {
  359. m_pActiveObj->Release();
  360. m_pActiveObj = 0;
  361. }
  362. }
  363. m_pIPO->InPlaceDeactivate();
  364. // m_state = OS_RUNNING;
  365. }
  366. if (m_pVO)
  367. {
  368. // kill the advisory connection
  369. m_pVO->SetAdvise(DVASPECT_CONTENT, 0, 0);
  370. m_pVO->Release();
  371. }
  372. if (m_pOO)
  373. {
  374. m_pOO->Close(OLECLOSE_NOSAVE);
  375. m_pOO->SetClientSite(0);
  376. m_pOO->Release();
  377. }
  378. if (m_pDisp)
  379. m_pDisp->Release();
  380. if (m_pUnk)
  381. m_pUnk->Release();
  382. MYDBGASSERT(!m_pActiveObj);
  383. m_pDisp = 0;
  384. m_pOC = 0;
  385. m_pIPO = 0;
  386. m_pActiveObj = 0;
  387. m_pVO = 0;
  388. m_pOO = 0;
  389. m_pUnk = 0;
  390. m_state = OS_PASSIVE;
  391. }
  392. //+---------------------------------------------------------------------------
  393. //
  394. // Member: CICMOCCtr::AddRef
  395. //
  396. // Synopsis: bump refcount up on container. Note that all the
  397. // interfaces handed out delegate to this one.
  398. //
  399. //----------------------------------------------------------------------------
  400. STDMETHODIMP_(ULONG)
  401. CICMOCCtr::AddRef(VOID)
  402. {
  403. return ++m_Ref;
  404. }
  405. //+---------------------------------------------------------------------------
  406. //
  407. // Member: CICMOCCtr::Release
  408. //
  409. // Synopsis: decrement the refcount on container, and delete when it
  410. // hits 0 - note that all the interfaces handed out delegate
  411. // to this one.
  412. //
  413. //----------------------------------------------------------------------------
  414. STDMETHODIMP_(ULONG)
  415. CICMOCCtr::Release(VOID)
  416. {
  417. ULONG ulRC = --m_Ref;
  418. if (!ulRC)
  419. {
  420. delete this;
  421. }
  422. return ulRC;
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Member: CICMOCCtr::QueryInterface
  427. //
  428. // Synopsis: this is where we hand out all the interfaces. All the
  429. // interfaces delegate back to this.
  430. //
  431. // Arguments: [riid] -- IID of interface desired.
  432. // [ppv] -- interface returned.
  433. //
  434. // Returns: HRESULT
  435. //
  436. //----------------------------------------------------------------------------
  437. STDMETHODIMP
  438. CICMOCCtr::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  439. {
  440. *ppv = 0;
  441. LPUNKNOWN pUnk;
  442. if (::IsEqualIID(riid, IID_IOleClientSite))
  443. pUnk = &m_CS;
  444. else if (::IsEqualIID(riid, IID_IAdviseSink))
  445. pUnk = &m_AS;
  446. else if (::IsEqualIID(riid, IID_IUnknown))
  447. pUnk = this;
  448. else if (::IsEqualIID(riid, IID_IOleInPlaceFrame) ||
  449. ::IsEqualIID(riid, IID_IOleInPlaceUIWindow))
  450. pUnk = &m_IPF;
  451. else if (::IsEqualIID(riid, IID_IOleInPlaceSite))
  452. pUnk = &m_IPS;
  453. else if (::IsEqualIID(riid, IID_IPropertyBag))
  454. pUnk = &m_PB;
  455. else
  456. return E_NOINTERFACE;
  457. pUnk->AddRef();
  458. *ppv = pUnk;
  459. return S_OK;
  460. }
  461. extern "C" CLSID const CLSID_FS =
  462. {
  463. 0xD27CDB6E,
  464. 0xAE6D,
  465. 0x11CF,
  466. { 0x96, 0xB8, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }
  467. };
  468. //+---------------------------------------------------------------------------
  469. //
  470. // Member: CICMOCCtr::CreateFSOC
  471. //
  472. // Synopsis: Creates an instance of the Future Splash OC, embedding it in
  473. // our container. QIs for all the relevant pointers and
  474. // transitions the control to the UIActive state.
  475. //
  476. // Arguments: pOle32Link - ptr to Ole32LinkageStruct containing funtion
  477. // pointers to dynamically linked OLE32 DLL
  478. //
  479. //----------------------------------------------------------------------------
  480. HRESULT
  481. CICMOCCtr::CreateFSOC(Ole32LinkageStruct *pOle32Link)
  482. {
  483. MYDBGASSERT(pOle32Link);
  484. HRESULT hr = -1;
  485. RECT rc;
  486. LPPERSISTPROPERTYBAG pPPB = 0;
  487. // GetFrameWindow() also asserts that hwnd ::IsWindow()
  488. MYDBGASSERT(GetFrameWindow());
  489. //
  490. // Use dyna-linked CoCreateInstance to create the OC
  491. //
  492. if (pOle32Link->hInstOle32 && pOle32Link->pfnCoCreateInstance)
  493. {
  494. hr = pOle32Link->pfnCoCreateInstance(
  495. CLSID_FS,
  496. 0,
  497. CLSCTX_INPROC_SERVER,
  498. IID_IUnknown,
  499. (LPVOID *) &m_pUnk);
  500. }
  501. else
  502. {
  503. hr = E_FAIL;
  504. }
  505. if (hr)
  506. goto Cleanup;
  507. m_state = OS_RUNNING;
  508. // get the View object - although we rarely draw the OC thru this.
  509. // since we immediately transition it to the UIActive state, it
  510. // usually draws itself through its own wndproc.
  511. hr = m_pUnk->QueryInterface(IID_IViewObject, (LPVOID FAR *) &m_pVO);
  512. if (hr)
  513. goto Cleanup;
  514. // get the IOleObject pointer - the main interface through which
  515. // we handle the basic OLE object state transition stuff
  516. // for the Future Splash OC
  517. hr = m_pUnk->QueryInterface(IID_IOleObject, (LPVOID FAR *) &m_pOO);
  518. if (hr)
  519. goto Cleanup;
  520. // get status bits on the OC - we're not currently doing anything
  521. // with them.
  522. hr = m_pOO->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
  523. if (hr)
  524. goto Cleanup;
  525. // set our client site into the oleobject
  526. hr = m_pOO->SetClientSite(&m_CS);
  527. if (hr)
  528. goto Cleanup;
  529. hr = m_pUnk->QueryInterface(IID_IPersistPropertyBag, (LPVOID *) &pPPB);
  530. if (hr)
  531. goto Cleanup;
  532. hr = pPPB->Load(&m_PB, 0);
  533. if (hr)
  534. goto Cleanup;
  535. // set our advise sink into the view object, so we
  536. // get notifications that we need to redraw.
  537. hr = m_pVO->SetAdvise(DVASPECT_CONTENT, 0, &m_AS);
  538. if (hr)
  539. goto Cleanup;
  540. //
  541. // Use dyna-linked OleSetContainedObject
  542. //
  543. if (pOle32Link->hInstOle32 && pOle32Link->pfnOleSetContainedObject)
  544. {
  545. // standard OLE protocol stuff.
  546. hr = pOle32Link->pfnOleSetContainedObject(m_pUnk, TRUE);
  547. }
  548. else
  549. {
  550. hr = E_FAIL;
  551. }
  552. if (hr)
  553. goto Cleanup;
  554. // ditto
  555. hr = m_pOO->SetHostNames(g_awchHostName, 0);
  556. if (hr)
  557. goto Cleanup;
  558. // get the IDispatch for the control. This is for late-bound
  559. // access to the properties and methods.
  560. hr = m_pUnk->QueryInterface(IID_IDispatch, (LPVOID FAR *) &m_pDisp);
  561. if (hr)
  562. goto Cleanup;
  563. // get the IOleControl interface; although we use it for very little.
  564. hr = m_pUnk->QueryInterface(IID_IOleControl, (LPVOID FAR *) &m_pOC);
  565. if (hr)
  566. goto Cleanup;
  567. // transition the control to the inplace-active state - it will have
  568. // an hWnd after it returns from DoVerb, and will begin drawing
  569. // itself.
  570. _GetDoVerbRect(&rc); // get rect for firing verbs.
  571. hr = m_pOO->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, &m_CS, 0, GetMainWindow(), &rc);
  572. if (hr)
  573. goto Cleanup;
  574. // go ahead and UI activate it. This will cause it to QI for our
  575. // IOleInPlaceFrame and call SetActiveObject, which we will store
  576. // in m_pActiveObj
  577. hr = m_pOO->DoVerb(OLEIVERB_UIACTIVATE, 0, &m_CS, 0, GetMainWindow(), &rc);
  578. if (hr)
  579. goto Cleanup;
  580. Cleanup:
  581. if (pPPB)
  582. pPPB->Release();
  583. return hr;
  584. }
  585. //+---------------------------------------------------------------------------
  586. //
  587. // Member: CICMOCCtr::_AdjustForTools
  588. //
  589. // Synopsis: adjusts the rect passed in for any toolspace claimed by the
  590. // FS OC. Currently, the FS OC always just
  591. // passed in a rect with four zeros in it - but if it ever
  592. // does decide to do this, we're ready :).
  593. //
  594. // Arguments: [prc] -- the rect we want to reduce by the BORDERWIDTHS
  595. // stored in m_rcToolSpace.
  596. //
  597. //----------------------------------------------------------------------------
  598. VOID
  599. CICMOCCtr::_AdjustForTools(LPRECT prc)
  600. {
  601. prc->left += m_rcToolSpace.left;
  602. prc->top += m_rcToolSpace.top;
  603. prc->bottom -= m_rcToolSpace.bottom;
  604. prc->right -= m_rcToolSpace.right;
  605. }
  606. //+---------------------------------------------------------------------------
  607. //
  608. // Member: CICMOCCtr::GetSize
  609. //
  610. // Synopsis: returns the size, in pixels, of the FS OC.
  611. //
  612. // Arguments: [prc] -- returned size.
  613. //
  614. //----------------------------------------------------------------------------
  615. HRESULT
  616. CICMOCCtr::GetSize(LPRECT prc)
  617. {
  618. MYDBGASSERT(m_pOO);
  619. HRESULT hr;
  620. // if we're inplace active, just ask the frame window.
  621. if (m_state >= OS_INPLACE)
  622. {
  623. MYDBGASSERT(m_pIPO);
  624. ::GetClientRect(GetFrameWindow(), prc);
  625. hr = S_OK;
  626. }
  627. else // not inplace active - probably this is never hit.
  628. {
  629. SIZEL sizel;
  630. hr = m_pOO->GetExtent(DVASPECT_CONTENT, &sizel);
  631. if (!hr)
  632. {
  633. prc->left = 0;
  634. prc->top = 0;
  635. prc->right = ::HPixFromHimetric(sizel.cx);
  636. prc->bottom = ::VPixFromHimetric(sizel.cy);
  637. }
  638. }
  639. // adjust the borders for any tools that a UIActive object
  640. // wants to place there.
  641. if (!hr)
  642. _AdjustForTools(prc);
  643. return hr;
  644. }
  645. //+---------------------------------------------------------------------------
  646. //
  647. // Member: CICMOCCtr::DoLayout
  648. //
  649. // Synopsis: manages the vertical layout of things -
  650. // sizes the OC container itself.
  651. //
  652. // Arguments: [cxMain] -- width
  653. // [cyMain] -- height
  654. //
  655. //----------------------------------------------------------------------------
  656. VOID
  657. CICMOCCtr::DoLayout(INT cxMain, INT cyMain)
  658. {
  659. RECT rc;
  660. MYDBGASSERT(m_hWndFrame && ::IsWindow(m_hWndFrame));
  661. ::GetClientRect(m_hWndFrame, &rc);
  662. SetSize(&rc, TRUE);
  663. }
  664. HRESULT
  665. CICMOCCtr::_SetExtent(LPRECT prc)
  666. {
  667. SIZEL sizel;
  668. HRESULT hr;
  669. sizel.cx = ::HimetricFromHPix(prc->right - prc->left);
  670. sizel.cy = ::HimetricFromVPix(prc->bottom - prc->top);
  671. MYDBGASSERT(m_pOO);
  672. hr = m_pOO->SetExtent(DVASPECT_CONTENT, &sizel);
  673. if (hr)
  674. goto cleanup;
  675. hr = m_pOO->GetExtent(DVASPECT_CONTENT, &sizel);
  676. if (hr)
  677. goto cleanup;
  678. prc->right = ::HPixFromHimetric(sizel.cx);
  679. prc->bottom = ::VPixFromHimetric(sizel.cy);
  680. cleanup:
  681. return hr;
  682. }
  683. //+---------------------------------------------------------------------------
  684. //
  685. // Member: CICMOCCtr::SetSize
  686. //
  687. // Synopsis: sets the size of the FS OC space (the HTML area)
  688. //
  689. // Effects: if fMoveFrameWindow is TRUE, then it moves the whole
  690. // framewindow around, otherwise, it just readjusts how much
  691. // of the framewindow space is used by the OC itself.
  692. // In reality, what happens is that the OC calls us to
  693. // set some border space (although at this writing it still
  694. // is setting BORDERWIDTHS of 0,0,0,0), we allow that
  695. // much space, then call IOleInPlaceObject->SetObjectRects
  696. // to resize the object to whatever's left.
  697. // Otherwise, if the object is not yet active, we just
  698. // call IOleObject::SetExtent().
  699. //
  700. // Arguments: [prc] -- size to set object to
  701. // [fMoveFrameWindow] -- is the hwnd size changing, or just
  702. // the object within?
  703. //
  704. //
  705. //----------------------------------------------------------------------------
  706. HRESULT
  707. CICMOCCtr::SetSize(LPRECT prc, BOOL fMoveFrameWindow)
  708. {
  709. HRESULT hr;
  710. RECT rcClient;
  711. RECT rcExtent;
  712. // get client coords.
  713. rcClient = *prc;
  714. ::MoveRect(&rcClient, -rcClient.left, -rcClient.top);
  715. if (fMoveFrameWindow)
  716. {
  717. ::SetWindowPos(
  718. GetFrameWindow(),
  719. 0,
  720. prc->left,
  721. prc->top,
  722. prc->right - prc->left,
  723. prc->bottom - prc->top,
  724. SWP_NOZORDER | SWP_NOACTIVATE);
  725. if (m_pActiveObj)
  726. m_pActiveObj->ResizeBorder(&rcClient, &m_IPF, TRUE);
  727. }
  728. // subtract off any tools the client has around .
  729. _AdjustForTools(&rcClient);
  730. rcExtent = rcClient;
  731. hr = _SetExtent(&rcExtent);
  732. if (hr)
  733. goto cleanup;
  734. // now we need to call SetObjectRects
  735. if (m_pIPO && m_state >= OS_INPLACE)
  736. hr = m_pIPO->SetObjectRects(&rcExtent, &rcClient);
  737. cleanup:
  738. return hr;
  739. }
  740. //+---------------------------------------------------------------------------
  741. //
  742. // Member: CICMOCCtr::Paint
  743. //
  744. // Synopsis: Paint with no parameters
  745. //
  746. //----------------------------------------------------------------------------
  747. VOID
  748. CICMOCCtr::Paint(VOID)
  749. {
  750. PAINTSTRUCT ps;
  751. RECT rc;
  752. // we don't need to call IViewObject if the object is activated.
  753. // it's got an hWnd and is receiving paint messages of its own.
  754. if (m_state < OS_INPLACE)
  755. {
  756. if (!GetSize(&rc))
  757. {
  758. ::BeginPaint(GetFrameWindow(), &ps);
  759. Paint(ps.hdc, &rc);
  760. ::EndPaint(GetFrameWindow(), &ps);
  761. }
  762. }
  763. }
  764. //+---------------------------------------------------------------------------
  765. //
  766. // Member: CICMOCCtr::Paint
  767. //
  768. // Synopsis: paint with the hdc and rect passed in. Uses
  769. // IViewObject::Draw()
  770. //
  771. // Arguments: [hDC] -- dc to draw to - can be container's or
  772. // even print dc (never is a print dc in
  773. // our scenario -
  774. // [lpr] -- rect for painting.
  775. //
  776. //----------------------------------------------------------------------------
  777. VOID
  778. CICMOCCtr::Paint(HDC hDC, LPRECT lpr)
  779. {
  780. // adjust the borders in to allow for any tools the OC
  781. // wanted to insert - so far it never does.
  782. _AdjustForTools(lpr);
  783. // have to use a RECTL instead of RECT - remnant of the
  784. // OLE 16 bit days.
  785. RECTL rcl = {lpr->left, lpr->top, lpr->right, lpr->bottom};
  786. if (m_pVO)
  787. m_pVO->Draw(DVASPECT_CONTENT, -1, 0, 0, 0, hDC, &rcl, 0, 0, 0);
  788. }
  789. VOID
  790. CICMOCCtr::MapStateToFrame(ProgState ps)
  791. {
  792. // if the statemappings are -1, they are unitialized, don't use them.
  793. LONG lFrame = m_alStateMappings[ps];
  794. if (-1 != lFrame)
  795. SetFrame(lFrame); // ignore error - nothing we can do.
  796. }
  797. HRESULT
  798. CICMOCCtr::SetFrame(LONG lFrame)
  799. {
  800. HRESULT hr;
  801. OLECHAR * pFrameNum = OLESTR("FrameNum");
  802. OLECHAR * pPlay = OLESTR("Play");
  803. DISPPARAMS dp = {0, 0, 0, 0};
  804. DISPID dispidPut = DISPID_PROPERTYPUT;
  805. VARIANTARG var;
  806. EXCEPINFO ei;
  807. DISPID id;
  808. UINT uArgErr;
  809. m_DOA.DynVariantInit(&var);
  810. V_VT(&var) = VT_I4;
  811. V_I4(&var) = lFrame;
  812. dp.cArgs = 1;
  813. dp.rgvarg = &var;
  814. dp.cNamedArgs = 1;
  815. dp.rgdispidNamedArgs = &dispidPut;
  816. hr = m_pDisp->GetIDsOfNames(
  817. IID_NULL,
  818. &pFrameNum,
  819. 1,
  820. LOCALE_SYSTEM_DEFAULT,
  821. &id);
  822. if (hr)
  823. goto Cleanup;
  824. hr = m_pDisp->Invoke(
  825. id,
  826. IID_NULL,
  827. LOCALE_SYSTEM_DEFAULT,
  828. DISPATCH_PROPERTYPUT,
  829. &dp,
  830. 0,
  831. &ei,
  832. &uArgErr);
  833. if (hr)
  834. goto Cleanup;
  835. hr = m_pDisp->GetIDsOfNames(
  836. IID_NULL,
  837. &pPlay,
  838. 1,
  839. LOCALE_SYSTEM_DEFAULT,
  840. &id);
  841. if (hr)
  842. goto Cleanup;
  843. ::memset(&dp, 0, sizeof dp);
  844. hr = m_pDisp->Invoke(
  845. id,
  846. IID_NULL,
  847. LOCALE_SYSTEM_DEFAULT,
  848. DISPATCH_METHOD,
  849. &dp,
  850. 0,
  851. &ei,
  852. &uArgErr);
  853. if (hr)
  854. goto Cleanup;
  855. Cleanup:
  856. return hr;
  857. }
  858. //+---------------------------------------------------------------------------
  859. //
  860. // Member: CICMOCCtr::OnActivateApp
  861. //
  862. // Synopsis: all WM_ACTIVATE messages (forwarded from
  863. // main browser hWnd wndproc) must call
  864. // IOleInPlaceActiveObject::OnFrameWindowActivate(),
  865. // per the OLE compound document spec.
  866. //
  867. // Arguments: [wParam] -- whatever the WM_ACTIVATE msg passed
  868. // [lParam] -- ditto
  869. //
  870. // Returns: 0 - to say we handled the message.
  871. //
  872. //----------------------------------------------------------------------------
  873. LRESULT
  874. CICMOCCtr::OnActivateApp(WPARAM wParam, LPARAM lParam)
  875. {
  876. if (m_pActiveObj)
  877. m_pActiveObj->OnFrameWindowActivate((BOOL)wParam);
  878. return 0;
  879. }
  880. //+---------------------------------------------------------------------------
  881. //
  882. // Member: CICMOCCtr::SetFocus
  883. //
  884. // Synopsis: transfers focus from framewindow to the current
  885. // in-place active object. Per OLE Compound Document spec.
  886. //
  887. //----------------------------------------------------------------------------
  888. LRESULT
  889. CICMOCCtr::SetFocus(VOID)
  890. {
  891. HWND hWnd = NULL;
  892. LPOLEINPLACEACTIVEOBJECT pAO = GetIPAObject();
  893. if (pAO)
  894. {
  895. if (!pAO->GetWindow(&hWnd))
  896. {
  897. if (hWnd && !::IsWindow(hWnd))
  898. hWnd = NULL;
  899. }
  900. }
  901. // if no inplaceactive object, set focus to frame window.
  902. if (!hWnd)
  903. hWnd = GetFrameWindow();
  904. ::SetFocus(hWnd);
  905. return 0;
  906. }
  907. //+---------------------------------------------------------------------------
  908. //
  909. // Class: CAdviseSink implementations
  910. //
  911. // Purpose: to implement IAdviseSink for CICMOCCtr
  912. //
  913. // Notes: we don't do much with this interface - it's required
  914. // for contractual reasons only.
  915. //
  916. //----------------------------------------------------------------------------
  917. STDMETHODIMP
  918. CAdviseSink::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  919. {
  920. return m_pCtr->QueryInterface(riid, ppv);
  921. }
  922. STDMETHODIMP_(ULONG)
  923. CAdviseSink::AddRef(VOID)
  924. {
  925. return m_pCtr->AddRef();
  926. }
  927. STDMETHODIMP_(ULONG)
  928. CAdviseSink::Release(VOID)
  929. {
  930. return m_pCtr->Release();
  931. }
  932. CAdviseSink::CAdviseSink(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  933. {
  934. }
  935. STDMETHODIMP_(VOID)
  936. CAdviseSink::OnDataChange(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
  937. {
  938. return;
  939. }
  940. //+---------------------------------------------------------------------------
  941. //
  942. // Member: CAdviseSink::OnViewChange
  943. //
  944. // Synopsis: IAdviseSink::OnViewChange() - we do get called with this
  945. // occasionally, but it appears that we're better off just
  946. // letting the control's wndproc paint it.
  947. // Calling this was causing extra flicker.
  948. //
  949. //----------------------------------------------------------------------------
  950. STDMETHODIMP_(VOID)
  951. CAdviseSink::OnViewChange(DWORD dwAspect, LONG lIndex)
  952. {
  953. return;
  954. }
  955. STDMETHODIMP_(VOID)
  956. CAdviseSink::OnRename(LPMONIKER pmk)
  957. {
  958. }
  959. STDMETHODIMP_(VOID)
  960. CAdviseSink::OnSave(VOID)
  961. {
  962. }
  963. STDMETHODIMP_(VOID)
  964. CAdviseSink::OnClose(VOID)
  965. {
  966. }
  967. //+---------------------------------------------------------------------------
  968. //
  969. // Class: COleClientSite ()
  970. //
  971. // Purpose: our implementation of IOleClientSite
  972. //
  973. // Interface: COleClientSite -- ctor
  974. // QueryInterface -- gimme an interface!
  975. // AddRef -- bump up refcount
  976. // Release -- bump down refcount
  977. // SaveObject -- returns E_FAIL
  978. // GetMoniker -- E_NOTIMPL
  979. // GetContainer -- returns our COleContainer impl
  980. // ShowObject -- just say OK
  981. // OnShowWindow -- just say OK
  982. // RequestNewObjectLayout -- E_NOTIMPL
  983. //
  984. // Notes: probably the most important thing our IOleClientSite
  985. // implementation does is hand off our IOleContainer
  986. // implementation when GetContainer() is called.
  987. //
  988. //----------------------------------------------------------------------------
  989. COleClientSite::COleClientSite(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  990. {
  991. }
  992. STDMETHODIMP
  993. COleClientSite::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  994. {
  995. return m_pCtr->QueryInterface(riid, ppv);
  996. }
  997. STDMETHODIMP_(ULONG)
  998. COleClientSite::AddRef(VOID)
  999. {
  1000. return m_pCtr->AddRef();
  1001. }
  1002. STDMETHODIMP_(ULONG)
  1003. COleClientSite::Release(VOID)
  1004. {
  1005. return m_pCtr->Release();
  1006. }
  1007. //+---------------------------------------------------------------------------
  1008. //
  1009. // Member: COleClientSite::SaveObject
  1010. //
  1011. // Synopsis: not implemented - makes no sense in this scenario.
  1012. //
  1013. //----------------------------------------------------------------------------
  1014. STDMETHODIMP
  1015. COleClientSite::SaveObject(VOID)
  1016. {
  1017. return E_FAIL;
  1018. }
  1019. //+---------------------------------------------------------------------------
  1020. //
  1021. // Member: COleClientSite::GetMoniker
  1022. //
  1023. // Synopsis: Not yet implemented; never will be implemented.
  1024. //
  1025. //----------------------------------------------------------------------------
  1026. STDMETHODIMP
  1027. COleClientSite::GetMoniker(DWORD dwAssign, DWORD dwWhich, LPMONIKER FAR * ppmk)
  1028. {
  1029. *ppmk = 0;
  1030. return E_NOTIMPL;
  1031. }
  1032. //+---------------------------------------------------------------------------
  1033. //
  1034. // Member: COleClientSite::GetContainer
  1035. //
  1036. // Synopsis: returns our implementation of IOleContainer. For some
  1037. // reason, unless we do this, frames don't work. Note that
  1038. // our IOleContainer implementation is stubbed out with
  1039. // E_NOTIMPL (it seems kind of odd to implement this for
  1040. // a container with one embedding). But it turns out the
  1041. // FS OC has a bug in it's error handling - it
  1042. // QIs for IOleContainer, then QIs from that for
  1043. // IQueryService. In truth, we'll hand out our implementation
  1044. // of IQueryService, from any interface - we're easy :).
  1045. // We *want* to provide every service the OC asks for.
  1046. // Anyway, when it can't get IOleContainer, the OC's failure
  1047. // path seems to be constructed in such a way that frames
  1048. // don't work thereafter.
  1049. //
  1050. // Arguments: [ppCtr] -- returned IOleContainer
  1051. //
  1052. // Returns: S_OK. Never fails.
  1053. //
  1054. //----------------------------------------------------------------------------
  1055. STDMETHODIMP
  1056. COleClientSite::GetContainer(LPOLECONTAINER FAR * ppCtr)
  1057. {
  1058. *ppCtr = &m_pCtr->m_OCtr;
  1059. (*ppCtr)->AddRef();
  1060. return S_OK;
  1061. }
  1062. //+---------------------------------------------------------------------------
  1063. //
  1064. // Member: COleClientSite::ShowObject
  1065. //
  1066. // Synopsis: IOleClientSite::ShowObject implementation. To quote the docs:
  1067. // "Tells the container to position the object so it is visible
  1068. // to the user. This method ensures that the container itself
  1069. // is visible and not minimized."
  1070. //
  1071. // In short, we ignore it. We're not going to un-minimize
  1072. // the container on the embeddings' whim :).
  1073. //
  1074. //----------------------------------------------------------------------------
  1075. STDMETHODIMP
  1076. COleClientSite::ShowObject(VOID)
  1077. {
  1078. return S_OK;
  1079. }
  1080. //+---------------------------------------------------------------------------
  1081. //
  1082. // Member: COleClientSite::OnShowWindow
  1083. //
  1084. // Synopsis: fine with us, return S_OK.
  1085. //
  1086. //----------------------------------------------------------------------------
  1087. STDMETHODIMP
  1088. COleClientSite::OnShowWindow(BOOL bShow)
  1089. {
  1090. return S_OK;
  1091. }
  1092. //+---------------------------------------------------------------------------
  1093. //
  1094. // Member: COleClientSite::RequestNewObjectLayout
  1095. //
  1096. // Synopsis: not being called by WebBrower OC, so do not implement.
  1097. //
  1098. //----------------------------------------------------------------------------
  1099. STDMETHODIMP
  1100. COleClientSite::RequestNewObjectLayout(VOID)
  1101. {
  1102. return E_NOTIMPL;
  1103. }
  1104. //+---------------------------------------------------------------------------
  1105. //
  1106. // Member: CInPlaceFrame::CInPlaceFrame
  1107. //
  1108. // Synopsis: inits m_pCtr - pointer to MSNOCCtr
  1109. //
  1110. //----------------------------------------------------------------------------
  1111. CInPlaceFrame::CInPlaceFrame(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  1112. {
  1113. }
  1114. STDMETHODIMP
  1115. CInPlaceFrame::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  1116. {
  1117. return m_pCtr->QueryInterface(riid, ppv);
  1118. }
  1119. STDMETHODIMP_(ULONG)
  1120. CInPlaceFrame::AddRef(VOID)
  1121. {
  1122. return m_pCtr->AddRef();
  1123. }
  1124. STDMETHODIMP_(ULONG)
  1125. CInPlaceFrame::Release(VOID)
  1126. {
  1127. return m_pCtr->Release();
  1128. }
  1129. // IOleWindow stuff
  1130. //+---------------------------------------------------------------------------
  1131. //
  1132. // Member: CInPlaceFrame::GetWindow
  1133. //
  1134. // Synopsis: returns frame window
  1135. //
  1136. // Arguments: [phwnd] -- place to return window
  1137. //
  1138. //----------------------------------------------------------------------------
  1139. STDMETHODIMP
  1140. CInPlaceFrame::GetWindow(HWND * phwnd)
  1141. {
  1142. MYDBGASSERT(phwnd);
  1143. // this can never fail if we've gotten this far.
  1144. *phwnd = m_pCtr->GetFrameWindow();
  1145. MYDBGASSERT(*phwnd);
  1146. return S_OK;
  1147. }
  1148. //+---------------------------------------------------------------------------
  1149. //
  1150. // Member: CInPlaceFrame::ContextSensitiveHelp
  1151. //
  1152. // Synopsis: This is not implemented by design - this is for
  1153. // the SHift+F1 context sensitive help mode and Esc
  1154. // to exit. Esc is already being used in the main
  1155. // accelerator table to mean 'stop browsing' to be
  1156. // like IE3. We do not do help this way.
  1157. //
  1158. //----------------------------------------------------------------------------
  1159. STDMETHODIMP
  1160. CInPlaceFrame::ContextSensitiveHelp(BOOL fEnterMode)
  1161. {
  1162. return E_NOTIMPL;
  1163. }
  1164. // IOleInPlaceUIWindow stuff
  1165. //+---------------------------------------------------------------------------
  1166. //
  1167. // Member: CInPlaceFrame::GetBorder
  1168. //
  1169. // Synopsis: IOleInPlaceFrame::GetBorder() - let's us restrict where
  1170. // the server can put tools. We don't care, they can put
  1171. // them anywhere.
  1172. //
  1173. // Arguments: [lprectBorder] -- return border info in here.
  1174. //
  1175. // Returns: S_OK always with entire frame client rect -
  1176. // we place no restrictions.
  1177. //
  1178. //----------------------------------------------------------------------------
  1179. STDMETHODIMP
  1180. CInPlaceFrame::GetBorder(LPRECT lprectBorder)
  1181. {
  1182. // we have no restrictions about where the server can put tools.
  1183. ::GetClientRect(m_pCtr->GetFrameWindow(), lprectBorder);
  1184. return S_OK;
  1185. }
  1186. //+---------------------------------------------------------------------------
  1187. //
  1188. // Member: CInPlaceFrame::RequestBorderSpace
  1189. //
  1190. // Synopsis: IOleInPlaceFrame::RequestBorderSpace()
  1191. // inplace object actually requests border space - if
  1192. // we can satisfy the request, we return S_OK, otherwise
  1193. // INPLACE_E_NOTOOLSPACE. It doesn't actually use the
  1194. // borderspace until it calls
  1195. // IOleInPlaceFrame::SetBorderSpace(). This is used for
  1196. // negotiation.
  1197. //
  1198. // Arguments: [pborderwidths] -- structure (actually a RECT) that is
  1199. // interpreted differently from a RECT.
  1200. // The left.top.bottom.right members
  1201. // represent space on each of our four
  1202. // borders the server would like to use.
  1203. //
  1204. // Returns: HRESULT
  1205. //
  1206. //----------------------------------------------------------------------------
  1207. STDMETHODIMP
  1208. CInPlaceFrame::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
  1209. {
  1210. RECT rc;
  1211. RECT rcBorder;
  1212. if (!pborderwidths)
  1213. return S_OK; // they're telling us no toolspace necessary.
  1214. rcBorder = *pborderwidths;
  1215. if (GetBorder(&rc))
  1216. return INPLACE_E_NOTOOLSPACE;
  1217. if (rcBorder.left + rcBorder.right > WIDTH(rc) ||
  1218. rcBorder.top + rcBorder.bottom > HEIGHT(rc))
  1219. return INPLACE_E_NOTOOLSPACE;
  1220. return S_OK;
  1221. }
  1222. //+---------------------------------------------------------------------------
  1223. //
  1224. // Member: CInPlaceFrame::SetBorderSpace
  1225. //
  1226. // Synopsis: Sets border space for tools - for some reason, the
  1227. // FS OC always calls this with a pborderwidths
  1228. // consisting of four zeros - it never actually uses any
  1229. // border space (sigh). Well, the code is here for this
  1230. // to work. We do a SetSize() to relayout stuff when
  1231. // it does this.
  1232. //
  1233. // Arguments: [pborderwidths] -- space the OC wants to use.
  1234. //
  1235. // Returns: HRESULT
  1236. //
  1237. //----------------------------------------------------------------------------
  1238. STDMETHODIMP
  1239. CInPlaceFrame::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
  1240. {
  1241. RECT rc;
  1242. if (!pborderwidths)
  1243. {
  1244. ::memset(&m_pCtr->m_rcToolSpace, 0, sizeof m_pCtr->m_rcToolSpace);
  1245. return S_OK;
  1246. }
  1247. if (RequestBorderSpace(pborderwidths))
  1248. return OLE_E_INVALIDRECT;
  1249. // we get the entire client space to pass to setSize().
  1250. ::GetClientRect(m_pCtr->GetFrameWindow(), &rc);
  1251. m_pCtr->m_rcToolSpace = *pborderwidths;
  1252. return m_pCtr->SetSize(&rc, FALSE);
  1253. }
  1254. //+---------------------------------------------------------------------------
  1255. //
  1256. // Member: CInPlaceFrame::SetActiveObject
  1257. //
  1258. // Synopsis: IOleInPlaceFrame::SetActiveObject(). The server calls
  1259. // this normally whenever it transitions to the UIActive
  1260. // state. There can only be one UIActive object at a time.
  1261. // This UIACtive object is represented by its
  1262. // IOleInPlaceActiveObject implementation. We call this
  1263. // object's implementation of TranslateAccelerator() right
  1264. // in the main message loop to give the current embedding
  1265. // first shot at keyboard messages.
  1266. //
  1267. // Normally, this is only called when the container transitions
  1268. // an object to UIActive by calling
  1269. // IOleObject::DoVerb(OLEIVERB_UIACTIVE) for the object,
  1270. // transitioning all the other objects (we don't have any :))
  1271. // to OS_INPLACE (if they're OLEMISC_ACTIVATEWHENVISIBLE is set)
  1272. // or even just OS_RUNNING.
  1273. //
  1274. // Effects: sets a new active object in m_pActiveObj. Releases the
  1275. // old one, if any.
  1276. //
  1277. // Arguments: [pActiveObject] -- new active object
  1278. // [pszObjName] -- name of object - we don't use this.
  1279. //
  1280. // Returns: S_OK always.
  1281. //
  1282. //----------------------------------------------------------------------------
  1283. STDMETHODIMP
  1284. CInPlaceFrame::SetActiveObject(
  1285. IOleInPlaceActiveObject * pActiveObject,
  1286. LPCOLESTR pszObjName)
  1287. {
  1288. // reset the toolspace rect in case the last inplacactive object
  1289. // forgot to.
  1290. m_pCtr->_ResetToolSpace();
  1291. // if it was already set, save it so we can release
  1292. // it. We don't want to release it before we addref
  1293. // the new one in case they're the same thing.
  1294. LPOLEINPLACEACTIVEOBJECT pOld = m_pCtr->m_pActiveObj;
  1295. m_pCtr->m_pActiveObj = pActiveObject;
  1296. if (pActiveObject)
  1297. {
  1298. MYDBGASSERT(OS_UIACTIVE == m_pCtr->GetState());
  1299. m_pCtr->m_pActiveObj->AddRef();
  1300. }
  1301. if (pOld)
  1302. pOld->Release();
  1303. return S_OK;
  1304. }
  1305. // IOleInPlaceFrame stuff
  1306. //+---------------------------------------------------------------------------
  1307. //
  1308. // Member: CInPlaceFrame::InsertMenus
  1309. //
  1310. // Synopsis: OC calling us when it wants to do menu negotiation
  1311. // It calls us with a blank hmenu that we're supposed to
  1312. // add items to and fille out the OLEMENUGROUPWIDTHS
  1313. // structure to let it know what we did.
  1314. // We're not adding items to it currently.
  1315. //
  1316. // Arguments: [hmenuShared] -- menu to append to
  1317. // [pMGW] -- OLEMENUGROUPWIDTHS struct to fill out.
  1318. //
  1319. // Returns: S_OK
  1320. //
  1321. //
  1322. // Note: OC doesn't call this.
  1323. //
  1324. //----------------------------------------------------------------------------
  1325. STDMETHODIMP
  1326. CInPlaceFrame::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS pMGW)
  1327. {
  1328. // we're not inserting anything of our own to this menu.
  1329. pMGW->width[0] = 0; // 'File' menu
  1330. pMGW->width[2] = 0; // 'View' menu
  1331. pMGW->width[4] = 0; // 'Window' menu
  1332. pMGW->width[5] = 0; // 'Help' menu
  1333. return S_OK;
  1334. }
  1335. //+---------------------------------------------------------------------------
  1336. //
  1337. // Member: CInPlaceFrame::SetMenu
  1338. //
  1339. // Synopsis: This is the OC calling the container asking us to
  1340. // set the shared menu in its frame. We're supposed to
  1341. // use the HOLEMENU object passed in and the
  1342. // hWndActiveObject to call OleSetMenuDescriptor() so
  1343. // that OLE can do message filtering and route WM_COMMAND
  1344. // messages.
  1345. //
  1346. //
  1347. // Arguments: [hmenuShared] -- shared menu.
  1348. // [holemenu] -- ole menu descriptor thingy
  1349. // [hwndActiveObject] -- hwnd of server who's merging menus
  1350. //
  1351. // Returns: HRESULT
  1352. //
  1353. //----------------------------------------------------------------------------
  1354. STDMETHODIMP
  1355. CInPlaceFrame::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
  1356. {
  1357. // we're not doing any menu negotiation
  1358. return S_OK;
  1359. }
  1360. //+---------------------------------------------------------------------------
  1361. //
  1362. // Member: CInPlaceFrame::RemoveMenus
  1363. //
  1364. // Synopsis: IOleInPlaceFrame::RemoveMenus(), this is where the
  1365. // server gives us a chance to remove all our items from
  1366. // the hMenu. We're not adding any, so we don't remove any.
  1367. //
  1368. // Arguments: [hmenuShared] -- menu to clean up.
  1369. //
  1370. //----------------------------------------------------------------------------
  1371. STDMETHODIMP
  1372. CInPlaceFrame::RemoveMenus(HMENU hmenuShared)
  1373. {
  1374. // we aren't adding anything to this thing anyway.
  1375. return S_OK;
  1376. }
  1377. //+---------------------------------------------------------------------------
  1378. //
  1379. // Member: CInPlaceFrame::SetStatusText
  1380. //
  1381. // Synopsis: called by the FS OC to put text in our status
  1382. // text area.
  1383. //
  1384. // Returns: HRESULT
  1385. //
  1386. // Arguments: [pszStatusText] -- text to display
  1387. //
  1388. //----------------------------------------------------------------------------
  1389. STDMETHODIMP
  1390. CInPlaceFrame::SetStatusText(LPCOLESTR pszStatusText)
  1391. {
  1392. return m_pCtr->_DisplayStatusText(pszStatusText);
  1393. }
  1394. //+---------------------------------------------------------------------------
  1395. //
  1396. // Member: CICMOCCtr::_DisplayStatusText
  1397. //
  1398. // Synopsis: helper that displays status text.
  1399. //
  1400. // Arguments: [pszStatusText] -- text to display
  1401. //
  1402. //
  1403. // Returns: S_OK or HRESULT_FROM_WIN32(::GetLastError());
  1404. //
  1405. //----------------------------------------------------------------------------
  1406. HRESULT
  1407. CICMOCCtr::_DisplayStatusText(LPCOLESTR pszStatusText)
  1408. {
  1409. CHAR ach[MAX_STATUS_TEXT];
  1410. if (::WideCharToMultiByte(
  1411. CP_ACP,
  1412. 0,
  1413. pszStatusText,
  1414. -1,
  1415. ach,
  1416. NElems(ach),
  1417. 0,
  1418. 0))
  1419. {
  1420. // put the status text somewhere.
  1421. return S_OK;
  1422. }
  1423. else
  1424. {
  1425. return HRESULT_FROM_WIN32(::GetLastError());
  1426. }
  1427. }
  1428. //+---------------------------------------------------------------------------
  1429. //
  1430. // Member: CInPlaceFrame::EnableModeless
  1431. //
  1432. // Synopsis: this is called by the embedding to let us know it's
  1433. // putting up a modal dialog box - we should 'grey' out
  1434. // any of our modeless dialogs. It delegates to
  1435. // CICMOCCtr::EnableModeless()
  1436. //
  1437. // Arguments: [fEnable] -- enable or disable.
  1438. //
  1439. //----------------------------------------------------------------------------
  1440. STDMETHODIMP
  1441. CInPlaceFrame::EnableModeless(BOOL fEnable)
  1442. {
  1443. return m_pCtr->EnableModeless(fEnable);
  1444. }
  1445. //+---------------------------------------------------------------------------
  1446. //
  1447. // Member: CICMOCCtr::EnableModeless
  1448. //
  1449. // Synopsis: delegated to from CInPlaceFrame::EnableModeless().
  1450. // always returns S_OK - we don't have any modeless
  1451. // dialogs (yet).
  1452. //
  1453. // Arguments: [fEnable] -- enable or disable.
  1454. //
  1455. // Returns: S_OK
  1456. //
  1457. //----------------------------------------------------------------------------
  1458. HRESULT
  1459. CICMOCCtr::EnableModeless(BOOL fEnable)
  1460. {
  1461. m_fModelessEnabled = fEnable; // in case anyone wants to know.
  1462. return S_OK;
  1463. }
  1464. //+---------------------------------------------------------------------------
  1465. //
  1466. // Member: CInPlaceFrame::TranslateAccelerator
  1467. //
  1468. // Synopsis: The current active object's
  1469. // IOleInPlaceActiveObject::TranslateAccelerator() is being
  1470. // called at the top of our main message loop. If it
  1471. // does *not* want to handle a message, it will call
  1472. // this method of ours to pass the keyboard message back to
  1473. // us. We call ::TranslateAccelerator on the global main
  1474. // haccel, and, if it's handled (by returning TRUE - 1),
  1475. // we indicate it's handled by returning S_OK (0 :).
  1476. // On the other hand, if it's *not* handled, we return
  1477. // S_FALSE.
  1478. //
  1479. // Arguments: [lpmsg] -- keyboard msg to handle
  1480. // [wID] -- command identifier value - per spec.
  1481. //
  1482. // Returns: HRESULT
  1483. //
  1484. //----------------------------------------------------------------------------
  1485. STDMETHODIMP
  1486. CInPlaceFrame::TranslateAccelerator(LPMSG lpmsg, WORD wID)
  1487. {
  1488. // note this should never be called - only local servers
  1489. // (out of process) should call this by using
  1490. // OleTranslateAccelerator().
  1491. return m_pCtr->_TransAccelerator(lpmsg, wID);
  1492. }
  1493. //+---------------------------------------------------------------------------
  1494. //
  1495. // Member: CICMOCCtr::_TransAccelerator
  1496. //
  1497. // Synopsis: handle accelerator messages coming from
  1498. // either IOleInplaceFrame::TranslateAccelerator, or
  1499. // IOleControlSite::TranslateAccelerator.
  1500. //
  1501. // Effects: forwards them to the main accelerator table.
  1502. //
  1503. // Arguments: [lpmsg] -- keyboard msg.
  1504. // [wID] -- per spec.
  1505. //
  1506. // Returns: S_OK if we handled it, S_FALSE otherwise.
  1507. //
  1508. //----------------------------------------------------------------------------
  1509. HRESULT
  1510. CICMOCCtr::_TransAccelerator(LPMSG lpmsg, WORD wID)
  1511. {
  1512. // the docs suggest that this method might need to return E_INVALIDARG.
  1513. // anyway, this is defensive. If the FS OC
  1514. // calls us with an 0 ptr, we just return error
  1515. if (!lpmsg)
  1516. return E_INVALIDARG;
  1517. // forward the keystroke to the main accelerator table, if you have one.
  1518. // if you handle it, say S_OK.
  1519. #if 0
  1520. // this sample has no main accelerator table.
  1521. if (::TranslateAccelerator(GetMainWindow(),GetMainAccel(), lpmsg))
  1522. {
  1523. return S_OK; // we handled it
  1524. }
  1525. else
  1526. #endif
  1527. {
  1528. return S_FALSE; // we didn't.
  1529. }
  1530. }
  1531. //+---------------------------------------------------------------------------
  1532. //
  1533. // Class: CInPlaceSite ()
  1534. //
  1535. // Purpose: IOleInPlaceSite implementation.
  1536. //
  1537. // Interface: CInPlaceSite -- ctor
  1538. // QueryInterface -- get a new interface
  1539. // AddRef -- bump ref count
  1540. // Release -- decrement ref count
  1541. // GetWindow -- returns frame window
  1542. // ContextSensitiveHelp -- not implemented by design
  1543. // CanInPlaceActivate -- returns S_OK.
  1544. // OnInPlaceActivate -- caches IOleInPlaceObject ptr
  1545. // OnUIActivate -- returns S_OK - sets state
  1546. // GetWindowContext -- returns IOleInPlaceFrame,
  1547. // IOleInPlaceUIWindow,
  1548. // PosRect and ClipRect
  1549. // Scroll -- not implemented ever
  1550. // OnUIDeactivate -- kills objmenu
  1551. // OnInPlaceDeactivate -- releases cached IOleInPlaceObject
  1552. // DiscardUndoState -- returns S_OK
  1553. // DeactivateAndUndo -- deactivates in place active object
  1554. // OnPosRectChange -- never implemented.
  1555. //
  1556. //----------------------------------------------------------------------------
  1557. CInPlaceSite::CInPlaceSite(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  1558. {
  1559. }
  1560. STDMETHODIMP
  1561. CInPlaceSite::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  1562. {
  1563. return m_pCtr->QueryInterface(riid, ppv);
  1564. }
  1565. STDMETHODIMP_(ULONG)
  1566. CInPlaceSite::AddRef(VOID)
  1567. {
  1568. return m_pCtr->AddRef();
  1569. }
  1570. STDMETHODIMP_(ULONG)
  1571. CInPlaceSite::Release(VOID)
  1572. {
  1573. return m_pCtr->Release();
  1574. }
  1575. CPropertyBag::CPropertyBag(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  1576. {
  1577. }
  1578. CPropertyBag::~CPropertyBag(VOID)
  1579. {
  1580. for (INT i = 0; i < m_aryBagProps.Size(); i++)
  1581. {
  1582. m_pCtr->m_DOA.DynSysFreeString(m_aryBagProps[i].bstrName);
  1583. m_pCtr->m_DOA.DynVariantClear(&m_aryBagProps[i].varValue);
  1584. }
  1585. }
  1586. STDMETHODIMP
  1587. CPropertyBag::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  1588. {
  1589. return m_pCtr->QueryInterface(riid, ppv);
  1590. }
  1591. STDMETHODIMP_(ULONG)
  1592. CPropertyBag::AddRef(VOID)
  1593. {
  1594. return m_pCtr->AddRef();
  1595. }
  1596. STDMETHODIMP_(ULONG)
  1597. CPropertyBag::Release(VOID)
  1598. {
  1599. return m_pCtr->Release();
  1600. }
  1601. static LONG
  1602. LongFromValue(LPTSTR sz)
  1603. {
  1604. if (CmIsDigit(sz))
  1605. return CmAtol(sz);
  1606. return -1;
  1607. }
  1608. HRESULT
  1609. CPropertyBag::AddPropertyToBag(LPTSTR szName, LPTSTR szValue)
  1610. {
  1611. BagProp bp;
  1612. HRESULT hr;
  1613. LONG lValue;
  1614. LPWSTR pawch;
  1615. //WCHAR awch[INTERNET_MAX_URL_LENGTH] = {0};
  1616. // initialize so error cleanup can work properly.
  1617. bp.bstrName = 0;
  1618. m_pCtr->m_DOA.DynVariantInit(&bp.varValue);
  1619. if (!(pawch = (LPWSTR)CmMalloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR))))
  1620. {
  1621. goto MemoryError;
  1622. }
  1623. //if (-1 == ::mbstowcs(awch, szName, NElems(awch)))
  1624. #ifndef UNICODE
  1625. if (!MultiByteToWideChar(CP_ACP, 0, szName, -1, pawch, INTERNET_MAX_URL_LENGTH)) // NElems(awch)))
  1626. {
  1627. hr = E_FAIL;
  1628. goto Error;
  1629. }
  1630. #else
  1631. lstrcpyU(pawch, szName);
  1632. #endif
  1633. bp.bstrName = m_pCtr->m_DOA.DynSysAllocString(pawch);
  1634. if (!bp.bstrName)
  1635. goto MemoryError;
  1636. // see if it's a VT_I4.
  1637. lValue = ::LongFromValue(szValue);
  1638. // it's a VT_BSTR - probably most common case
  1639. if (-1 == lValue)
  1640. {
  1641. //if (-1 == ::mbstowcs(awch, szValue, NElems(awch)))
  1642. #ifndef UNICODE
  1643. if (!MultiByteToWideChar(CP_ACP, 0, szValue, -1, pawch, INTERNET_MAX_URL_LENGTH)) // NElems(awch)))
  1644. {
  1645. hr = E_FAIL;
  1646. goto Error;
  1647. }
  1648. #else
  1649. lstrcpyU(pawch, szValue);
  1650. #endif
  1651. V_VT(&bp.varValue) = VT_BSTR;
  1652. V_BSTR(&bp.varValue) = m_pCtr->m_DOA.DynSysAllocString(pawch);
  1653. if (!V_BSTR(&bp.varValue))
  1654. goto MemoryError;
  1655. }
  1656. else // it's a VT_I4
  1657. {
  1658. V_VT(&bp.varValue) = VT_I4;
  1659. V_I4(&bp.varValue) = lValue;
  1660. }
  1661. hr = m_aryBagProps.AppendIndirect(&bp);
  1662. if (hr)
  1663. goto Error;
  1664. Cleanup:
  1665. if (pawch)
  1666. {
  1667. CmFree(pawch);
  1668. }
  1669. return hr;
  1670. MemoryError:
  1671. hr = E_OUTOFMEMORY;
  1672. Error:
  1673. if (bp.bstrName)
  1674. m_pCtr->m_DOA.DynSysFreeString(bp.bstrName);
  1675. if (pawch)
  1676. {
  1677. CmFree(pawch);
  1678. }
  1679. m_pCtr->m_DOA.DynVariantClear(&bp.varValue);
  1680. goto Cleanup;
  1681. }
  1682. STDMETHODIMP
  1683. CPropertyBag::Read(LPCOLESTR pszName, LPVARIANT pVar, LPERRORLOG pErrorLog)
  1684. {
  1685. for (INT i = 0; i < m_aryBagProps.Size(); i++)
  1686. {
  1687. if (!::lstrcmpiU(m_aryBagProps[i].bstrName, pszName))
  1688. {
  1689. if (V_VT(pVar) == V_VT(&m_aryBagProps[i].varValue))
  1690. {
  1691. return m_pCtr->m_DOA.DynVariantCopy(pVar, &m_aryBagProps[i].varValue);
  1692. }
  1693. else
  1694. {
  1695. return m_pCtr->m_DOA.DynVariantChangeType(
  1696. pVar,
  1697. &m_aryBagProps[i].varValue,
  1698. 0,
  1699. V_VT(pVar));
  1700. }
  1701. }
  1702. }
  1703. return E_INVALIDARG; // we don't have the property.
  1704. }
  1705. // IOleWindow stuff
  1706. //+---------------------------------------------------------------------------
  1707. //
  1708. // Member: CInPlaceSite::GetWindow
  1709. //
  1710. // Synopsis: returns frame window.
  1711. //
  1712. // Arguments: [phwnd] -- return window *here*
  1713. //
  1714. //----------------------------------------------------------------------------
  1715. STDMETHODIMP
  1716. CInPlaceSite::GetWindow(HWND * phwnd)
  1717. {
  1718. // just reuse the CInPlaceFrame impl
  1719. return m_pCtr->m_IPF.GetWindow(phwnd);
  1720. }
  1721. //+---------------------------------------------------------------------------
  1722. //
  1723. // Member: CInPlaceSite::ContextSensitiveHelp
  1724. //
  1725. // Synopsis: This is not implemented by design - this is for
  1726. // the SHift+F1 context sensitive help mode and Esc
  1727. // to exit. Esc is already being used in the main
  1728. // accelerator table to mean 'stop browsing' to be
  1729. // like IE3. We do not do help this way.
  1730. //
  1731. //----------------------------------------------------------------------------
  1732. STDMETHODIMP
  1733. CInPlaceSite::ContextSensitiveHelp(BOOL fEnterMode)
  1734. {
  1735. return E_NOTIMPL;
  1736. }
  1737. // IOleInPlaceSite stuff
  1738. //+---------------------------------------------------------------------------
  1739. //
  1740. // Member: CInPlaceSite::CanInPlaceActivate
  1741. //
  1742. // Synopsis: just say yes.
  1743. //
  1744. //----------------------------------------------------------------------------
  1745. STDMETHODIMP
  1746. CInPlaceSite::CanInPlaceActivate(VOID)
  1747. {
  1748. return S_OK;
  1749. }
  1750. //+---------------------------------------------------------------------------
  1751. //
  1752. // Member: CInPlaceSite::OnInPlaceActivate
  1753. //
  1754. // Synopsis: caches the IOleInPlaceObject pointer.
  1755. //
  1756. //----------------------------------------------------------------------------
  1757. STDMETHODIMP
  1758. CInPlaceSite::OnInPlaceActivate(VOID)
  1759. {
  1760. HRESULT hr = m_pCtr->m_pOO->QueryInterface(
  1761. IID_IOleInPlaceObject,
  1762. (LPVOID *) &m_pCtr->m_pIPO);
  1763. if (!hr)
  1764. m_pCtr->SetState(OS_INPLACE);
  1765. return hr;
  1766. }
  1767. //+---------------------------------------------------------------------------
  1768. //
  1769. // Member: CInPlaceSite::OnUIActivate
  1770. //
  1771. // Synopsis: just sets state bit
  1772. //
  1773. //----------------------------------------------------------------------------
  1774. STDMETHODIMP
  1775. CInPlaceSite::OnUIActivate(VOID)
  1776. {
  1777. m_pCtr->SetState(OS_UIACTIVE);
  1778. return S_OK;
  1779. }
  1780. //+---------------------------------------------------------------------------
  1781. //
  1782. // Member: CInPlaceSite::GetWindowContext
  1783. //
  1784. // Synopsis: returns a bunch of interfaces and positioning interface
  1785. // the inplace-active object needs to do its thang.
  1786. //
  1787. // Arguments: [ppFrame] -- return our IOleInPlaceFrame implementation
  1788. // [ppDoc] -- return our IOleInPlaceUIWindow impl.
  1789. // [prcPosRect] -- position info
  1790. // [prcClipRect] -- clip info - same as pos info for this case
  1791. // [pFrameInfo] -- return 0 - inproc object doesn't use this.
  1792. //
  1793. // Notes: note that ppFrame and ppDoc are really just the same
  1794. // object because we're an SDI app.
  1795. //
  1796. //----------------------------------------------------------------------------
  1797. STDMETHODIMP
  1798. CInPlaceSite::GetWindowContext(
  1799. IOleInPlaceFrame **ppFrame,
  1800. IOleInPlaceUIWindow **ppDoc,
  1801. LPRECT prcPosRect,
  1802. LPRECT prcClipRect,
  1803. LPOLEINPLACEFRAMEINFO pFrameInfo)
  1804. {
  1805. // get the frame
  1806. HRESULT hr = m_pCtr->QueryInterface(
  1807. IID_IOleInPlaceFrame,
  1808. (LPVOID *)ppFrame);
  1809. MYDBGASSERT(!hr);
  1810. // return the frame again :) - this is all per-spec.
  1811. hr = m_pCtr->QueryInterface(
  1812. IID_IOleInPlaceUIWindow,
  1813. (LPVOID *) ppDoc);
  1814. MYDBGASSERT(!hr);
  1815. // get the clip and pos rect - same for this application.
  1816. HWND hWnd = m_pCtr->GetMainWindow();
  1817. MYDBGASSERT(hWnd);
  1818. HWND hWndFrame = m_pCtr->GetFrameWindow();
  1819. ::GetClientRect(hWndFrame, prcPosRect);
  1820. //
  1821. // NTRAID - #148143
  1822. // Apparently the W9x implementation is different, so MapWindowPoints for
  1823. // the clipping and position rect only on 9X. Also, make sure that the
  1824. // origin is NULL to keep post 2.0 versions of future splash happy on 9X.
  1825. //
  1826. if (OS_W9X)
  1827. {
  1828. ::MapWindowPoints(hWndFrame, hWnd, (LPPOINT)prcPosRect, 2);
  1829. prcPosRect->top = 0;
  1830. prcPosRect->left = 0;
  1831. }
  1832. *prcClipRect = *prcPosRect;
  1833. //
  1834. // OLYMPUS - #156880
  1835. // Clipping handled differently by future splash versions > 2.0
  1836. // so don't re-map the rect points, just use the client rect so we
  1837. // work with all splash versions - nickball
  1838. //
  1839. //::MapWindowPoints(hWndFrame, hWnd, (LPPOINT)prcClipRect, 2);
  1840. return S_OK;
  1841. }
  1842. //+---------------------------------------------------------------------------
  1843. //
  1844. // Member: CInPlaceSite::Scroll
  1845. //
  1846. // Synopsis: never implement this for FS OC. This has
  1847. // nothing to do with the scrollbars you see on the HTML.
  1848. //
  1849. //----------------------------------------------------------------------------
  1850. STDMETHODIMP
  1851. CInPlaceSite::Scroll(SIZE scrollExtent)
  1852. {
  1853. return E_NOTIMPL;
  1854. }
  1855. //+---------------------------------------------------------------------------
  1856. //
  1857. // Member: CInPlaceSite::OnUIDeactivate
  1858. //
  1859. // Synopsis: set state bits
  1860. //
  1861. // Arguments: [fUndoable] -- not used
  1862. //
  1863. //----------------------------------------------------------------------------
  1864. STDMETHODIMP
  1865. CInPlaceSite::OnUIDeactivate(BOOL fUndoable)
  1866. {
  1867. m_pCtr->SetState(OS_INPLACE);
  1868. return S_OK;
  1869. }
  1870. //+---------------------------------------------------------------------------
  1871. //
  1872. // Member: CInPlaceSite::OnInPlaceDeactivate
  1873. //
  1874. // Synopsis: releases the IOleInPlaceObject pointer we were
  1875. // caching for the object, and sets state to OS_RUNNING.
  1876. // Also fires the OLEIVERB_DISCARDUNDOSTATE at the control
  1877. // to tell it to release any undo state it's holding onto.
  1878. // I very much doubt the FS OC has any undo state,
  1879. // but, this is the protocol.
  1880. //
  1881. //----------------------------------------------------------------------------
  1882. STDMETHODIMP
  1883. CInPlaceSite::OnInPlaceDeactivate(VOID)
  1884. {
  1885. RECT rc;
  1886. if (m_pCtr->m_pIPO)
  1887. {
  1888. m_pCtr->m_pIPO->Release();
  1889. m_pCtr->SetState(OS_RUNNING);
  1890. m_pCtr->m_pIPO = 0;
  1891. }
  1892. if (m_pCtr->m_pOO)
  1893. {
  1894. m_pCtr->_GetDoVerbRect(&rc); // get rect for firing verbs.
  1895. m_pCtr->m_pOO->DoVerb(
  1896. OLEIVERB_DISCARDUNDOSTATE,
  1897. 0,
  1898. &m_pCtr->m_CS,
  1899. 0,
  1900. m_pCtr->GetFrameWindow(),
  1901. 0);
  1902. }
  1903. return S_OK;
  1904. }
  1905. //+---------------------------------------------------------------------------
  1906. //
  1907. // Member: CICMOCCtr::_GetDoVerbRect
  1908. //
  1909. // Synopsis: whenever firing DoVerb(), we need a rect for the object
  1910. // that describes the area for the object in parent client coords.
  1911. //
  1912. // Arguments: [prc] -- rect returned.
  1913. //
  1914. //----------------------------------------------------------------------------
  1915. VOID
  1916. CICMOCCtr::_GetDoVerbRect(LPRECT prc)
  1917. {
  1918. ::GetClientRect(GetFrameWindow(), prc);
  1919. ::MapWindowPoints(GetFrameWindow(), GetMainWindow(), (LPPOINT)prc, 2);
  1920. }
  1921. //+---------------------------------------------------------------------------
  1922. //
  1923. // Member: CInPlaceSite::DiscardUndoState
  1924. //
  1925. // Synopsis: just say OK - we don't hold any undo state for
  1926. // object.
  1927. //
  1928. //----------------------------------------------------------------------------
  1929. STDMETHODIMP
  1930. CInPlaceSite::DiscardUndoState(VOID)
  1931. {
  1932. return S_OK;
  1933. }
  1934. //+---------------------------------------------------------------------------
  1935. //
  1936. // Member: CInPlaceSite::DeactivateAndUndo
  1937. //
  1938. // Synopsis: absolutely minimum implementation of deactivateandundo.
  1939. // just calls IOleInPlaceObject::InPlaceDeactivate().
  1940. //
  1941. // Returns: S_OK always.
  1942. //
  1943. //----------------------------------------------------------------------------
  1944. STDMETHODIMP
  1945. CInPlaceSite::DeactivateAndUndo(VOID)
  1946. {
  1947. if (m_pCtr->m_pIPO)
  1948. m_pCtr->m_pIPO->InPlaceDeactivate();
  1949. return S_OK;
  1950. }
  1951. //+---------------------------------------------------------------------------
  1952. //
  1953. // Member: CInPlaceSite::OnPosRectChange
  1954. //
  1955. // Synopsis: never implement this.
  1956. //
  1957. //----------------------------------------------------------------------------
  1958. STDMETHODIMP
  1959. CInPlaceSite::OnPosRectChange(LPCRECT lprcPosRect)
  1960. {
  1961. return E_NOTIMPL;
  1962. }
  1963. //+---------------------------------------------------------------------------
  1964. //
  1965. // Class: COleContainer ()
  1966. //
  1967. // Purpose: our implementation of IOleContainer. does nothing.
  1968. //
  1969. //----------------------------------------------------------------------------
  1970. STDMETHODIMP
  1971. COleContainer::QueryInterface(REFIID riid, LPVOID FAR * ppv)
  1972. {
  1973. return m_pCtr->QueryInterface(riid, ppv);
  1974. }
  1975. STDMETHODIMP_(ULONG)
  1976. COleContainer::AddRef(VOID)
  1977. {
  1978. return m_pCtr->AddRef();
  1979. }
  1980. STDMETHODIMP_(ULONG)
  1981. COleContainer::Release(VOID)
  1982. {
  1983. return m_pCtr->Release();
  1984. }
  1985. COleContainer::COleContainer(LPICMOCCtr pCtr) : m_pCtr(pCtr)
  1986. {
  1987. }
  1988. STDMETHODIMP
  1989. COleContainer::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum)
  1990. {
  1991. MYDBGASSERT(FALSE); // never called
  1992. return E_NOTIMPL;
  1993. }
  1994. STDMETHODIMP
  1995. COleContainer::LockContainer(BOOL fLock)
  1996. {
  1997. MYDBGASSERT(FALSE); // never called
  1998. return S_OK;
  1999. }
  2000. STDMETHODIMP
  2001. COleContainer::ParseDisplayName(
  2002. IBindCtx *pbc,
  2003. LPOLESTR pszDisplayName,
  2004. ULONG *pchEaten,
  2005. IMoniker **ppmkOut)
  2006. {
  2007. return E_NOTIMPL;
  2008. }