Leaked source code of windows server 2003
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.

1818 lines
53 KiB

  1. //=--------------------------------------------------------------------------=
  2. // CtlEmbed.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of the interfaces required for inplace activation for
  13. // COleControl
  14. //
  15. #include "IPServer.H"
  16. #include "CtrlObj.H"
  17. #include "CtlHelp.H"
  18. #include "Globals.H"
  19. #include "StdEnum.H"
  20. #include "Util.H"
  21. // for ASSERT and FAIL
  22. //
  23. SZTHISFILE
  24. //=--------------------------------------------------------------------------=
  25. // all controls support the following in-place verbs at an absolute minimum.
  26. //
  27. #define CINPLACEVERBS 4
  28. const VERBINFO rgInPlaceVerbs [] = {
  29. { OLEIVERB_SHOW, 0, 0, 0},
  30. { OLEIVERB_HIDE, 0, 0, 0},
  31. { OLEIVERB_INPLACEACTIVATE, 0, 0, 0},
  32. { OLEIVERB_PRIMARY, 0, 0, 0}
  33. };
  34. // NOTE: Resource ID for Properties string must be 1000
  35. //
  36. const VERBINFO ovProperties =
  37. { CTLIVERB_PROPERTIES, 1000, 0, OLEVERBATTRIB_ONCONTAINERMENU };
  38. const VERBINFO ovUIActivate =
  39. { OLEIVERB_UIACTIVATE, 0, 0, 0};
  40. //=--------------------------------------------------------------------------=
  41. // COleControl::GetControlInfo (IOleControl)
  42. //=--------------------------------------------------------------------------=
  43. // returns some information on a control, such as an accelerator table, and
  44. // flags. really used for keyboard handling and mnemonics
  45. //
  46. // Parameters:
  47. // CONTROLINFO * - [in] where to put said information
  48. //
  49. // Output:
  50. // HRESULT - S_OK
  51. //
  52. // Notes:
  53. //
  54. STDMETHODIMP COleControl::GetControlInfo
  55. (
  56. CONTROLINFO *pControlInfo
  57. )
  58. {
  59. CHECK_POINTER(pControlInfo);
  60. // certain hosts have a bug in which it doesn't initialize the cb in the
  61. // CONTROLINFO structure, so we can only assert on that here.
  62. //
  63. ASSERT(pControlInfo->cb == sizeof(CONTROLINFO), "Host doesn't initialize CONTROLINFO structure");
  64. // NOTE: control writers should override this routine if they want to
  65. // return accelerator information in their control.
  66. //
  67. pControlInfo->hAccel = NULL;
  68. pControlInfo->cAccel = NULL;
  69. return S_OK;
  70. }
  71. //=--------------------------------------------------------------------------=
  72. // COleControl::OnMnemonic [IOleControl]
  73. //=--------------------------------------------------------------------------=
  74. // the container has decided to pass on a key that the end-user has pressed to
  75. // us. default implementation will be to just activate the control. people
  76. // looking for more functionality should override this method.
  77. //
  78. // Parameters:
  79. // LPMSG - [in] message for this mnemonic
  80. //
  81. // Output:
  82. // HRESULT - S_OK, E_POINTER
  83. //
  84. // Notes:
  85. //
  86. STDMETHODIMP COleControl::OnMnemonic
  87. (
  88. LPMSG pMsg
  89. )
  90. {
  91. // OVERRIDE: default implementation is to just activate our control.
  92. // user can override if they want more interesting behaviour.
  93. //
  94. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  95. }
  96. //=--------------------------------------------------------------------------=
  97. // COleControl:OnAmbientPropertyChange [IOleControl]
  98. //=--------------------------------------------------------------------------=
  99. // a container calls this whenever it changes an ambient property.
  100. //
  101. // Parameters:
  102. // DISPID - [in] dispid of the property that changed.
  103. //
  104. // Output:
  105. // HRESULT - S_OK
  106. //
  107. // Notes:
  108. //
  109. STDMETHODIMP COleControl::OnAmbientPropertyChange
  110. (
  111. DISPID dispid
  112. )
  113. {
  114. // if we're being told about a change in mode [design/run] then
  115. // remember that so our stashing of mode will update itself
  116. // correctly
  117. //
  118. if (dispid == DISPID_AMBIENT_USERMODE || dispid == DISPID_UNKNOWN)
  119. m_fModeFlagValid = FALSE;
  120. // just pass this on to the derived control and see if they want
  121. // to do anything with it.
  122. //
  123. AmbientPropertyChanged(dispid);
  124. return S_OK;
  125. }
  126. //=--------------------------------------------------------------------------=
  127. // COleControL::FreezeEvents [IOleControl]
  128. //=--------------------------------------------------------------------------=
  129. // allows a container to freeze all of a controls events. when events are
  130. // frozen, a control will not fire any of them.
  131. //
  132. // Parameters:
  133. // BOOL - [in] TRUE means FREEZE, FALSE means THAW
  134. //
  135. // Output:
  136. // HRESULT - S_OK
  137. //
  138. // Notes:
  139. // - we maintain an internal count of freezes versus thaws.
  140. //
  141. STDMETHODIMP COleControl::FreezeEvents
  142. (
  143. BOOL fFreeze
  144. )
  145. {
  146. // OVERRIDE: by default, we don't care. user can override if they want to.
  147. //
  148. return S_OK;
  149. }
  150. //=--------------------------------------------------------------------------=
  151. // COleControl::SetClientSite [IOleObject]
  152. //=--------------------------------------------------------------------------=
  153. // informs the embedded object [control] of it's client site [display
  154. // location] within it's container
  155. //
  156. // Parameters:
  157. // IOleClientSite * - [in] pointer to client site.
  158. //
  159. // Output:
  160. // HRESULT - S_OK, E_UNEXPECTED
  161. //
  162. // Notes:
  163. //
  164. STDMETHODIMP COleControl::SetClientSite
  165. (
  166. IOleClientSite *pClientSite
  167. )
  168. {
  169. RELEASE_OBJECT(m_pClientSite);
  170. RELEASE_OBJECT(m_pControlSite);
  171. RELEASE_OBJECT(m_pSimpleFrameSite);
  172. // store away the new client site
  173. //
  174. m_pClientSite = pClientSite;
  175. // if we've actually got one, then get some other interfaces we want to keep
  176. // around, and keep a handle on it
  177. //
  178. if (m_pClientSite) {
  179. m_pClientSite->AddRef();
  180. m_pClientSite->QueryInterface(IID_IOleControlSite, (void **)&m_pControlSite);
  181. if (OLEMISCFLAGSOFCONTROL(m_ObjectType) & OLEMISC_SIMPLEFRAME)
  182. m_pClientSite->QueryInterface(IID_ISimpleFrameSite, (void **)&m_pSimpleFrameSite);
  183. }
  184. return S_OK;
  185. }
  186. //=--------------------------------------------------------------------------=
  187. // COleControl::GetClientSite [IOleObject]
  188. //=--------------------------------------------------------------------------=
  189. // obtains a pointer to the controls client site.
  190. //
  191. // Parameters:
  192. // IOleClientSite ** - [out]
  193. //
  194. // Output:
  195. // HRESULT - S_OK
  196. //
  197. // Notes:
  198. //
  199. STDMETHODIMP COleControl::GetClientSite
  200. (
  201. IOleClientSite **ppClientSite
  202. )
  203. {
  204. CHECK_POINTER(ppClientSite);
  205. *ppClientSite = m_pClientSite;
  206. ADDREF_OBJECT(*ppClientSite);
  207. return S_OK;
  208. }
  209. //=--------------------------------------------------------------------------=
  210. // COleControl::SetHostNames [IOleObject]
  211. //=--------------------------------------------------------------------------=
  212. // Provides the control with the name of its container application and the
  213. // compound document in which it is embedded
  214. //
  215. // Parameters:
  216. // LPCOLESTR - [in] name of container application
  217. // LPCOLESTR - [in] name of container document
  218. //
  219. // Output:
  220. // HRESULT - S_OK
  221. //
  222. // Notes:
  223. // - we don't care about this
  224. //
  225. STDMETHODIMP COleControl::SetHostNames
  226. (
  227. LPCOLESTR szContainerApp,
  228. LPCOLESTR szContainerObject
  229. )
  230. {
  231. // we don't care about these
  232. //
  233. return S_OK;
  234. }
  235. //=--------------------------------------------------------------------------=
  236. // COleControl::Close [IOleObject]
  237. //=--------------------------------------------------------------------------=
  238. // Changes the control from the running to the loaded state
  239. //
  240. // Parameters:
  241. // DWORD - [in] indicates whether to save the object before closing
  242. //
  243. // Output:
  244. // HRESULT - S_OK, OLE_E_PROMPTSAVECANCELLED
  245. //
  246. // Notes:
  247. //
  248. STDMETHODIMP COleControl::Close
  249. (
  250. DWORD dwSaveOption
  251. )
  252. {
  253. HRESULT hr;
  254. if (m_fInPlaceActive) {
  255. hr = InPlaceDeactivate();
  256. RETURN_ON_FAILURE(hr);
  257. }
  258. // handle the save flag.
  259. //
  260. if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY || dwSaveOption == OLECLOSE_PROMPTSAVE) && m_fDirty) {
  261. if (m_pClientSite) m_pClientSite->SaveObject();
  262. if (m_pOleAdviseHolder) m_pOleAdviseHolder->SendOnSave();
  263. }
  264. return S_OK;
  265. }
  266. //=--------------------------------------------------------------------------=
  267. // COleControl::SetMoniker [IOleObject]
  268. //=--------------------------------------------------------------------------=
  269. // Notifies an object of its container's moniker, the object's own moniker
  270. // relative to the container, or the object's full moniker
  271. //
  272. // Parameters:
  273. // DWORD - [in] which moniker is being set
  274. // IMoniker * - [in] the moniker
  275. //
  276. // Output:
  277. // HRESULT - S_OK, E_FAIL
  278. //
  279. // Notes:
  280. // - we don't support monikers.
  281. //
  282. STDMETHODIMP COleControl::SetMoniker
  283. (
  284. DWORD dwWhichMoniker,
  285. IMoniker *pMoniker
  286. )
  287. {
  288. return E_NOTIMPL;
  289. }
  290. //=--------------------------------------------------------------------------=
  291. // COleControl::GetMoniker [IOleObject]
  292. //=--------------------------------------------------------------------------=
  293. // Returns a embedded object's moniker, which the caller can use to link to
  294. // the object
  295. //
  296. // Parameters:
  297. // DWORD - [in] how it's assigned
  298. // DWORD - [in] which moniker
  299. // IMoniker ** - [out] duh.
  300. //
  301. // Output:
  302. // HRESULT - E_NOTIMPL
  303. //
  304. // Notes:
  305. // - we don't support monikers
  306. //
  307. STDMETHODIMP COleControl::GetMoniker
  308. (
  309. DWORD dwAssign,
  310. DWORD dwWhichMoniker,
  311. IMoniker **ppMonikerOut
  312. )
  313. {
  314. return E_NOTIMPL;
  315. }
  316. //=--------------------------------------------------------------------------=
  317. // COleControl::InitFromData [IOleObject]
  318. //=--------------------------------------------------------------------------=
  319. // Initializes a newly created object with data from a specified data object,
  320. // which can reside either in the same container or on the Clipboard
  321. //
  322. // Parameters:
  323. // IDataObject* - [in] data object with the data
  324. // BOOL - [in] how object is created
  325. // DWORD - reserved
  326. //
  327. // Output:
  328. // HRESULT - S_OK, S_FALSE, E_NOTIMPL, OLE_E_NOTRUNNING
  329. //
  330. // Notes:
  331. // - we don't have data object support
  332. //
  333. STDMETHODIMP COleControl::InitFromData
  334. (
  335. IDataObject *pDataObject,
  336. BOOL fCreation,
  337. DWORD dwReserved
  338. )
  339. {
  340. return E_NOTIMPL;
  341. }
  342. //=--------------------------------------------------------------------------=
  343. // COleControl::GetClipboardData [IOleObject]
  344. //=--------------------------------------------------------------------------=
  345. // Retrieves a data object containing the current contents of the control.
  346. // Using the pointer to this data object, it is possible to create a new control
  347. // with the same data as the original
  348. //
  349. // Parameters:
  350. // DWORD - reserved
  351. // IDataObject ** - [out] data object for this control
  352. //
  353. // Output:
  354. // HREUSLT - S_OK, E_NOTIMPL, OLE_E_NOTRUNNING
  355. //
  356. // Notes:
  357. //
  358. STDMETHODIMP COleControl::GetClipboardData
  359. (
  360. DWORD dwReserved,
  361. IDataObject **ppDataObject
  362. )
  363. {
  364. *ppDataObject = NULL; // be a good neighbour
  365. return E_NOTIMPL;
  366. }
  367. //=--------------------------------------------------------------------------=
  368. // COleControl::DoVerb [IOleObject]
  369. //=--------------------------------------------------------------------------=
  370. // Requests an object to perform an action in response to an end-user's
  371. // action.
  372. //
  373. // Parameters:
  374. // LONG - [in] verb to be performed
  375. // LPMSG - [in] event that invoked the verb
  376. // IOleClientSite * - [in] the controls active client site
  377. // LONG - [in] reserved
  378. // HWND - [in] handle of window containing the object.
  379. // LPCRECT - [in] pointer to objects's display rectangle
  380. //
  381. // Output:
  382. // HRESULT - S_OK, OLE_E_NOTINPLACEACTIVE, OLE_E_CANT_BINDTOSOURCE,
  383. // DV_E_LINK, OLEOBJ_S_CANNOT_DOVERB_NOW, OLEOBJ_S_INVALIDHWND,
  384. // OLEOBJ_E_NOVERBS, OLEOBJ_S_INVALIDVERB, MK_E_CONNECT,
  385. // OLE_CLASSDIFF, E_NOTIMPL
  386. //
  387. // Notes:
  388. //
  389. STDMETHODIMP COleControl::DoVerb
  390. (
  391. LONG lVerb,
  392. LPMSG pMsg,
  393. IOleClientSite *pActiveSite,
  394. LONG lIndex,
  395. HWND hwndParent,
  396. LPCRECT prcPosRect
  397. )
  398. {
  399. HRESULT hr;
  400. switch (lVerb) {
  401. case OLEIVERB_SHOW:
  402. case OLEIVERB_INPLACEACTIVATE:
  403. case OLEIVERB_UIACTIVATE:
  404. hr = InPlaceActivate(lVerb);
  405. OnVerb(lVerb);
  406. return (hr);
  407. case OLEIVERB_HIDE:
  408. UIDeactivate();
  409. if (m_fInPlaceVisible) SetInPlaceVisible(FALSE);
  410. OnVerb(lVerb);
  411. return S_OK;
  412. // we used to have OLEIVERB_PRIMARY InPlaceActivate Ourselves, but it
  413. // turns out that the CDK and certain hosts expect this to show the
  414. // properties instead. Users can change what this verb does at will.
  415. //
  416. case OLEIVERB_PRIMARY:
  417. case CTLIVERB_PROPERTIES:
  418. case OLEIVERB_PROPERTIES:
  419. {
  420. // show the frame ourselves if the hose can't.
  421. //
  422. if (m_pControlSite) {
  423. hr = m_pControlSite->ShowPropertyFrame();
  424. if (hr != E_NOTIMPL)
  425. return hr;
  426. }
  427. IUnknown *pUnk = (IUnknown *)(IOleObject *)this;
  428. MAKE_WIDEPTR_FROMANSI(pwsz, NAMEOFOBJECT(m_ObjectType));
  429. ModalDialog(TRUE);
  430. hr = OleCreatePropertyFrame(GetActiveWindow(),
  431. GetSystemMetrics(SM_CXSCREEN) / 2,
  432. GetSystemMetrics(SM_CYSCREEN) / 2,
  433. pwsz,
  434. 1,
  435. &pUnk,
  436. CPROPPAGESOFCONTROL(m_ObjectType),
  437. (LPCLSID)*(PPROPPAGESOFCONTROL(m_ObjectType)),
  438. g_lcidLocale,
  439. NULL, NULL);
  440. ModalDialog(FALSE);
  441. return hr;
  442. }
  443. default:
  444. // if it's a derived-control defined verb, pass it on to them
  445. //
  446. if (lVerb > 0) {
  447. hr = DoCustomVerb(lVerb);
  448. if (hr == OLEOBJ_S_INVALIDVERB) {
  449. // unrecognised verb -- just do the primary verb and
  450. // activate it.
  451. //
  452. hr = InPlaceActivate(OLEIVERB_PRIMARY);
  453. return (FAILED(hr)) ? hr : OLEOBJ_S_INVALIDVERB;
  454. } else
  455. return hr;
  456. } else {
  457. FAIL("Unrecognized Negative verb in DoVerb(). bad.");
  458. return E_NOTIMPL;
  459. }
  460. break;
  461. }
  462. // dead code
  463. FAIL("this should be dead code!");
  464. }
  465. //=--------------------------------------------------------------------------=
  466. // COleControl::EnumVerbs [IOleObject]
  467. //=--------------------------------------------------------------------------=
  468. // create an enumerator object for the verbs this object supports.
  469. //
  470. // Parameters:
  471. // IEnumOleVERB ** - [out] new enumerator.
  472. //
  473. // Output:
  474. // HRESULT - S_OK, E_OUTOFMEMORY
  475. //
  476. // Notes:
  477. //
  478. STDMETHODIMP COleControl::EnumVerbs
  479. (
  480. IEnumOLEVERB **ppEnumVerbs
  481. )
  482. {
  483. int cVerbs;
  484. OLEVERB *rgVerbs, *pVerb;
  485. DWORD dw = OLEMISCFLAGSOFCONTROL(m_ObjectType);
  486. BOOL fCanInPlace = !(dw & OLEMISC_INVISIBLEATRUNTIME) || (dw & OLEMISC_ACTIVATEWHENVISIBLE);
  487. BOOL fCanUIActivate = !(dw & OLEMISC_NOUIACTIVATE);
  488. BOOL fHasProperties = (CPROPPAGESOFCONTROL(m_ObjectType) != 0);
  489. int cVerbExtra = CCUSTOMVERBSOFCONTROL(m_ObjectType);
  490. // count up all the verbs
  491. //
  492. cVerbs = (fCanInPlace ? CINPLACEVERBS : 0) + (fCanUIActivate ? 1 : 0)
  493. + (fHasProperties ? 1 : 0) + cVerbExtra;
  494. // if there aren't any, this suddenly gets really easy !
  495. //
  496. if (cVerbs == 0)
  497. return OLEOBJ_E_NOVERBS;
  498. // HeapAlloc some storage for these dudes so that we can pass them on to
  499. // the standard enumerator!
  500. //
  501. if (! (rgVerbs = (OLEVERB *)HeapAlloc(g_hHeap, 0, cVerbs * sizeof(OLEVERB))))
  502. return E_OUTOFMEMORY;
  503. // start copying over verbs. first, the in-place guys
  504. //
  505. pVerb = rgVerbs;
  506. if (fCanInPlace) {
  507. memcpy(pVerb, rgInPlaceVerbs, CINPLACEVERBS * sizeof(OLEVERB));
  508. pVerb += CINPLACEVERBS;
  509. }
  510. if (fCanUIActivate)
  511. memcpy(pVerb++, &ovUIActivate, sizeof(OLEVERB));
  512. // if their control has properties, copy that over now.
  513. //
  514. if (fHasProperties) {
  515. memcpy(pVerb, &ovProperties, sizeof(OLEVERB));
  516. pVerb++;
  517. }
  518. // finally, any custom verbs!
  519. //
  520. if (cVerbExtra) {
  521. memcpy(pVerb, CUSTOMVERBSOFCONTROL(m_ObjectType), sizeof(OLEVERB) * cVerbExtra);
  522. }
  523. *ppEnumVerbs = (IEnumOLEVERB *) (IEnumGeneric *) new CStandardEnum(IID_IEnumOLEVERB,
  524. cVerbs, sizeof(OLEVERB), rgVerbs, CopyOleVerb);
  525. if (!*ppEnumVerbs)
  526. return E_OUTOFMEMORY;
  527. // this forces us to go and look for the Localized DLLs. This is necessary here
  528. // because the CopyOleVerb will get information from localized resources, but
  529. // will only use the global GetResourceHandle, which only uses the global value
  530. // for the LCID. This turns out to not be a big performance hit, since this
  531. // function is typically only called in design mode, and we stash this value.
  532. //
  533. GetResourceHandle();
  534. return S_OK;
  535. }
  536. //=--------------------------------------------------------------------------=
  537. // COleControl::Update [IOleObject]
  538. //=--------------------------------------------------------------------------=
  539. // Updates an object handler's or link object's data or view caches.
  540. //
  541. // Output:
  542. // HRESULT - S_OK
  543. //
  544. // Notes:
  545. //
  546. STDMETHODIMP COleControl::Update
  547. (
  548. void
  549. )
  550. {
  551. // nothing to do!!!
  552. //
  553. return S_OK;
  554. }
  555. //=--------------------------------------------------------------------------=
  556. // COleControl::IsUpToDate [IOleObject]
  557. //=--------------------------------------------------------------------------=
  558. // Checks recursively whether or not an object is up to date.
  559. //
  560. // Output:
  561. // HRESULT - S_OK, S_FALSE, OLE_E_UNVAILABLE
  562. //
  563. // Notes:
  564. //
  565. STDMETHODIMP COleControl::IsUpToDate
  566. (
  567. void
  568. )
  569. {
  570. // we're always up to date
  571. //
  572. return S_OK;
  573. }
  574. //=--------------------------------------------------------------------------=
  575. // COleControl::GetUserClassID [IOleObject]
  576. //=--------------------------------------------------------------------------=
  577. // Returns the controls class identifier, the CLSID corresponding to the
  578. // string identifying the object to an end user.
  579. //
  580. // Parameters:
  581. // CLSID * - [in] where to put the CLSID
  582. //
  583. // Output:
  584. // HRESULT - S_OK, E_FAIL
  585. //
  586. // Notes:
  587. //
  588. STDMETHODIMP COleControl::GetUserClassID
  589. (
  590. CLSID *pclsid
  591. )
  592. {
  593. // this is the same as IPersist::GetClassID
  594. //
  595. return GetClassID(pclsid);
  596. }
  597. //=--------------------------------------------------------------------------=
  598. // COleControl::GetUserType [IOleObject]
  599. //=--------------------------------------------------------------------------=
  600. // Retrieves the user-type name of the control for display in user-interface
  601. // elements such as menus, list boxes, and dialog boxes.
  602. //
  603. // Parameters:
  604. // DWORD - [in] specifies the form of the type name.
  605. // LPOLESTR * - [out] where to put user type
  606. //
  607. // Output:
  608. // HRESULT - S_OK, OLE_S_USEREG, E_OUTOFMEMORY
  609. //
  610. // Notes:
  611. //
  612. STDMETHODIMP COleControl::GetUserType
  613. (
  614. DWORD dwFormOfType,
  615. LPOLESTR *ppszUserType
  616. )
  617. {
  618. *ppszUserType = OLESTRFROMANSI(NAMEOFOBJECT(m_ObjectType));
  619. return (*ppszUserType) ? S_OK : E_OUTOFMEMORY;
  620. }
  621. //=--------------------------------------------------------------------------=
  622. // COleControl::SetExtent [IOleObject]
  623. //=--------------------------------------------------------------------------=
  624. // Informs the control of how much display space its container has assigned it.
  625. //
  626. // Parameters:
  627. // DWORD - [in] which form or 'aspect' is to be displayed.
  628. // SIZEL * - [in] size limit for the control.
  629. //
  630. // Output:
  631. // HRESULT - S_OK, E_FAIL, OLE_E_NOTRUNNING
  632. //
  633. // Notes:
  634. //
  635. STDMETHODIMP COleControl::SetExtent
  636. (
  637. DWORD dwDrawAspect,
  638. SIZEL *psizel
  639. )
  640. {
  641. SIZEL sl;
  642. RECT rect;
  643. BOOL f;
  644. if (dwDrawAspect & DVASPECT_CONTENT) {
  645. // change the units to pixels, and resize the control.
  646. //
  647. HiMetricToPixel(psizel, &sl);
  648. // first call the user version. if they return FALSE, they want
  649. // to keep their current size
  650. //
  651. f = OnSetExtent(&sl);
  652. if (f)
  653. HiMetricToPixel(psizel, &m_Size);
  654. // set things up with our HWND if we've got one.
  655. //
  656. if (!m_pInPlaceSiteWndless) {
  657. if (m_fInPlaceActive) {
  658. // theoretically, one should not need to call OnPosRectChange
  659. // here, but there appear to be a few host related issues that
  660. // will make us keep it here. we won't, however, both with
  661. // windowless ole controls, since they are all new hosts who
  662. // should know better
  663. //
  664. GetWindowRect(m_hwnd, &rect);
  665. MapWindowPoints(NULL, m_hwndParent, (LPPOINT)&rect, 2);
  666. rect.right = rect.left + m_Size.cx;
  667. rect.bottom = rect.top + m_Size.cy;
  668. m_pInPlaceSite->OnPosRectChange(&rect);
  669. if (m_hwnd) {
  670. // just go and resize
  671. //
  672. if (m_hwndReflect)
  673. SetWindowPos(m_hwndReflect, 0, 0, 0, m_Size.cx, m_Size.cy,
  674. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  675. SetWindowPos(m_hwnd, 0, 0, 0, m_Size.cx, m_Size.cy,
  676. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  677. }
  678. } else if (m_hwnd) {
  679. SetWindowPos(m_hwnd, NULL, 0, 0, m_Size.cx, m_Size.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  680. } else {
  681. ViewChanged();
  682. }
  683. } else
  684. if (m_pInPlaceSite) m_pInPlaceSite->OnPosRectChange(&rect);
  685. // return code depending on whether or not user accepted given
  686. // size
  687. //
  688. return (f) ? S_OK : E_FAIL;
  689. } else {
  690. // we don't support any other aspects.
  691. //
  692. return DV_E_DVASPECT;
  693. }
  694. // dead code
  695. FAIL("This should be dead code");
  696. }
  697. //=--------------------------------------------------------------------------=
  698. // COleControl::GetExtent [IOleObject]
  699. //=--------------------------------------------------------------------------=
  700. // Retrieves the control's current display size.
  701. //
  702. // Parameters:
  703. // DWORD - [in] aspect
  704. // SIZEL * - [in] where to put results
  705. //
  706. // Output:
  707. // S_OK, E_INVALIDARG
  708. //
  709. // Notes:
  710. //
  711. STDMETHODIMP COleControl::GetExtent
  712. (
  713. DWORD dwDrawAspect,
  714. SIZEL *pSizeLOut
  715. )
  716. {
  717. if (dwDrawAspect & DVASPECT_CONTENT) {
  718. PixelToHiMetric((const SIZEL *)&m_Size, pSizeLOut);
  719. return S_OK;
  720. } else {
  721. return DV_E_DVASPECT;
  722. }
  723. // dead code
  724. }
  725. //=--------------------------------------------------------------------------=
  726. // COleControl::Advise [IOleObject]
  727. //=--------------------------------------------------------------------------=
  728. // establishes and advisory connection between the control and the container,
  729. // in which the control will notify the container of certain events.
  730. //
  731. // Parameters:
  732. // IAdviseSink * - [in] advise sink of calling object
  733. // DWORD - [out] cookie
  734. //
  735. // Output:
  736. // HRESULT - S_OK, E_OUTOFMEMORY
  737. //
  738. // Notes:
  739. //
  740. STDMETHODIMP COleControl::Advise
  741. (
  742. IAdviseSink *pAdviseSink,
  743. DWORD *pdwConnection
  744. )
  745. {
  746. HRESULT hr;
  747. // if we haven't yet created a standard advise holder object, do so
  748. // now
  749. //
  750. if (!m_pOleAdviseHolder) {
  751. hr = CreateOleAdviseHolder(&m_pOleAdviseHolder);
  752. RETURN_ON_FAILURE(hr);
  753. }
  754. // just get it to do the work for us!
  755. //
  756. return m_pOleAdviseHolder->Advise(pAdviseSink, pdwConnection);
  757. }
  758. //=--------------------------------------------------------------------------=
  759. // COleControl::Unadvise [IOleObject]
  760. //=--------------------------------------------------------------------------=
  761. // Deletes a previously established advisory connection.
  762. //
  763. // Parameters:
  764. // DWORD - [in] connection cookie
  765. //
  766. // Output:
  767. // HRESULT - S_OK, E_FAIL, OLE_E_NOCONNECTION
  768. //
  769. // Notes:
  770. //
  771. STDMETHODIMP COleControl::Unadvise
  772. (
  773. DWORD dwConnection
  774. )
  775. {
  776. if (!m_pOleAdviseHolder) {
  777. FAIL("Somebody called Unadvise on IOleObject without calling Advise!");
  778. CONNECT_E_NOCONNECTION;
  779. }
  780. return m_pOleAdviseHolder->Unadvise(dwConnection);
  781. }
  782. //=--------------------------------------------------------------------------=
  783. // COleControl::EnumAdvise [IOleObject]
  784. //=--------------------------------------------------------------------------=
  785. // Enumerates the advisory connections registered for an object, so a container
  786. // can know what to release prior to closing down.
  787. //
  788. // Parameters:
  789. // IEnumSTATDATA ** - [out] where to put enumerator
  790. //
  791. // Output:
  792. // HRESULT - S_OK, E_FAIL, E_NOTIMPL
  793. //
  794. // Notes:
  795. //
  796. STDMETHODIMP COleControl::EnumAdvise
  797. (
  798. IEnumSTATDATA **ppEnumOut
  799. )
  800. {
  801. if (!m_pOleAdviseHolder) {
  802. FAIL("Somebody Called EnumAdvise without setting up any connections");
  803. *ppEnumOut = NULL;
  804. return E_FAIL;
  805. }
  806. return m_pOleAdviseHolder->EnumAdvise(ppEnumOut);
  807. }
  808. //=--------------------------------------------------------------------------=
  809. // COleControl::GetMiscStatus [IOleObject]
  810. //=--------------------------------------------------------------------------=
  811. // Returns a value indicating the status of an object at creation and loading.
  812. //
  813. // Parameters:
  814. // DWORD - [in] aspect desired
  815. // DWORD * - [out] where to put the bits.
  816. //
  817. // Output:
  818. // HRESULT - S_OK, OLE_S_USEREG, CO_E_CLASSNOTREG, CO_E_READREGDB
  819. //
  820. // Notes:
  821. //
  822. STDMETHODIMP COleControl::GetMiscStatus
  823. (
  824. DWORD dwAspect,
  825. DWORD *pdwStatus
  826. )
  827. {
  828. CHECK_POINTER(pdwStatus);
  829. if (dwAspect == DVASPECT_CONTENT) {
  830. *pdwStatus = OLEMISCFLAGSOFCONTROL(m_ObjectType);
  831. return S_OK;
  832. } else {
  833. return DV_E_DVASPECT;
  834. }
  835. // dead code
  836. }
  837. //=--------------------------------------------------------------------------=
  838. // COleControl::SetColorScheme [IOleObject]
  839. //=--------------------------------------------------------------------------=
  840. // Specifies the color palette that the object application should use when it
  841. // edits the specified object.
  842. //
  843. // Parameters:
  844. // LOGPALETTE * - [in] new palette
  845. //
  846. // Output:
  847. // HRESULT - S_OK, E_NOTIMPL, OLE_E_PALETTE, OLE_E_NOTRUNNING
  848. //
  849. // Notes:
  850. // - we don't care.
  851. //
  852. STDMETHODIMP COleControl::SetColorScheme
  853. (
  854. LOGPALETTE *pLogpal
  855. )
  856. {
  857. // OVERRIDE: control writers can use this if they want to
  858. //
  859. return S_OK;
  860. }
  861. //=--------------------------------------------------------------------------=
  862. // COleControl::GetWindow [IOleWindow/IOleInPlaceObject]
  863. //=--------------------------------------------------------------------------=
  864. // Returns the window handle to one of the windows participating in in-place
  865. // activation (frame, document, parent, or in-place object window).
  866. //
  867. // Parameters:
  868. // HWND * - [out] where to return window handle.
  869. //
  870. // Output:
  871. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, E_FAIL
  872. //
  873. // Notes:
  874. // - this routine has slightly different semantics for windowless controls
  875. //
  876. STDMETHODIMP COleControl::GetWindow
  877. (
  878. HWND *phwnd
  879. )
  880. {
  881. // if we're windowles, then we want to return E_FAIL for this so hosts
  882. // know we're windowless
  883. //
  884. if (m_pInPlaceSiteWndless)
  885. return E_FAIL;
  886. // otherwise, just return our outer window.
  887. //
  888. *phwnd = GetOuterWindow();
  889. return (*phwnd) ? S_OK : E_UNEXPECTED;
  890. }
  891. //=--------------------------------------------------------------------------=
  892. // COleControl::ContextSensitiveHelp [IOleWindow/IOleInPlaceObject]
  893. //=--------------------------------------------------------------------------=
  894. // Determines whether context-sensitive help mode should be entered during an
  895. // in-place activation session.
  896. //
  897. // Parameters:
  898. // BOOL - [in] whether or not to enter help mode.
  899. //
  900. // Output:
  901. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED
  902. //
  903. // Notes:
  904. //
  905. STDMETHODIMP COleControl::ContextSensitiveHelp
  906. (
  907. BOOL fEnterMode
  908. )
  909. {
  910. return E_NOTIMPL;
  911. }
  912. //=--------------------------------------------------------------------------=
  913. // COleControl::InPlaceActivate
  914. //=--------------------------------------------------------------------------=
  915. // activates the control, and depending on the verb, optionally ui activates
  916. // it as well.
  917. //
  918. // Parameters:
  919. // LONG - [in] the verb that caused us to activate
  920. //
  921. // Output:
  922. // HRESULT
  923. //
  924. // Notes:
  925. // - this is spaghetti code at it's worst. effectively, we have to
  926. // be able to handle three types of site pointers -- IOleInPlaceSIte,
  927. // IOleInPlaceSiteEx, and IOleInPlaceSiteWindowless. not terribly
  928. // pretty.
  929. //
  930. HRESULT COleControl::InPlaceActivate
  931. (
  932. LONG lVerb
  933. )
  934. {
  935. BOOL f;
  936. SIZEL sizel;
  937. IOleInPlaceSiteEx *pIPSEx = NULL;
  938. HRESULT hr;
  939. BOOL fNoRedraw = FALSE;
  940. // if we don't have a client site, then there's not much to do.
  941. //
  942. if (!m_pClientSite)
  943. return S_OK;
  944. // get an InPlace site pointer.
  945. //
  946. if (!GetInPlaceSite()) {
  947. // if they want windowless support, then we want IOleInPlaceSiteWindowless
  948. //
  949. if (FCONTROLISWINDOWLESS(m_ObjectType))
  950. m_pClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&m_pInPlaceSiteWndless);
  951. // if we're not able to do windowless siting, then we'll just get an
  952. // IOleInPlaceSite pointer.
  953. //
  954. if (!m_pInPlaceSiteWndless) {
  955. hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
  956. RETURN_ON_FAILURE(hr);
  957. }
  958. }
  959. // now, we want an IOleInPlaceSiteEx pointer for windowless and flicker free
  960. // activation. if we're windowless, we've already got it, else we need to
  961. // try and get it
  962. //
  963. if (m_pInPlaceSiteWndless) {
  964. pIPSEx = (IOleInPlaceSiteEx *)m_pInPlaceSiteWndless;
  965. pIPSEx->AddRef();
  966. } else
  967. m_pClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&pIPSEx);
  968. // if we're not already active, go and do it.
  969. //
  970. if (!m_fInPlaceActive) {
  971. OLEINPLACEFRAMEINFO InPlaceFrameInfo;
  972. RECT rcPos, rcClip;
  973. // if we have a windowless site, see if we can go in-place windowless
  974. // active
  975. //
  976. hr = S_FALSE;
  977. if (m_pInPlaceSiteWndless) {
  978. hr = m_pInPlaceSiteWndless->CanWindowlessActivate();
  979. CLEANUP_ON_FAILURE(hr);
  980. // if they refused windowless, we'll try windowed
  981. //
  982. if (S_OK != hr) {
  983. RELEASE_OBJECT(m_pInPlaceSiteWndless);
  984. hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
  985. CLEANUP_ON_FAILURE(hr);
  986. }
  987. }
  988. // just try regular windowed in-place activation
  989. //
  990. if (hr != S_OK) {
  991. hr = m_pInPlaceSite->CanInPlaceActivate();
  992. if (hr != S_OK) {
  993. hr = (FAILED(hr)) ? E_FAIL : hr;
  994. goto CleanUp;
  995. }
  996. }
  997. // if we are here, then we have permission to go in-place active.
  998. // now, announce our intentions to actually go ahead and do this.
  999. //
  1000. hr = (pIPSEx) ? pIPSEx->OnInPlaceActivateEx(&fNoRedraw, (m_pInPlaceSiteWndless) ? ACTIVATE_WINDOWLESS : 0)
  1001. : m_pInPlaceSite->OnInPlaceActivate();
  1002. CLEANUP_ON_FAILURE(hr);
  1003. // if we're here, we're ready to go in-place active. we just need
  1004. // to set up some flags, and then create the window [if we have
  1005. // one]
  1006. //
  1007. m_fInPlaceActive = TRUE;
  1008. // we need to get some information about our location in the parent
  1009. // window, as well as some information about the parent
  1010. //
  1011. InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  1012. hr = GetInPlaceSite()->GetWindow(&m_hwndParent);
  1013. if (SUCCEEDED(hr))
  1014. hr = GetInPlaceSite()->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow, &rcPos, &rcClip, &InPlaceFrameInfo);
  1015. CLEANUP_ON_FAILURE(hr);
  1016. // make sure we'll display ourselves in the correct location with the correct size
  1017. //
  1018. sizel.cx = rcPos.right - rcPos.left;
  1019. sizel.cy = rcPos.bottom - rcPos.top;
  1020. f = OnSetExtent(&sizel);
  1021. if (f) m_Size = sizel;
  1022. SetObjectRects(&rcPos, &rcClip);
  1023. // finally, create our window if we have to!
  1024. //
  1025. if (!m_pInPlaceSiteWndless) {
  1026. SetInPlaceParent(m_hwndParent);
  1027. // create the window, and display it. die horribly if we couldnt'
  1028. //
  1029. if (!CreateInPlaceWindow(rcPos.left, rcPos.top, fNoRedraw)) {
  1030. hr = E_FAIL;
  1031. goto CleanUp;
  1032. }
  1033. }
  1034. }
  1035. // don't need this any more
  1036. //
  1037. RELEASE_OBJECT(pIPSEx);
  1038. // if we're not inplace visible yet, do so now.
  1039. //
  1040. if (!m_fInPlaceVisible)
  1041. SetInPlaceVisible(TRUE);
  1042. // if we weren't asked to UIActivate, then we're done.
  1043. //
  1044. if (lVerb != OLEIVERB_PRIMARY && lVerb != OLEIVERB_UIACTIVATE)
  1045. return S_OK;
  1046. // if we're not already UI active, do sow now.
  1047. //
  1048. if (!m_fUIActive) {
  1049. m_fUIActive = TRUE;
  1050. // inform the container of our intent
  1051. //
  1052. GetInPlaceSite()->OnUIActivate();
  1053. // take the focus [which is what UI Activation is all about !]
  1054. //
  1055. SetFocus(TRUE);
  1056. // set ourselves up in the host.
  1057. //
  1058. m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  1059. if (m_pInPlaceUIWindow)
  1060. m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  1061. // we have to explicitly say we don't wany any border space.
  1062. //
  1063. m_pInPlaceFrame->SetBorderSpace(NULL);
  1064. if (m_pInPlaceUIWindow)
  1065. m_pInPlaceUIWindow->SetBorderSpace(NULL);
  1066. }
  1067. // be-de-be-de-be-de that's all folks!
  1068. //
  1069. return S_OK;
  1070. CleanUp:
  1071. // something catastrophic happened [or, at least something bad].
  1072. // die a horrible fiery mangled painful death.
  1073. //
  1074. QUICK_RELEASE(pIPSEx);
  1075. m_fInPlaceActive = FALSE;
  1076. return hr;
  1077. }
  1078. //=--------------------------------------------------------------------------=
  1079. // COleControl::InPlaceDeactivate [IOleInPlaceObject]
  1080. //=--------------------------------------------------------------------------=
  1081. // Deactivates an active in-place object and discards the object's undo state.
  1082. //
  1083. // Output:
  1084. // HRESULT - S_OK, E_UNEXPECTED
  1085. //
  1086. // Notes:
  1087. //
  1088. STDMETHODIMP COleControl::InPlaceDeactivate
  1089. (
  1090. void
  1091. )
  1092. {
  1093. // if we're not in-place active yet, then this is easy.
  1094. //
  1095. if (!m_fInPlaceActive)
  1096. return S_OK;
  1097. // transition from UIActive back to active
  1098. //
  1099. if (m_fUIActive)
  1100. UIDeactivate();
  1101. m_fInPlaceActive = FALSE;
  1102. m_fInPlaceVisible = FALSE;
  1103. // if we have a window, tell it to go away.
  1104. //
  1105. if (m_hwnd) {
  1106. ASSERT(!m_pInPlaceSiteWndless, "internal state really messed up");
  1107. // so our window proc doesn't crash.
  1108. //
  1109. BeforeDestroyWindow();
  1110. SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)0xFFFFFFFF);
  1111. DestroyWindow(m_hwnd);
  1112. m_hwnd = NULL;
  1113. if (m_hwndReflect) {
  1114. SetWindowLongPtr(m_hwndReflect, GWLP_USERDATA, 0);
  1115. DestroyWindow(m_hwndReflect);
  1116. m_hwndReflect = NULL;
  1117. }
  1118. }
  1119. RELEASE_OBJECT(m_pInPlaceFrame);
  1120. RELEASE_OBJECT(m_pInPlaceUIWindow);
  1121. GetInPlaceSite()->OnInPlaceDeactivate();
  1122. return S_OK;
  1123. }
  1124. //=--------------------------------------------------------------------------=
  1125. // COleControl::UIDeactivate [IOleInPlaceObject]
  1126. //=--------------------------------------------------------------------------=
  1127. // transitions us from UI Active to merely being active [visible] for
  1128. // a control, this doesn't mean all that much.
  1129. //
  1130. // Output:
  1131. // HRESULT - S_OK, E_UNEXPECTED
  1132. //
  1133. // Notes:
  1134. //
  1135. STDMETHODIMP COleControl::UIDeactivate
  1136. (
  1137. void
  1138. )
  1139. {
  1140. // if we're not UIActive, not much to do.
  1141. //
  1142. if (!m_fUIActive)
  1143. return S_OK;
  1144. m_fUIActive = FALSE;
  1145. // notify frame windows, if appropriate, that we're no longer ui-active.
  1146. //
  1147. if (m_pInPlaceUIWindow) m_pInPlaceUIWindow->SetActiveObject(NULL, NULL);
  1148. m_pInPlaceFrame->SetActiveObject(NULL, NULL);
  1149. // we don't need to explicitly release the focus here since somebody
  1150. // else grabbing the focus is what is likely to cause us to get lose it
  1151. //
  1152. GetInPlaceSite()->OnUIDeactivate(FALSE);
  1153. return S_OK;
  1154. }
  1155. //=--------------------------------------------------------------------------=
  1156. // COleControl::SetObjectRects [IOleInPlaceObject]
  1157. //=--------------------------------------------------------------------------=
  1158. // Indicates how much of the control is visible.
  1159. //
  1160. // Parameters:
  1161. // LPCRECT - [in] position of the control.
  1162. // LPCRECT - [in] clipping rectangle for the control.
  1163. //
  1164. // Output:
  1165. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED
  1166. //
  1167. // Notes:
  1168. //
  1169. STDMETHODIMP COleControl::SetObjectRects
  1170. (
  1171. LPCRECT prcPos,
  1172. LPCRECT prcClip
  1173. )
  1174. {
  1175. BOOL fRemoveWindowRgn;
  1176. // move our window to the new location and handle clipping. not applicable
  1177. // for windowless controls, since the container will be responsible for all
  1178. // clipping.
  1179. //
  1180. if (m_hwnd) {
  1181. fRemoveWindowRgn = m_fUsingWindowRgn;
  1182. if (prcClip) {
  1183. // the container wants us to clip, so figure out if we really
  1184. // need to
  1185. //
  1186. RECT rcIXect;
  1187. if ( IntersectRect(&rcIXect, prcPos, prcClip) ) {
  1188. if (!EqualRect(&rcIXect, prcPos)) {
  1189. OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
  1190. HRGN tempRgn = CreateRectRgnIndirect(&rcIXect);
  1191. SetWindowRgn(GetOuterWindow(), tempRgn, TRUE);
  1192. if (m_hRgn != NULL)
  1193. DeleteObject(m_hRgn);
  1194. m_hRgn = tempRgn;
  1195. m_fUsingWindowRgn = TRUE;
  1196. fRemoveWindowRgn = FALSE;
  1197. }
  1198. }
  1199. }
  1200. if (fRemoveWindowRgn) {
  1201. SetWindowRgn(GetOuterWindow(), NULL, TRUE);
  1202. if (m_hRgn != NULL)
  1203. {
  1204. DeleteObject(m_hRgn);
  1205. m_hRgn = NULL;
  1206. }
  1207. m_fUsingWindowRgn = FALSE;
  1208. }
  1209. // set our control's location, but don't change it's size at all
  1210. // [people for whom zooming is important should set that up here]
  1211. //
  1212. DWORD dwFlag;
  1213. OnSetObjectRectsChangingWindowPos(&dwFlag);
  1214. int cx, cy;
  1215. cx = prcPos->right - prcPos->left;
  1216. cy = prcPos->bottom - prcPos->top;
  1217. SetWindowPos(GetOuterWindow(), NULL, prcPos->left, prcPos->top, cx, cy, dwFlag | SWP_NOZORDER | SWP_NOACTIVATE);
  1218. }
  1219. // save out our current location. windowless controls want this more
  1220. // that windowed ones do, but everybody can have it just in case
  1221. //
  1222. m_rcLocation = *prcPos;
  1223. return S_OK;
  1224. }
  1225. //=--------------------------------------------------------------------------=
  1226. // COleControl::ReactivateAndUndo [IOleInPlaceObject]
  1227. //=--------------------------------------------------------------------------=
  1228. // Reactivates a previously deactivated object, undoing the last state of the object.
  1229. //
  1230. // Output:
  1231. // HRESULT - S_OK, E_NOTUNDOABLE
  1232. //
  1233. // Notes:
  1234. //
  1235. STDMETHODIMP COleControl::ReactivateAndUndo
  1236. (
  1237. void
  1238. )
  1239. {
  1240. return E_NOTIMPL;
  1241. }
  1242. //=--------------------------------------------------------------------------=
  1243. // COleControl::OnWindowMessage [IOleInPlaceObjectWindowless]
  1244. //=--------------------------------------------------------------------------=
  1245. // this method lets the container dispatch a message to a windowless OLE
  1246. // object.
  1247. //
  1248. // Parameters:
  1249. // UINT - [in] the message
  1250. // WPARAM - [in] the messages wparam
  1251. // LPARAM - [in] duh.
  1252. // LRESULT * - [out] the output value
  1253. //
  1254. // Output:
  1255. // HRESULT - S_OK
  1256. //
  1257. // Notes:
  1258. // - people should call m_pInPlaceSiteWndless->OnDefWindowMessage [control
  1259. // writers should just call OcxDefWindowProc(msg, wparam, lparam)];
  1260. //
  1261. STDMETHODIMP COleControl::OnWindowMessage
  1262. (
  1263. UINT msg,
  1264. WPARAM wParam,
  1265. LPARAM lParam,
  1266. LRESULT *plResult
  1267. )
  1268. {
  1269. // little bit of pre-processing -- we need to handle some cases here
  1270. // before passing the messages on
  1271. //
  1272. switch (msg) {
  1273. // make sure our UI Activation correctly matches the focus
  1274. //
  1275. case WM_KILLFOCUS:
  1276. case WM_SETFOCUS:
  1277. // give the control site focus notification
  1278. //
  1279. if (m_fInPlaceActive && m_pControlSite)
  1280. m_pControlSite->OnFocus(msg == WM_SETFOCUS);
  1281. break;
  1282. }
  1283. // just pass it to the control's window proc.
  1284. //
  1285. *plResult = WindowProc(msg, wParam, lParam);
  1286. return S_OK;
  1287. }
  1288. //=--------------------------------------------------------------------------=
  1289. // COleControl::GetDropTarget [IOleInPlaceObjectWindowless]
  1290. //=--------------------------------------------------------------------------=
  1291. // this method returns a pointer to the objects IDropTarget interface. since
  1292. // they do not have a window, windowless objects cannot register an IDropTarget
  1293. // interface.
  1294. //
  1295. // Parameters:
  1296. // IDropTarget ** - [out]
  1297. //
  1298. // Output:
  1299. // HRESULT - S_OK, E_NOTIMPL
  1300. //
  1301. // Notes:
  1302. //
  1303. STDMETHODIMP COleControl::GetDropTarget
  1304. (
  1305. IDropTarget **ppDropTarget
  1306. )
  1307. {
  1308. // OVERRIDE: if you want to do drag and drop and you're windowless,
  1309. // override me.
  1310. //
  1311. return E_NOTIMPL;
  1312. }
  1313. //=--------------------------------------------------------------------------=
  1314. // COleControl::TranslateAccelerator [IOleInPlaceActiveObject]
  1315. //=--------------------------------------------------------------------------=
  1316. // Processes menu accelerator-key messages from the container's message queue.
  1317. //
  1318. // Parameters:
  1319. // LPMSG - [in] the message that has the special key in it.
  1320. //
  1321. // Output:
  1322. // HRESULT - S_OK, S_FALSE, E_UNEXPECTED
  1323. //
  1324. // Notes:
  1325. //
  1326. STDMETHODIMP COleControl::TranslateAccelerator
  1327. (
  1328. LPMSG pmsg
  1329. )
  1330. {
  1331. // see if we want it or not.
  1332. //
  1333. if (OnSpecialKey(pmsg))
  1334. return S_OK;
  1335. // if not, then we want to forward it back to the site for further processing
  1336. //
  1337. if (m_pControlSite)
  1338. return m_pControlSite->TranslateAccelerator(pmsg, _SpecialKeyState());
  1339. // we didn't want it.
  1340. //
  1341. return S_FALSE;
  1342. }
  1343. //=--------------------------------------------------------------------------=
  1344. // COleControl::OnFrameWindowActivate [IOleInPlaceActiveObject]
  1345. //=--------------------------------------------------------------------------=
  1346. // Notifies the control when the container's top-level frame window is
  1347. // activated or deactivated.
  1348. //
  1349. // Parameters:
  1350. // BOOL - [in] state of containers top level window.
  1351. //
  1352. // Output:
  1353. // HRESULT - S_OK
  1354. //
  1355. // Notes:
  1356. //
  1357. STDMETHODIMP COleControl::OnFrameWindowActivate
  1358. (
  1359. BOOL fActivate
  1360. )
  1361. {
  1362. // we're supposed to go UI active in this case
  1363. //
  1364. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  1365. }
  1366. //=--------------------------------------------------------------------------=
  1367. // COleControl::OnDocWindowActivate [IOleInPlaceActiveObject]
  1368. //=--------------------------------------------------------------------------=
  1369. // Notifies the active control when the container's document window is
  1370. // activated or deactivated.
  1371. //
  1372. // Parameters:
  1373. // BOOL - state of mdi child window.
  1374. //
  1375. // Output:
  1376. // HRESULT - S_OK
  1377. //
  1378. // Notes:
  1379. //
  1380. STDMETHODIMP COleControl::OnDocWindowActivate
  1381. (
  1382. BOOL fActivate
  1383. )
  1384. {
  1385. // we're supposed to go UI active in this case
  1386. //
  1387. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  1388. }
  1389. //=--------------------------------------------------------------------------=
  1390. // COleControl::ResizeBorder [IOleInPlaceActiveObject]
  1391. //=--------------------------------------------------------------------------=
  1392. // Alerts the control that it needs to resize its border space.
  1393. //
  1394. // Parameters:
  1395. // LPCRECT - [in] new outer rectangle for border space
  1396. // IOleInPlaceUIWindow * - [in] the document or frame who's border has changed
  1397. // BOOL - [in] true if it was the fram window taht called.
  1398. //
  1399. // Output:
  1400. // HRESULT - S_OK
  1401. //
  1402. // Notes:
  1403. //
  1404. STDMETHODIMP COleControl::ResizeBorder
  1405. (
  1406. LPCRECT prcBorder,
  1407. IOleInPlaceUIWindow *pInPlaceUIWindow,
  1408. BOOL fFrame
  1409. )
  1410. {
  1411. // this is largely uninteresting to us, since we have no border.
  1412. //
  1413. return S_OK;
  1414. }
  1415. //=--------------------------------------------------------------------------=
  1416. // COleControl::EnableModeless [IOleInPlaceActiveObject]
  1417. //=--------------------------------------------------------------------------=
  1418. // Enables or disables modeless dialog boxes when the container creates or
  1419. // destroys a modal dialog box.
  1420. //
  1421. // Parameters:
  1422. // BOOL - [in] enable or disable modeless dialogs.
  1423. //
  1424. // Output:
  1425. // HRESULT - S_OK
  1426. //
  1427. // Notes:
  1428. //
  1429. STDMETHODIMP COleControl::EnableModeless
  1430. (
  1431. BOOL fEnable
  1432. )
  1433. {
  1434. // phenomenally uninteresting
  1435. //
  1436. return S_OK;
  1437. }
  1438. //=--------------------------------------------------------------------------=
  1439. // COleControl::GetClassInfo [IProvideClassInfo]
  1440. //=--------------------------------------------------------------------------=
  1441. // returns the TypeInfo for the control's coclass.
  1442. //
  1443. // Parameters:
  1444. // ITypeInfo ** - [out]
  1445. //
  1446. // Output:
  1447. // HRESULT
  1448. //
  1449. // Notes:
  1450. //
  1451. STDMETHODIMP COleControl::GetClassInfo
  1452. (
  1453. ITypeInfo **ppTypeInfo
  1454. )
  1455. {
  1456. ITypeLib *pTypeLib;
  1457. HRESULT hr;
  1458. CHECK_POINTER(ppTypeInfo);
  1459. *ppTypeInfo = NULL;
  1460. // go and get our type library.
  1461. // CONSIDER: - go to the same sorta scheme that we use for TypeInfo caching.
  1462. // CONSIDER: - consider trying to register our typelib if this fails.
  1463. //
  1464. hr = LoadRegTypeLib(*g_pLibid, (USHORT)VERSIONOFOBJECT(m_ObjectType), 0,
  1465. LANGIDFROMLCID(g_lcidLocale), &pTypeLib);
  1466. RETURN_ON_FAILURE(hr);
  1467. // got the typelib. get typeinfo for our coclass.
  1468. //
  1469. hr = pTypeLib->GetTypeInfoOfGuid((REFIID)CLSIDOFOBJECT(m_ObjectType), ppTypeInfo);
  1470. pTypeLib->Release();
  1471. RETURN_ON_FAILURE(hr);
  1472. return S_OK;
  1473. }
  1474. //=--------------------------------------------------------------------------=
  1475. // COleControl::ViewChange [callable]
  1476. //=--------------------------------------------------------------------------=
  1477. // called whenever the view of the object has changed.
  1478. //
  1479. // Notes:
  1480. //
  1481. void COleControl::ViewChanged
  1482. (
  1483. void
  1484. )
  1485. {
  1486. // send the view change notification to anybody listening.
  1487. //
  1488. if (m_pViewAdviseSink) {
  1489. m_pViewAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
  1490. // if they only asked to be advised once, kill the connection
  1491. //
  1492. if (m_fViewAdviseOnlyOnce)
  1493. SetAdvise(DVASPECT_CONTENT, 0, NULL);
  1494. }
  1495. }
  1496. //=--------------------------------------------------------------------------=
  1497. // COleControl::SetInPlaceVisible [helper]
  1498. //=--------------------------------------------------------------------------=
  1499. // controls the visibility of the control window.
  1500. //
  1501. // Parameters:
  1502. // BOOL - TRUE shows FALSE hides.
  1503. //
  1504. // Notes:
  1505. //
  1506. void COleControl::SetInPlaceVisible
  1507. (
  1508. BOOL fShow
  1509. )
  1510. {
  1511. BOOL fVisible;
  1512. m_fInPlaceVisible = fShow;
  1513. // don't do anything if we don't have a window. otherwise, set it
  1514. //
  1515. if (m_hwnd) {
  1516. fVisible = ((GetWindowLong(GetOuterWindow(), GWL_STYLE) & WS_VISIBLE) != 0);
  1517. if (fVisible && !fShow)
  1518. ShowWindow(GetOuterWindow(), SW_HIDE);
  1519. else if (!fVisible && fShow)
  1520. ShowWindow(GetOuterWindow(), SW_SHOWNA);
  1521. }
  1522. }
  1523. //=--------------------------------------------------------------------------=
  1524. // COleControl::AmbientPropertyChanged [overridable]
  1525. //=--------------------------------------------------------------------------=
  1526. // a method that derived controls can override to do whatever they want.
  1527. // we don't particularily care about this event.
  1528. //
  1529. // Parameters:
  1530. // DISPID - [in] dispid of prop that changed.
  1531. //
  1532. // Notes:
  1533. //
  1534. void COleControl::AmbientPropertyChanged
  1535. (
  1536. DISPID dispid
  1537. )
  1538. {
  1539. // do nothing
  1540. }
  1541. //=--------------------------------------------------------------------------=
  1542. // COleControl::DoCustomVerb [overridable]
  1543. //=--------------------------------------------------------------------------=
  1544. // we were asked to execute a verb we don't know about right away. see if
  1545. // it's a verb that the dervied-control defined.
  1546. //
  1547. // Parameters:
  1548. // LONG - [in] the verb.
  1549. //
  1550. // Output:
  1551. // HRESULT - S_OK, OLEOBJ_S_INVALIDVERB
  1552. //
  1553. // Notes:
  1554. //
  1555. HRESULT COleControl::DoCustomVerb
  1556. (
  1557. LONG lVerb
  1558. )
  1559. {
  1560. return OLEOBJ_S_INVALIDVERB;
  1561. }
  1562. //=--------------------------------------------------------------------------=
  1563. // COleControl::OnSetExtent [overridable]
  1564. //=--------------------------------------------------------------------------=
  1565. // let the user do something in the resize, if they care.
  1566. //
  1567. // Parameters:
  1568. // SIZEL * - [in] new values.
  1569. //
  1570. // Output:
  1571. // BOOL - FALSE means keep current size
  1572. //
  1573. // Notes:
  1574. //
  1575. BOOL COleControl::OnSetExtent
  1576. (
  1577. const SIZEL *pSizeL
  1578. )
  1579. {
  1580. return TRUE;
  1581. }
  1582. //=--------------------------------------------------------------------------=
  1583. // COleControl::OnSpecialKey [overridable]
  1584. //=--------------------------------------------------------------------------=
  1585. // allows controls to handle special keys such as arrows, CTRL+, etc ...
  1586. //
  1587. // Parameters:
  1588. // LPMSG - [in] the special key msg.
  1589. //
  1590. // Output:
  1591. // BOOL - TRUE we processed it, FALSE we didn't.
  1592. //
  1593. // Notes:
  1594. //
  1595. BOOL COleControl::OnSpecialKey
  1596. (
  1597. LPMSG pmsg
  1598. )
  1599. {
  1600. // do nothing.
  1601. //
  1602. return FALSE;
  1603. }
  1604. //=--------------------------------------------------------------------------=
  1605. // COleControl::ModalDialog [callable, utility]
  1606. //=--------------------------------------------------------------------------=
  1607. // should be called when the control is about to show and hide a modal dialog.
  1608. //
  1609. // Parameters:
  1610. // BOOL - [in] true means showing a modal dialog, false means done
  1611. //
  1612. // Notes:
  1613. //
  1614. void COleControl::ModalDialog
  1615. (
  1616. BOOL fShow
  1617. )
  1618. {
  1619. // notify the container of our intention to show a modal dialog...
  1620. //
  1621. if (m_pInPlaceFrame)
  1622. m_pInPlaceFrame->EnableModeless(!fShow);
  1623. }
  1624. //=--------------------------------------------------------------------------=
  1625. // COleControl::BeforeDestroyWindow [overridable]
  1626. //=--------------------------------------------------------------------------=
  1627. // called just before we destroy a window. gives the user the opportunity to
  1628. // save information out, especially if they're a subclassed control, and this
  1629. // is an interesting thing to do.
  1630. //
  1631. // Notes:
  1632. //
  1633. void COleControl::BeforeDestroyWindow
  1634. (
  1635. void
  1636. )
  1637. {
  1638. // fweeee
  1639. }
  1640. //=--------------------------------------------------------------------------=
  1641. // COleControl::OnSetObjectRectsChangingWIndowPos [overridable]
  1642. //=--------------------------------------------------------------------------=
  1643. // called just before we perform a SetWindowPos in the SetObjectRects
  1644. // function. gives a control the opportunity to change the flags.
  1645. //
  1646. // Notes:
  1647. //
  1648. void COleControl::OnSetObjectRectsChangingWindowPos(DWORD *dwFlag)
  1649. {
  1650. *dwFlag = 0;
  1651. }
  1652. void COleControl::OnVerb(LONG lVerb)
  1653. {
  1654. }