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.

1480 lines
45 KiB

  1. // Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
  2. //=--------------------------------------------------------------------------=
  3. //
  4. // implementation of the interfaces required for inplace activation for
  5. // COleControl
  6. #include "header.h"
  7. #include "CtlHelp.H"
  8. #include "StdEnum.H"
  9. #include "ctrlobj.h"
  10. #ifndef _DEBUG
  11. #undef THIS_FILE
  12. static const char THIS_FILE[] = __FILE__;
  13. #endif
  14. // External Functions
  15. BOOL IsBusy() ; // See wwheel.cpp - TRUE if we are merging.
  16. // all controls support the following in-place verbs at an absolute minimum.
  17. #define CINPLACEVERBS 4
  18. const VERBINFO rgInPlaceVerbs [] = {
  19. { OLEIVERB_SHOW, 0, 0, 0},
  20. { OLEIVERB_HIDE, 0, 0, 0},
  21. { OLEIVERB_INPLACEACTIVATE, 0, 0, 0},
  22. { OLEIVERB_PRIMARY, 0, 0, 0}
  23. };
  24. // NOTE: Resource ID for Properties string must be 1000
  25. const VERBINFO ovProperties =
  26. { CTLIVERB_PROPERTIES, 1000, 0, OLEVERBATTRIB_ONCONTAINERMENU };
  27. const VERBINFO ovUIActivate =
  28. { OLEIVERB_UIACTIVATE, 0, 0, 0};
  29. //=--------------------------------------------------------------------------=
  30. // COleControl::GetControlInfo (IOleControl)
  31. //=--------------------------------------------------------------------------=
  32. // returns some information on a control, such as an accelerator table, and
  33. // flags. really used for keyboard handling and mnemonics
  34. //
  35. // Parameters:
  36. // CONTROLINFO * - [in] where to put said information
  37. STDMETHODIMP COleControl::GetControlInfo(CONTROLINFO *pControlInfo)
  38. {
  39. DBWIN("COleControl::GetControlInfo()\n");
  40. CHECK_POINTER(pControlInfo);
  41. // certain hosts have a bug in which it doesn't initialize the cb in the
  42. // CONTROLINFO structure, so we can only assert on that here.
  43. ASSERT_COMMENT(pControlInfo->cb == sizeof(CONTROLINFO), "Host doesn't initialize CONTROLINFO structure");
  44. // NOTE: control writers should override this routine if they want to
  45. // return accelerator information in their control.
  46. pControlInfo->hAccel = NULL;
  47. pControlInfo->cAccel = NULL;
  48. return S_OK;
  49. }
  50. //=--------------------------------------------------------------------------=
  51. // COleControl::OnMnemonic [IOleControl]
  52. //=--------------------------------------------------------------------------=
  53. // the container has decided to pass on a key that the end-user has pressed to
  54. // us. default implementation will be to just activate the control. people
  55. // looking for more functionality should override this method.
  56. //
  57. // Parameters:
  58. // LPMSG - [in] message for this mnemonic
  59. STDMETHODIMP COleControl::OnMnemonic(LPMSG pMsg)
  60. {
  61. // OVERRIDE: default implementation is to just activate our control.
  62. // user can override if they want more interesting behaviour.
  63. DBWIN("COleControl::OnMnemonic()\n");
  64. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  65. }
  66. //=--------------------------------------------------------------------------=
  67. // COleControl:OnAmbientPropertyChange [IOleControl]
  68. //=--------------------------------------------------------------------------=
  69. // a container calls this whenever it changes an ambient property.
  70. //
  71. // Parameters:
  72. // DISPID - [in] dispid of the property that changed.
  73. //
  74. // Output:
  75. // HRESULT - S_OK
  76. STDMETHODIMP COleControl::OnAmbientPropertyChange(DISPID dispid)
  77. {
  78. // if we're being told about a change in mode [design/run] then
  79. // remember that so our stashing of mode will update itself
  80. // correctly
  81. DBWIN("COleControl::OnAmbientPropertyChange()\n");
  82. if (dispid == DISPID_AMBIENT_USERMODE || dispid == DISPID_UNKNOWN)
  83. m_fModeFlagValid = FALSE;
  84. // just pass this on to the derived control and see if they want
  85. // to do anything with it.
  86. //
  87. AmbientPropertyChanged(dispid);
  88. return S_OK;
  89. }
  90. //=--------------------------------------------------------------------------=
  91. // COleControL::FreezeEvents [IOleControl]
  92. //=--------------------------------------------------------------------------=
  93. // allows a container to freeze all of a controls events. when events are
  94. // frozen, a control will not fire any of them.
  95. //
  96. // Parameters:
  97. // BOOL - [in] TRUE means FREEZE, FALSE means THAW
  98. //
  99. // Output:
  100. // HRESULT - S_OK
  101. //
  102. // Notes:
  103. // - we maintain an internal count of freezes versus thaws.
  104. STDMETHODIMP COleControl::FreezeEvents(BOOL fFreeze)
  105. {
  106. // OVERRIDE: by default, we don't care. user can override if they want to.
  107. DBWIN("COleControl::FreezeEvents()\n");
  108. return S_OK;
  109. }
  110. //=--------------------------------------------------------------------------=
  111. // COleControl::SetClientSite [IOleObject]
  112. //=--------------------------------------------------------------------------=
  113. // informs the embedded object [control] of it's client site [display
  114. // location] within it's container
  115. //
  116. // Parameters:
  117. // IOleClientSite * - [in] pointer to client site.
  118. //
  119. // Output:
  120. // HRESULT - S_OK, E_UNEXPECTED
  121. STDMETHODIMP COleControl::SetClientSite(IOleClientSite *pClientSite)
  122. {
  123. RELEASE_OBJECT(m_pClientSite);
  124. RELEASE_OBJECT(m_pControlSite);
  125. // RELEASE_OBJECT(m_pSimpleFrameSite);
  126. // store away the new client site
  127. m_pClientSite = pClientSite;
  128. // if we've actually got one, then get some other interfaces we want to keep
  129. // around, and keep a handle on it
  130. if (m_pClientSite) {
  131. m_pClientSite->AddRef();
  132. m_pClientSite->QueryInterface(IID_IOleControlSite, (void **)&m_pControlSite);
  133. #ifdef _DEBUG
  134. if (OLEMISCFLAGSOFCONTROL(m_ObjectType) & OLEMISC_SIMPLEFRAME)
  135. ASSERT_COMMENT(FALSE, "We took out simple frame support...");
  136. // m_pClientSite->QueryInterface(IID_ISimpleFrameSite, (void **)&m_pSimpleFrameSite);
  137. #endif
  138. }
  139. return S_OK;
  140. }
  141. //=--------------------------------------------------------------------------=
  142. // COleControl::GetClientSite [IOleObject]
  143. //=--------------------------------------------------------------------------=
  144. // obtains a pointer to the controls client site.
  145. //
  146. // Parameters:
  147. // IOleClientSite ** - [out]
  148. STDMETHODIMP COleControl::GetClientSite(IOleClientSite **ppClientSite)
  149. {
  150. CHECK_POINTER(ppClientSite);
  151. *ppClientSite = m_pClientSite;
  152. ADDREF_OBJECT(*ppClientSite);
  153. return S_OK;
  154. }
  155. //=--------------------------------------------------------------------------=
  156. // COleControl::SetHostNames [IOleObject]
  157. //=--------------------------------------------------------------------------=
  158. // Provides the control with the name of its container application and the
  159. // compound document in which it is embedded
  160. //
  161. // Parameters:
  162. // LPCOLESTR - [in] name of container application
  163. // LPCOLESTR - [in] name of container document
  164. STDMETHODIMP COleControl::SetHostNames(LPCOLESTR szContainerApp,
  165. LPCOLESTR szContainerObject)
  166. {
  167. return S_OK;
  168. }
  169. //=--------------------------------------------------------------------------=
  170. // COleControl::Close [IOleObject]
  171. //=--------------------------------------------------------------------------=
  172. // Changes the control from the running to the loaded state
  173. //
  174. // Parameters:
  175. // DWORD - [in] indicates whether to save the object before closing
  176. //
  177. // Output:
  178. // HRESULT - S_OK, OLE_E_PROMPTSAVECANCELLED
  179. STDMETHODIMP COleControl::Close(DWORD dwSaveOption)
  180. {
  181. HRESULT hr;
  182. if (m_fInPlaceActive) {
  183. hr = InPlaceDeactivate();
  184. RETURN_ON_FAILURE(hr);
  185. }
  186. #if 0
  187. // handle the save flag.
  188. 14-Aug-1997 [ralphw] We don't support any form of saving
  189. if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY || dwSaveOption == OLECLOSE_PROMPTSAVE) && m_fDirty) {
  190. if (m_pClientSite) m_pClientSite->SaveObject();
  191. if (m_pOleAdviseHolder) m_pOleAdviseHolder->SendOnSave();
  192. }
  193. #endif
  194. return S_OK;
  195. }
  196. //=--------------------------------------------------------------------------=
  197. // COleControl::SetMoniker [IOleObject]
  198. //=--------------------------------------------------------------------------=
  199. // Notifies an object of its container's moniker, the object's own moniker
  200. // relative to the container, or the object's full moniker
  201. //
  202. // Parameters:
  203. // DWORD - [in] which moniker is being set
  204. // IMoniker * - [in] the moniker
  205. //
  206. // Output:
  207. // HRESULT - S_OK, E_FAIL
  208. //
  209. // Notes:
  210. // - we don't support monikers.
  211. STDMETHODIMP COleControl::SetMoniker(DWORD dwWhichMoniker, IMoniker *pMoniker)
  212. {
  213. return E_NOTIMPL;
  214. }
  215. //=--------------------------------------------------------------------------=
  216. // COleControl::GetMoniker [IOleObject]
  217. //=--------------------------------------------------------------------------=
  218. // Returns a embedded object's moniker, which the caller can use to link to
  219. // the object
  220. //
  221. // Parameters:
  222. // DWORD - [in] how it's assigned
  223. // DWORD - [in] which moniker
  224. // IMoniker ** - [out] duh.
  225. //
  226. // Output:
  227. // HRESULT - E_NOTIMPL
  228. //
  229. // Notes:
  230. // - we don't support monikers
  231. STDMETHODIMP COleControl::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
  232. IMoniker **ppMonikerOut)
  233. {
  234. return E_NOTIMPL;
  235. }
  236. //=--------------------------------------------------------------------------=
  237. // COleControl::InitFromData [IOleObject]
  238. //=--------------------------------------------------------------------------=
  239. // Initializes a newly created object with data from a specified data object,
  240. // which can reside either in the same container or on the Clipboard
  241. //
  242. // Parameters:
  243. // IDataObject* - [in] data object with the data
  244. // BOOL - [in] how object is created
  245. // DWORD - reserved
  246. //
  247. // Output:
  248. // HRESULT - S_OK, S_FALSE, E_NOTIMPL, OLE_E_NOTRUNNING
  249. //
  250. // Notes:
  251. // - we don't have data object support
  252. STDMETHODIMP COleControl::InitFromData(IDataObject *pDataObject,
  253. BOOL fCreation, DWORD dwReserved)
  254. {
  255. return E_NOTIMPL;
  256. }
  257. //=--------------------------------------------------------------------------=
  258. // COleControl::GetClipboardData [IOleObject]
  259. //=--------------------------------------------------------------------------=
  260. // Retrieves a data object containing the current contents of the control.
  261. // Using the pointer to this data object, it is possible to create a new control
  262. // with the same data as the original
  263. //
  264. // Parameters:
  265. // DWORD - reserved
  266. // IDataObject ** - [out] data object for this control
  267. //
  268. // Output:
  269. // HREUSLT - S_OK, E_NOTIMPL, OLE_E_NOTRUNNING
  270. //
  271. // Notes:
  272. //
  273. STDMETHODIMP COleControl::GetClipboardData(DWORD dwReserved,
  274. IDataObject **ppDataObject)
  275. {
  276. *ppDataObject = NULL; // be a good neighbour
  277. return E_NOTIMPL;
  278. }
  279. //=--------------------------------------------------------------------------=
  280. // COleControl::DoVerb [IOleObject]
  281. //=--------------------------------------------------------------------------=
  282. // Requests an object to perform an action in response to an end-user's
  283. // action.
  284. //
  285. // Parameters:
  286. // LONG - [in] verb to be performed
  287. // LPMSG - [in] event that invoked the verb
  288. // IOleClientSite * - [in] the controls active client site
  289. // LONG - [in] reserved
  290. // HWND - [in] handle of window containing the object.
  291. // LPCRECT - [in] pointer to objects's display rectangle
  292. //
  293. // Output:
  294. // HRESULT - S_OK, OLE_E_NOTINPLACEACTIVE, OLE_E_CANT_BINDTOSOURCE,
  295. // DV_E_LINK, OLEOBJ_S_CANNOT_DOVERB_NOW, OLEOBJ_S_INVALIDHWND,
  296. // OLEOBJ_E_NOVERBS, OLEOBJ_S_INVALIDVERB, MK_E_CONNECT,
  297. // OLE_CLASSDIFF, E_NOTIMPL
  298. STDMETHODIMP COleControl::DoVerb(LONG lVerb, LPMSG pMsg,
  299. IOleClientSite *pActiveSite, LONG lIndex, HWND hwndParent,
  300. LPCRECT prcPosRect)
  301. {
  302. HRESULT hr;
  303. switch (lVerb) {
  304. case OLEIVERB_SHOW:
  305. case OLEIVERB_INPLACEACTIVATE:
  306. case OLEIVERB_UIACTIVATE:
  307. // Check to see if we are merging?
  308. if (IsBusy())
  309. {
  310. // We cannot precess these if we are merging.
  311. return OLEOBJ_S_CANNOT_DOVERB_NOW ;
  312. }
  313. else
  314. {
  315. return InPlaceActivate(lVerb);
  316. }
  317. case OLEIVERB_HIDE:
  318. UIDeactivate();
  319. if (m_fInPlaceVisible)
  320. SetInPlaceVisible(FALSE);
  321. return S_OK;
  322. // we used to have OLEIVERB_PRIMARY InPlaceActivate Ourselves, but it
  323. // turns out that the CDK and certain hosts expect this to show the
  324. // properties instead. Users can change what this verb does at will.
  325. case OLEIVERB_PRIMARY:
  326. case CTLIVERB_PROPERTIES:
  327. case OLEIVERB_PROPERTIES:
  328. {
  329. // show the frame ourselves if the hose can't.
  330. if (m_pControlSite) {
  331. hr = m_pControlSite->ShowPropertyFrame();
  332. if (hr != E_NOTIMPL)
  333. return hr;
  334. }
  335. IUnknown *pUnk = (IUnknown *)(IOleObject *)this;
  336. MAKE_WIDEPTR_FROMANSI(pwsz, NAMEOFOBJECT(m_ObjectType));
  337. #if 0
  338. ModalDialog(TRUE);
  339. hr = OleCreatePropertyFrame(GetActiveWindow(),
  340. GetSystemMetrics(SM_CXSCREEN) / 2,
  341. GetSystemMetrics(SM_CYSCREEN) / 2,
  342. pwsz,
  343. 1,
  344. &pUnk,
  345. CPROPPAGESOFCONTROL(m_ObjectType),
  346. (LPCLSID)*(PPROPPAGESOFCONTROL(m_ObjectType)),
  347. g_lcidLocale,
  348. NULL, NULL);
  349. ModalDialog(FALSE);
  350. #endif
  351. return hr;
  352. }
  353. default:
  354. // if it's a derived-control defined verb, pass it on to them
  355. //
  356. if (lVerb > 0) {
  357. hr = DoCustomVerb(lVerb);
  358. if (hr == OLEOBJ_S_INVALIDVERB) {
  359. // unrecognised verb -- just do the primary verb and
  360. // activate the sucker.
  361. //
  362. hr = InPlaceActivate(OLEIVERB_PRIMARY);
  363. return (FAILED(hr)) ? hr : OLEOBJ_S_INVALIDVERB;
  364. } else
  365. return hr;
  366. }
  367. else {
  368. FAIL("Unrecognized Negative verb in DoVerb().");
  369. return E_NOTIMPL;
  370. }
  371. break;
  372. }
  373. // dead code
  374. FAIL("this should be dead code!");
  375. }
  376. //=--------------------------------------------------------------------------=
  377. // COleControl::EnumVerbs [IOleObject]
  378. //=--------------------------------------------------------------------------=
  379. // create an enumerator object for the verbs this object supports.
  380. //
  381. // Parameters:
  382. // IEnumOleVERB ** - [out] new enumerator.
  383. //
  384. // Output:
  385. // HRESULT - S_OK, E_OUTOFMEMORY
  386. STDMETHODIMP COleControl::EnumVerbs(IEnumOLEVERB **ppEnumVerbs)
  387. {
  388. int cVerbs;
  389. OLEVERB *rgVerbs, *pVerb;
  390. DWORD dw = OLEMISCFLAGSOFCONTROL(m_ObjectType);
  391. BOOL fCanInPlace = !(dw & OLEMISC_INVISIBLEATRUNTIME) || (dw & OLEMISC_ACTIVATEWHENVISIBLE);
  392. BOOL fCanUIActivate = !(dw & OLEMISC_NOUIACTIVATE);
  393. BOOL fHasProperties = (CPROPPAGESOFCONTROL(m_ObjectType) != 0);
  394. int cVerbExtra = CCUSTOMVERBSOFCONTROL(m_ObjectType);
  395. // count up all the verbs
  396. cVerbs = (fCanInPlace ? CINPLACEVERBS : 0) + (fCanUIActivate ? 1 : 0)
  397. + (fHasProperties ? 1 : 0) + cVerbExtra;
  398. // if there aren't any, this suddenly gets really easy !
  399. if (cVerbs == 0)
  400. return OLEOBJ_E_NOVERBS;
  401. if (! (rgVerbs = (OLEVERB *) lcCalloc(cVerbs * sizeof(OLEVERB))))
  402. return E_OUTOFMEMORY;
  403. // start copying over verbs. first, the in-place guys
  404. pVerb = rgVerbs;
  405. if (fCanInPlace) {
  406. memcpy(pVerb, rgInPlaceVerbs, CINPLACEVERBS * sizeof(OLEVERB));
  407. pVerb += CINPLACEVERBS;
  408. }
  409. if (fCanUIActivate)
  410. memcpy(pVerb++, &ovUIActivate, sizeof(OLEVERB));
  411. // if their control has properties, copy that over now.
  412. //
  413. if (fHasProperties) {
  414. memcpy(pVerb, &ovProperties, sizeof(OLEVERB));
  415. pVerb++;
  416. }
  417. // finally, any custom verbs!
  418. //
  419. if (cVerbExtra) {
  420. memcpy(pVerb, CUSTOMVERBSOFCONTROL(m_ObjectType), sizeof(OLEVERB) * cVerbExtra);
  421. }
  422. *ppEnumVerbs = (IEnumOLEVERB *) (IEnumGeneric *) new CStandardEnum(IID_IEnumOLEVERB,
  423. cVerbs, sizeof(OLEVERB), rgVerbs, CopyOleVerb);
  424. if (!*ppEnumVerbs)
  425. return E_OUTOFMEMORY;
  426. return S_OK;
  427. }
  428. //=--------------------------------------------------------------------------=
  429. // COleControl::Update [IOleObject]
  430. //=--------------------------------------------------------------------------=
  431. // Updates an object handler's or link object's data or view caches.
  432. STDMETHODIMP COleControl::Update(void)
  433. {
  434. return S_OK;
  435. }
  436. //=--------------------------------------------------------------------------=
  437. // COleControl::IsUpToDate [IOleObject]
  438. //=--------------------------------------------------------------------------=
  439. // Checks recursively whether or not an object is up to date.
  440. STDMETHODIMP COleControl::IsUpToDate(void)
  441. {
  442. return S_OK;
  443. }
  444. //=--------------------------------------------------------------------------=
  445. // COleControl::GetUserClassID [IOleObject]
  446. //=--------------------------------------------------------------------------=
  447. // Returns the controls class identifier, the CLSID corresponding to the
  448. // string identifying the object to an end user.
  449. //
  450. // Parameters:
  451. // CLSID * - [in] where to put the CLSID
  452. STDMETHODIMP COleControl::GetUserClassID(CLSID *pclsid)
  453. {
  454. // this is the same as IPersist::GetClassID
  455. return GetClassID(pclsid);
  456. }
  457. //=--------------------------------------------------------------------------=
  458. // COleControl::GetUserType [IOleObject]
  459. //=--------------------------------------------------------------------------=
  460. // Retrieves the user-type name of the control for display in user-interface
  461. // elements such as menus, list boxes, and dialog boxes.
  462. //
  463. // Parameters:
  464. // DWORD - [in] specifies the form of the type name.
  465. // LPOLESTR * - [out] where to put user type
  466. //
  467. // Output:
  468. // HRESULT - S_OK, OLE_S_USEREG, E_OUTOFMEMORY
  469. STDMETHODIMP COleControl::GetUserType(DWORD dwFormOfType,
  470. LPOLESTR *ppszUserType)
  471. {
  472. *ppszUserType = OLESTRFROMANSI(NAMEOFOBJECT(m_ObjectType));
  473. return (*ppszUserType) ? S_OK : E_OUTOFMEMORY;
  474. }
  475. //=--------------------------------------------------------------------------=
  476. // COleControl::SetExtent [IOleObject]
  477. //=--------------------------------------------------------------------------=
  478. // Informs the control of how much display space its container has assigned it.
  479. //
  480. // Parameters:
  481. // DWORD - [in] which form or 'aspect' is to be displayed.
  482. // SIZEL * - [in] size limit for the control.
  483. //
  484. // Output:
  485. // HRESULT - S_OK, E_FAIL, OLE_E_NOTRUNNING
  486. STDMETHODIMP COleControl::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  487. {
  488. SIZE sl;
  489. RECT rect;
  490. BOOL f;
  491. if (dwDrawAspect & DVASPECT_CONTENT) {
  492. // change the units to pixels, and resize the control.
  493. HiMetricToPixel(psizel, &sl);
  494. // first call the user version. if they return FALSE, they want
  495. // to keep their current size
  496. f = OnSetExtent(&sl);
  497. if (f)
  498. HiMetricToPixel(psizel, &m_Size);
  499. // set things up with our HWND if we've got one.
  500. if (!m_pInPlaceSiteWndless) {
  501. if (m_fInPlaceActive) {
  502. // theoretically, one should not need to call OnPosRectChange
  503. // here, but there appear to be a few host related issues that
  504. // will make us keep it here. we won't, however, bother with
  505. // windowless ole controls, since they are all new hosts who
  506. // should know better
  507. GetWindowRect(m_hwnd, &rect);
  508. MapWindowPoints(NULL, m_hwndParent, (LPPOINT)&rect, 2);
  509. rect.right = rect.left + m_Size.cx;
  510. rect.bottom = rect.top + m_Size.cy;
  511. m_pInPlaceSite->OnPosRectChange(&rect);
  512. if (m_hwnd) {
  513. // just go and resize
  514. SetWindowPos(m_hwnd, 0, 0, 0, m_Size.cx, m_Size.cy,
  515. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  516. }
  517. } else if (m_hwnd) {
  518. SetWindowPos(m_hwnd, NULL, 0, 0, m_Size.cx, m_Size.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  519. } else {
  520. ViewChanged();
  521. }
  522. } else
  523. if (m_pInPlaceSite) m_pInPlaceSite->OnPosRectChange(&rect);
  524. // return code depending on whether or not user accepted given
  525. // size
  526. return (f) ? S_OK : E_FAIL;
  527. } else {
  528. // we don't support any other aspects.
  529. return DV_E_DVASPECT;
  530. }
  531. // dead code
  532. FAIL("This should be dead code");
  533. }
  534. //=--------------------------------------------------------------------------=
  535. // COleControl::GetExtent [IOleObject]
  536. //=--------------------------------------------------------------------------=
  537. // Retrieves the control's current display size.
  538. //
  539. // Parameters:
  540. // DWORD - [in] aspect
  541. // SIZEL * - [in] where to put results
  542. //
  543. // Output:
  544. // S_OK, E_INVALIDARG
  545. //
  546. // Notes:
  547. //
  548. STDMETHODIMP COleControl::GetExtent(DWORD dwDrawAspect, SIZEL *pSizeLOut)
  549. {
  550. if (dwDrawAspect & DVASPECT_CONTENT) {
  551. PixelToHiMetric((const SIZEL *)&m_Size, pSizeLOut);
  552. return S_OK;
  553. } else {
  554. return DV_E_DVASPECT;
  555. }
  556. // dead code
  557. }
  558. //=--------------------------------------------------------------------------=
  559. // COleControl::Advise [IOleObject]
  560. //=--------------------------------------------------------------------------=
  561. // establishes and advisory connection between the control and the container,
  562. // in which the control will notify the container of certain events.
  563. //
  564. // Parameters:
  565. // IAdviseSink * - [in] advise sink of calling object
  566. // DWORD - [out] cookie
  567. //
  568. // Output:
  569. // HRESULT - S_OK, E_OUTOFMEMORY
  570. STDMETHODIMP COleControl::Advise(IAdviseSink *pAdviseSink,
  571. DWORD *pdwConnection)
  572. {
  573. HRESULT hr;
  574. // if we haven't yet created a standard advise holder object, do so
  575. // now
  576. if (!m_pOleAdviseHolder) {
  577. hr = CreateOleAdviseHolder(&m_pOleAdviseHolder);
  578. RETURN_ON_FAILURE(hr);
  579. }
  580. // just get it to do the work for us!
  581. return m_pOleAdviseHolder->Advise(pAdviseSink, pdwConnection);
  582. }
  583. //=--------------------------------------------------------------------------=
  584. // COleControl::Unadvise [IOleObject]
  585. //=--------------------------------------------------------------------------=
  586. // Deletes a previously established advisory connection.
  587. //
  588. // Parameters:
  589. // DWORD - [in] connection cookie
  590. //
  591. // Output:
  592. // HRESULT - S_OK, E_FAIL, OLE_E_NOCONNECTION
  593. STDMETHODIMP COleControl::Unadvise(DWORD dwConnection)
  594. {
  595. if (!m_pOleAdviseHolder) {
  596. FAIL("Somebody called Unadvise on IOleObject without calling Advise!");
  597. CONNECT_E_NOCONNECTION;
  598. }
  599. return m_pOleAdviseHolder->Unadvise(dwConnection);
  600. }
  601. //=--------------------------------------------------------------------------=
  602. // COleControl::EnumAdvise [IOleObject]
  603. //=--------------------------------------------------------------------------=
  604. // Enumerates the advisory connections registered for an object, so a container
  605. // can know what to release prior to closing down.
  606. //
  607. // Parameters:
  608. // IEnumSTATDATA ** - [out] where to put enumerator
  609. //
  610. // Output:
  611. // HRESULT - S_OK, E_FAIL, E_NOTIMPL
  612. STDMETHODIMP COleControl::EnumAdvise ( IEnumSTATDATA **ppEnumOut )
  613. {
  614. if (!m_pOleAdviseHolder) {
  615. FAIL("Somebody Called EnumAdvise without setting up any connections");
  616. *ppEnumOut = NULL;
  617. return E_FAIL;
  618. }
  619. return m_pOleAdviseHolder->EnumAdvise(ppEnumOut);
  620. }
  621. //=--------------------------------------------------------------------------=
  622. // COleControl::GetMiscStatus [IOleObject]
  623. //=--------------------------------------------------------------------------=
  624. // Returns a value indicating the status of an object at creation and loading.
  625. //
  626. // Parameters:
  627. // DWORD - [in] aspect desired
  628. // DWORD * - [out] where to put the bits.
  629. //
  630. // Output:
  631. // HRESULT - S_OK, OLE_S_USEREG, CO_E_CLASSNOTREG, CO_E_READREGDB
  632. //
  633. // Notes:
  634. //
  635. STDMETHODIMP COleControl::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
  636. {
  637. CHECK_POINTER(pdwStatus);
  638. if (dwAspect == DVASPECT_CONTENT) {
  639. *pdwStatus = OLEMISCFLAGSOFCONTROL(m_ObjectType);
  640. return S_OK;
  641. }
  642. else
  643. return DV_E_DVASPECT;
  644. }
  645. //=--------------------------------------------------------------------------=
  646. // COleControl::SetColorScheme [IOleObject]
  647. //=--------------------------------------------------------------------------=
  648. // Specifies the color palette that the object application should use when it
  649. // edits the specified object.
  650. //
  651. // Parameters:
  652. // LOGPALETTE * - [in] new palette
  653. //
  654. // Output:
  655. // HRESULT - S_OK, E_NOTIMPL, OLE_E_PALETTE, OLE_E_NOTRUNNING
  656. //
  657. // Notes:
  658. // - we don't care.
  659. STDMETHODIMP COleControl::SetColorScheme(LOGPALETTE *pLogpal)
  660. {
  661. return S_OK;
  662. }
  663. //=--------------------------------------------------------------------------=
  664. // COleControl::GetWindow [IOleWindow/IOleInPlaceObject]
  665. //=--------------------------------------------------------------------------=
  666. // Returns the window handle to one of the windows participating in in-place
  667. // activation (frame, document, parent, or in-place object window).
  668. //
  669. // Parameters:
  670. // HWND * - [out] where to return window handle.
  671. //
  672. // Output:
  673. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, E_FAIL
  674. //
  675. // Notes:
  676. // - this routine has slightly different semantics for windowless controls
  677. STDMETHODIMP COleControl::GetWindow(HWND *phwnd)
  678. {
  679. // if we're windowles, then we want to return E_FAIL for this so hosts
  680. // know we're windowless
  681. if (m_pInPlaceSiteWndless)
  682. return E_FAIL;
  683. // otherwise, just return our outer window.
  684. //
  685. *phwnd = m_hwnd;
  686. return (*phwnd) ? S_OK : E_UNEXPECTED;
  687. }
  688. //=--------------------------------------------------------------------------=
  689. // COleControl::ContextSensitiveHelp [IOleWindow/IOleInPlaceObject]
  690. //=--------------------------------------------------------------------------=
  691. // Determines whether context-sensitive help mode should be entered during an
  692. // in-place activation session.
  693. //
  694. // Parameters:
  695. // BOOL - [in] whether or not to enter help mode.
  696. //
  697. // Output:
  698. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED
  699. STDMETHODIMP COleControl::ContextSensitiveHelp(BOOL fEnterMode)
  700. {
  701. return E_NOTIMPL;
  702. }
  703. //=--------------------------------------------------------------------------=
  704. // COleControl::InPlaceActivate
  705. //=--------------------------------------------------------------------------=
  706. // activates the control, and depending on the verb, optionally ui activates
  707. // it as well.
  708. //
  709. // Parameters:
  710. // LONG - [in] the verb that caused us to activate
  711. //
  712. // Output:
  713. // HRESULT
  714. //
  715. // Notes:
  716. // - this is spaghetti code at it's worst. effectively, we have to
  717. // be able to handle three types of site pointers -- IOleInPlaceSIte,
  718. // IOleInPlaceSiteEx, and IOleInPlaceSiteWindowless. not terribly
  719. // pretty.
  720. //
  721. HRESULT COleControl::InPlaceActivate(LONG lVerb)
  722. {
  723. BOOL f;
  724. SIZEL sizel;
  725. IOleInPlaceSiteEx *pIPSEx = NULL;
  726. HRESULT hr;
  727. BOOL fNoRedraw = FALSE;
  728. // if we don't have a client site, then there's not much to do.
  729. if (!m_pClientSite)
  730. return S_OK;
  731. //
  732. // <mc>
  733. // This code attempts to insure that we don't give UI activation to a control that is not
  734. // enabled.
  735. // </mc>
  736. if ( m_hwnd )
  737. {
  738. HWND hWndButton;
  739. if ( !(hWndButton = ::GetWindow(m_hwnd, GW_CHILD)) || !IsWindowEnabled(hWndButton) )
  740. return OLEOBJ_S_CANNOT_DOVERB_NOW;
  741. }
  742. //
  743. // <mc>
  744. // This code catches the control creation entry to this function and calls a new virtual to insure that we
  745. // do indeed need a control window. If we don't need a control window we MUST return E_NOTIMPL from the
  746. // doverb() call which is the caller of this function. See ShouldCreateWindow() for more details.
  747. // </mc>
  748. if ( !m_hwnd )
  749. {
  750. if (! ShouldCreateWindow() )
  751. return E_NOTIMPL;
  752. }
  753. // get an InPlace site pointer.
  754. if (!GetInPlaceSite()) {
  755. // if they want windowless support, then we want IOleInPlaceSiteWindowless
  756. if (FCONTROLISWINDOWLESS(m_ObjectType))
  757. m_pClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&m_pInPlaceSiteWndless);
  758. // if we're not able to do windowless siting, then we'll just get an
  759. // IOleInPlaceSite pointer.
  760. if (!m_pInPlaceSiteWndless) {
  761. hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
  762. RETURN_ON_FAILURE(hr);
  763. }
  764. }
  765. // now, we want an IOleInPlaceSiteEx pointer for windowless and flicker free
  766. // activation. if we're windowless, we've already got it, else we need to
  767. // try and get it
  768. if (m_pInPlaceSiteWndless) {
  769. pIPSEx = (IOleInPlaceSiteEx *)m_pInPlaceSiteWndless;
  770. pIPSEx->AddRef();
  771. } else
  772. m_pClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&pIPSEx);
  773. // if we're not already active, go and do it.
  774. //
  775. if (!m_fInPlaceActive) {
  776. OLEINPLACEFRAMEINFO InPlaceFrameInfo;
  777. RECT rcPos, rcClip;
  778. // if we have a windowless site, see if we can go in-place windowless
  779. // active
  780. //
  781. hr = S_FALSE;
  782. if (m_pInPlaceSiteWndless) {
  783. hr = m_pInPlaceSiteWndless->CanWindowlessActivate();
  784. CLEANUP_ON_FAILURE(hr);
  785. // if they refused windowless, we'll try windowed
  786. //
  787. if (S_OK != hr) {
  788. RELEASE_OBJECT(m_pInPlaceSiteWndless);
  789. hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
  790. CLEANUP_ON_FAILURE(hr);
  791. }
  792. }
  793. // just try regular windowed in-place activation
  794. //
  795. if (hr != S_OK) {
  796. hr = m_pInPlaceSite->CanInPlaceActivate();
  797. if (hr != S_OK) {
  798. hr = (FAILED(hr)) ? E_FAIL : hr;
  799. goto CleanUp;
  800. }
  801. }
  802. // if we are here, then we have permission to go in-place active.
  803. // now, announce our intentions to actually go ahead and do this.
  804. //
  805. hr = (pIPSEx) ? pIPSEx->OnInPlaceActivateEx(&fNoRedraw, (m_pInPlaceSiteWndless) ? ACTIVATE_WINDOWLESS : 0)
  806. : m_pInPlaceSite->OnInPlaceActivate();
  807. CLEANUP_ON_FAILURE(hr);
  808. // if we're here, we're ready to go in-place active. we just need
  809. // to set up some flags, and then create the window [if we have
  810. // one]
  811. //
  812. m_fInPlaceActive = TRUE;
  813. // we need to get some information about our location in the parent
  814. // window, as well as some information about the parent
  815. //
  816. InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  817. hr = GetInPlaceSite()->GetWindow(&m_hwndParent);
  818. if (SUCCEEDED(hr))
  819. hr = GetInPlaceSite()->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow, &rcPos, &rcClip, &InPlaceFrameInfo);
  820. CLEANUP_ON_FAILURE(hr);
  821. // make sure we'll display ourselves in the correct location with the correct size
  822. //
  823. sizel.cx = rcPos.right - rcPos.left;
  824. sizel.cy = rcPos.bottom - rcPos.top;
  825. f = OnSetExtent(&sizel);
  826. if (f)
  827. m_Size = sizel;
  828. SetObjectRects(&rcPos, &rcClip);
  829. // finally, create our window if we have to!
  830. if (!m_pInPlaceSiteWndless) {
  831. SetInPlaceParent(m_hwndParent);
  832. // create the window, and display it. die horribly if we couldnt'
  833. //
  834. if (!CreateInPlaceWindow(rcPos.left, rcPos.top, fNoRedraw)) {
  835. hr = E_FAIL;
  836. goto CleanUp;
  837. }
  838. }
  839. }
  840. // don't need this any more
  841. //
  842. RELEASE_OBJECT(pIPSEx);
  843. // if we're not inplace visible yet, do so now.
  844. //
  845. if (!m_fInPlaceVisible)
  846. SetInPlaceVisible(TRUE);
  847. // if we weren't asked to UIActivate, then we're done.
  848. //
  849. if (lVerb != OLEIVERB_PRIMARY && lVerb != OLEIVERB_UIACTIVATE)
  850. return S_OK;
  851. // if we're not already UI active, do sow now.
  852. //
  853. if (!m_fUIActive) {
  854. m_fUIActive = TRUE;
  855. // inform the container of our intent
  856. GetInPlaceSite()->OnUIActivate();
  857. // take the focus [which is what UI Activation is all about !]
  858. DBWIN("Activate focus");
  859. SetFocus(TRUE);
  860. // set ourselves up in the host.
  861. m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  862. if (m_pInPlaceUIWindow)
  863. m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  864. // we have to explicitly say we don't wany any border space.
  865. //
  866. m_pInPlaceFrame->SetBorderSpace(NULL);
  867. if (m_pInPlaceUIWindow)
  868. m_pInPlaceUIWindow->SetBorderSpace(NULL);
  869. }
  870. // be-de-be-de-be-de that's all folks!
  871. //
  872. return S_OK;
  873. CleanUp:
  874. // something catastrophic happened [or, at least something bad].
  875. // die a horrible fiery mangled painful death.
  876. //
  877. QUICK_RELEASE(pIPSEx);
  878. m_fInPlaceActive = FALSE;
  879. return hr;
  880. }
  881. //=--------------------------------------------------------------------------=
  882. // COleControl::InPlaceDeactivate [IOleInPlaceObject]
  883. //=--------------------------------------------------------------------------=
  884. // Deactivates an active in-place object and discards the object's undo state.
  885. //
  886. // Output:
  887. // HRESULT - S_OK, E_UNEXPECTED
  888. STDMETHODIMP COleControl::InPlaceDeactivate(void)
  889. {
  890. // if we're not in-place active yet, then this is easy.
  891. if (!m_fInPlaceActive)
  892. return S_OK;
  893. // transition from UIActive back to active
  894. //
  895. if (m_fUIActive)
  896. UIDeactivate();
  897. m_fInPlaceActive = FALSE;
  898. m_fInPlaceVisible = FALSE;
  899. // if we have a window, tell it to go away.
  900. //
  901. if (m_hwnd) {
  902. ASSERT_COMMENT(!m_pInPlaceSiteWndless, "internal state really messed up");
  903. // so our window proc doesn't crash.
  904. //
  905. BeforeDestroyWindow();
  906. SetWindowLong(m_hwnd, GWLP_USERDATA, 0xFFFFFFFF);
  907. DestroyWindow(m_hwnd);
  908. m_hwnd = NULL;
  909. }
  910. RELEASE_OBJECT(m_pInPlaceFrame);
  911. RELEASE_OBJECT(m_pInPlaceUIWindow);
  912. GetInPlaceSite()->OnInPlaceDeactivate();
  913. return S_OK;
  914. }
  915. //=--------------------------------------------------------------------------=
  916. // COleControl::UIDeactivate [IOleInPlaceObject]
  917. //=--------------------------------------------------------------------------=
  918. // transitions us from UI Active to merely being active [visible] for
  919. // a control, this doesn't mean all that much.
  920. //
  921. // Output:
  922. // HRESULT - S_OK, E_UNEXPECTED
  923. STDMETHODIMP COleControl::UIDeactivate(void)
  924. {
  925. // if we're not UIActive, not much to do.
  926. //
  927. if (!m_fUIActive)
  928. return S_OK;
  929. m_fUIActive = FALSE;
  930. // notify frame windows, if appropriate, that we're no longer ui-active.
  931. //
  932. if (m_pInPlaceUIWindow) m_pInPlaceUIWindow->SetActiveObject(NULL, NULL);
  933. m_pInPlaceFrame->SetActiveObject(NULL, NULL);
  934. // we don't need to explicitly release the focus here since somebody
  935. // else grabbing the focus is what is likely to cause us to get lose it
  936. //
  937. GetInPlaceSite()->OnUIDeactivate(FALSE);
  938. return S_OK;
  939. }
  940. //=--------------------------------------------------------------------------=
  941. // COleControl::SetObjectRects [IOleInPlaceObject]
  942. //=--------------------------------------------------------------------------=
  943. // Indicates how much of the control is visible.
  944. //
  945. // Parameters:
  946. // LPCRECT - [in] position of the control.
  947. // LPCRECT - [in] clipping rectangle for the control.
  948. //
  949. // Output:
  950. // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED
  951. //
  952. // Notes:
  953. //
  954. #if 0
  955. STDMETHODIMP COleControl::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip)
  956. {
  957. BOOL fRemoveWindowRgn;
  958. // verify our information
  959. // This assertion doesn't seem valid because the container (IE 3) never
  960. // calls SetExtent().
  961. // ASSERT_COMMENT(m_Size.cx == (prcPos->right - prcPos->left) && m_Size.cy == (prcPos->bottom - prcPos->top), "Somebody called SetObjectRects without first setting the extent");
  962. /*
  963. * Move our window to the new location and handle clipping. Not
  964. * applicable for windowless controls, since the container will be
  965. * responsible for all clipping.
  966. */
  967. if (m_hwnd) {
  968. fRemoveWindowRgn = m_fUsingWindowRgn;
  969. if (prcClip) {
  970. // the container wants us to clip, so figure out if we really
  971. // need to
  972. RECT rcIXect;
  973. if (IntersectRect(&rcIXect, prcPos, prcClip)) {
  974. if (!EqualRect(&rcIXect, prcPos)) {
  975. OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
  976. SetWindowRgn(m_hwnd, CreateRectRgnIndirect(&rcIXect), TRUE);
  977. m_fUsingWindowRgn = TRUE;
  978. fRemoveWindowRgn = FALSE;
  979. }
  980. }
  981. }
  982. if (fRemoveWindowRgn) {
  983. SetWindowRgn(m_hwnd, NULL, TRUE);
  984. m_fUsingWindowRgn = FALSE;
  985. }
  986. // set our control's location and size
  987. // [people for whom zooming is important should set that up here]
  988. if (!EqualRect(prcPos, &m_rcLocation)) {
  989. m_Size.cx = (prcPos->right - prcPos->left);
  990. m_Size.cy = (prcPos->bottom - prcPos->top);
  991. SetWindowPos(m_hwnd, NULL, prcPos->left, prcPos->top, m_Size.cx, m_Size.cy, SWP_NOZORDER | SWP_NOACTIVATE);
  992. CopyRect(&m_rcLocation, prcPos);
  993. return S_OK;
  994. }
  995. }
  996. // save out our current location. windowless controls want this more
  997. // then windowed ones do, but everybody can have it just in case
  998. // BUGBUG: 20-Apr-1997 [ralphw] why do we care about this for
  999. // windowless controls
  1000. CopyRect(&m_rcLocation, prcPos);
  1001. return S_OK;
  1002. }
  1003. #endif
  1004. //=--------------------------------------------------------------------------=
  1005. // COleControl::ReactivateAndUndo [IOleInPlaceObject]
  1006. //=--------------------------------------------------------------------------=
  1007. // Reactivates a previously deactivated object, undoing the last state of the object.
  1008. //
  1009. // Output:
  1010. // HRESULT - S_OK, E_NOTUNDOABLE
  1011. STDMETHODIMP COleControl::ReactivateAndUndo(void)
  1012. {
  1013. return E_NOTIMPL;
  1014. }
  1015. //=--------------------------------------------------------------------------=
  1016. // COleControl::OnWindowMessage [IOleInPlaceObjectWindowless]
  1017. //=--------------------------------------------------------------------------=
  1018. // this method lets the container dispatch a message to a windowless OLE
  1019. // object.
  1020. //
  1021. // Parameters:
  1022. // UINT - [in] the message
  1023. // WPARAM - [in] the messages wparam
  1024. // LPARAM - [in] duh.
  1025. // LRESULT * - [out] the output value
  1026. //
  1027. // Output:
  1028. // HRESULT - S_OK
  1029. //
  1030. // Notes:
  1031. // - people should call m_pInPlaceSiteWndless->OnDefWindowMessage [control
  1032. // writers should just call OcxDefWindowProc(msg, wparam, lparam)];
  1033. //
  1034. // REVIEW: if we don't have a windowless command, this should get nuked
  1035. STDMETHODIMP COleControl::OnWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
  1036. {
  1037. // little bit of pre-processing -- we need to handle some cases here
  1038. // before passing the messages on
  1039. switch (msg) {
  1040. // make sure our UI Activation correctly matches the focus
  1041. //
  1042. case WM_KILLFOCUS:
  1043. case WM_SETFOCUS:
  1044. // give the control site focus notification
  1045. //
  1046. DBWIN("windowless focus");
  1047. if (m_fInPlaceActive && m_pControlSite)
  1048. m_pControlSite->OnFocus(msg == WM_SETFOCUS);
  1049. break;
  1050. }
  1051. // just pass it to the control's window proc.
  1052. *plResult = WindowProc(msg, wParam, lParam);
  1053. return S_OK;
  1054. }
  1055. //=--------------------------------------------------------------------------=
  1056. // COleControl::GetDropTarget [IOleInPlaceObjectWindowless]
  1057. //=--------------------------------------------------------------------------=
  1058. // this method returns a pointer to the objects IDropTarget interface. since
  1059. // they do not have a window, windowless objects cannot register an IDropTarget
  1060. // interface.
  1061. //
  1062. // Parameters:
  1063. // IDropTarget ** - [out]
  1064. //
  1065. // Output:
  1066. // HRESULT - S_OK, E_NOTIMPL
  1067. STDMETHODIMP COleControl::GetDropTarget(IDropTarget **ppDropTarget)
  1068. {
  1069. // OVERRIDE: if you want to do drag and drop and you're windowless,
  1070. // override me.
  1071. return E_NOTIMPL;
  1072. }
  1073. //=--------------------------------------------------------------------------=
  1074. // COleControl::TranslateAccelerator [IOleInPlaceActiveObject]
  1075. //=--------------------------------------------------------------------------=
  1076. // Processes menu accelerator-key messages from the container's message queue.
  1077. //
  1078. // Parameters:
  1079. // LPMSG - [in] the message that has the special key in it.
  1080. //
  1081. // Output:
  1082. // HRESULT - S_OK, S_FALSE, E_UNEXPECTED
  1083. STDMETHODIMP COleControl::TranslateAccelerator(LPMSG pmsg)
  1084. {
  1085. DBWIN("TranslateAccelerator");
  1086. // see if we want it or not.
  1087. if (OnSpecialKey(pmsg))
  1088. return S_OK;
  1089. // 30-Jul-1997 [ralphw] The docs don't talk about this, and I can't
  1090. // find anyone else who calls into controlsite.
  1091. // if not, then we want to forward it back to the site for further processing
  1092. if (m_pControlSite)
  1093. return m_pControlSite->TranslateAccelerator(pmsg, _SpecialKeyState());
  1094. // we didn't want it.
  1095. return S_FALSE;
  1096. }
  1097. //=--------------------------------------------------------------------------=
  1098. // COleControl::OnFrameWindowActivate [IOleInPlaceActiveObject]
  1099. //=--------------------------------------------------------------------------=
  1100. // Notifies the control when the container's top-level frame window is
  1101. // activated or deactivated.
  1102. //
  1103. // Parameters:
  1104. // BOOL - [in] state of containers top level window.
  1105. //
  1106. // Output:
  1107. // HRESULT - S_OK
  1108. STDMETHODIMP COleControl::OnFrameWindowActivate(BOOL fActivate)
  1109. {
  1110. // we're supposed to go UI active in this case
  1111. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  1112. }
  1113. //=--------------------------------------------------------------------------=
  1114. // COleControl::OnDocWindowActivate [IOleInPlaceActiveObject]
  1115. //=--------------------------------------------------------------------------=
  1116. // Notifies the active control when the container's document window is
  1117. // activated or deactivated.
  1118. //
  1119. // Parameters:
  1120. // BOOL - state of mdi child window.
  1121. STDMETHODIMP COleControl::OnDocWindowActivate(BOOL fActivate)
  1122. {
  1123. // we're supposed to go UI active in this case
  1124. return InPlaceActivate(OLEIVERB_UIACTIVATE);
  1125. }
  1126. //=--------------------------------------------------------------------------=
  1127. // COleControl::ResizeBorder [IOleInPlaceActiveObject]
  1128. //=--------------------------------------------------------------------------=
  1129. // Alerts the control that it needs to resize its border space.
  1130. //
  1131. // Parameters:
  1132. // LPCRECT - [in] new outer rectangle for border space
  1133. // IOleInPlaceUIWindow * - [in] the document or frame who's border has changed
  1134. // BOOL - [in] true if it was the fram window taht called.
  1135. STDMETHODIMP COleControl::ResizeBorder(LPCRECT prcBorder,
  1136. IOleInPlaceUIWindow *pInPlaceUIWindow, BOOL fFrame)
  1137. {
  1138. return S_OK;
  1139. }
  1140. //=--------------------------------------------------------------------------=
  1141. // COleControl::EnableModeless [IOleInPlaceActiveObject]
  1142. //=--------------------------------------------------------------------------=
  1143. // Enables or disables modeless dialog boxes when the container creates or
  1144. // destroys a modal dialog box.
  1145. //
  1146. // Parameters:
  1147. // BOOL - [in] enable or disable modeless dialogs.
  1148. STDMETHODIMP COleControl::EnableModeless(BOOL fEnable)
  1149. {
  1150. return S_OK;
  1151. }
  1152. //=--------------------------------------------------------------------------=
  1153. // COleControl::GetClassInfo [IProvideClassInfo]
  1154. //=--------------------------------------------------------------------------=
  1155. // returns the TypeInfo for the control's coclass.
  1156. //
  1157. // Parameters:
  1158. // ITypeInfo ** - [out]
  1159. //
  1160. STDMETHODIMP COleControl::GetClassInfo(ITypeInfo **ppTypeInfo)
  1161. {
  1162. ITypeLib *pTypeLib;
  1163. HRESULT hr;
  1164. CHECK_POINTER(ppTypeInfo);
  1165. *ppTypeInfo = NULL;
  1166. // go and get our type library.
  1167. // CONSIDER: - go to the same sorta scheme that we use for TypeInfo caching.
  1168. hr = LoadRegTypeLib(*g_pLibid, (USHORT)VERSIONOFOBJECT(m_ObjectType), 0,
  1169. LANGIDFROMLCID(g_lcidLocale), &pTypeLib);
  1170. if (FAILED(hr))
  1171. {
  1172. // Load and register our type library.
  1173. if (g_fServerHasTypeLibrary) {
  1174. char szTmp[MAX_PATH];
  1175. DWORD dwPathLen = GetModuleFileName(_Module.GetModuleInstance(), szTmp, MAX_PATH);
  1176. MAKE_WIDEPTR_FROMANSI(pwsz, szTmp);
  1177. hr = LoadTypeLib(pwsz, &pTypeLib);
  1178. RETURN_ON_FAILURE(hr);
  1179. hr = RegisterTypeLib(pTypeLib, pwsz, NULL);
  1180. if (FAILED(hr))
  1181. {
  1182. pTypeLib->Release();
  1183. return hr;
  1184. }
  1185. }
  1186. }
  1187. // got the typelib. get typeinfo for our coclass.
  1188. hr = pTypeLib->GetTypeInfoOfGuid((REFIID)CLSIDOFOBJECT(m_ObjectType), ppTypeInfo);
  1189. pTypeLib->Release();
  1190. RETURN_ON_FAILURE(hr);
  1191. return S_OK;
  1192. }
  1193. //=--------------------------------------------------------------------------=
  1194. // COleControl::ViewChange [callable]
  1195. //=--------------------------------------------------------------------------=
  1196. // called whenever the view of the object has changed.
  1197. void COleControl::ViewChanged(void)
  1198. {
  1199. // send the view change notification to anybody listening.
  1200. if (m_pViewAdviseSink) {
  1201. m_pViewAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
  1202. // if they only asked to be advised once, kill the connection
  1203. if (m_fViewAdviseOnlyOnce)
  1204. SetAdvise(DVASPECT_CONTENT, 0, NULL);
  1205. }
  1206. }
  1207. //=--------------------------------------------------------------------------=
  1208. // COleControl::SetInPlaceVisible [helper]
  1209. //=--------------------------------------------------------------------------=
  1210. // controls the visibility of the control window.
  1211. //
  1212. // Parameters:
  1213. // BOOL - TRUE shows FALSE hides.
  1214. void COleControl::SetInPlaceVisible(BOOL fShow)
  1215. {
  1216. BOOL fVisible;
  1217. m_fInPlaceVisible = fShow;
  1218. // don't do anything if we don't have a window. otherwise, set it
  1219. if (m_hwnd) {
  1220. fVisible = ((GetWindowLong(m_hwnd, GWL_STYLE) & WS_VISIBLE) != 0);
  1221. if (fVisible && !fShow)
  1222. ShowWindow(m_hwnd, SW_HIDE);
  1223. else if (!fVisible && fShow)
  1224. ShowWindow(m_hwnd, SW_SHOWNA);
  1225. }
  1226. }