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.

715 lines
17 KiB

  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // container.cpp
  4. //
  5. // This file contains the complete implementation of an ActiveX
  6. // control container. This purpose of this container is to test
  7. // a single control being hosted.
  8. //
  9. // (C) Copyright 1997 by Microsoft Corporation. All rights reserved.
  10. //
  11. //////////////////////////////////////////////////////////////////////////
  12. #include "precomp.h"
  13. #include <shlguid.h>
  14. #include "contain.h"
  15. /**
  16. * This method is the constructor for the CContainer object.
  17. */
  18. CContainer::CContainer()
  19. {
  20. m_cRefs = 1;
  21. m_hwnd = NULL;
  22. m_punk = NULL;
  23. memset(&m_rect, 0, sizeof(m_rect));
  24. }
  25. /**
  26. * This method is the destructor for the CContainer object.
  27. */
  28. CContainer::~CContainer()
  29. {
  30. if (m_punk)
  31. {
  32. m_punk->Release();
  33. m_punk=NULL;
  34. }
  35. }
  36. /**
  37. * This method is called when the caller wants an interface pointer.
  38. *
  39. * @param riid The interface being requested.
  40. * @param ppvObject The resultant object pointer.
  41. *
  42. * @return HRESULT S_OK, E_POINTER, E_NOINTERFACE
  43. */
  44. STDMETHODIMP CContainer::QueryInterface(REFIID riid, PVOID *ppvObject)
  45. {
  46. if (!ppvObject)
  47. return E_POINTER;
  48. //~ if (IsEqualIID(riid, IID_IOleClientSite))
  49. //~ *ppvObject = (IOleClientSite *)this;
  50. //~ else if (IsEqualIID(riid, IID_IOleInPlaceSite))
  51. if (IsEqualIID(riid, IID_IOleInPlaceSite))
  52. *ppvObject = (IOleInPlaceSite *)this;
  53. //~ else if (IsEqualIID(riid, IID_IOleInPlaceFrame))
  54. //~ *ppvObject = (IOleInPlaceFrame *)this;
  55. //~ else if (IsEqualIID(riid, IID_IOleInPlaceUIWindow))
  56. //~ *ppvObject = (IOleInPlaceUIWindow *)this;
  57. //~ else if (IsEqualIID(riid, IID_IOleControlSite))
  58. //~ *ppvObject = (IOleControlSite *)this;
  59. else if (IsEqualIID(riid, IID_IOleWindow))
  60. *ppvObject = (IOleWindow *)(IOleInPlaceFrame *)this;
  61. //~ else if (IsEqualIID(riid, IID_IDispatch))
  62. //~ *ppvObject = (IDispatch *)this;
  63. else if (IsEqualIID(riid, IID_IUnknown))
  64. *ppvObject = this;
  65. //~ else if (IsEqualIID(riid, IID_IOleCommandTarget))
  66. //~ *ppvObject = (IOleCommandTarget *)this;
  67. else
  68. {
  69. *ppvObject = NULL;
  70. return E_NOINTERFACE;
  71. }
  72. AddRef();
  73. return S_OK;
  74. }
  75. /**
  76. * This method increments the current object count.
  77. *
  78. * @return ULONG The new reference count.
  79. */
  80. ULONG CContainer::AddRef(void)
  81. {
  82. return ++m_cRefs;
  83. }
  84. /**
  85. * This method decrements the object count and deletes if necessary.
  86. *
  87. * @return ULONG Remaining ref count.
  88. */
  89. ULONG CContainer::Release(void)
  90. {
  91. if (--m_cRefs)
  92. return m_cRefs;
  93. delete this;
  94. return 0;
  95. }
  96. // ***********************************************************************
  97. // IOleClientSite
  98. // ***********************************************************************
  99. HRESULT CContainer::SaveObject()
  100. {
  101. return E_NOTIMPL;
  102. }
  103. HRESULT CContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER * ppMk)
  104. {
  105. return E_NOTIMPL;
  106. }
  107. HRESULT CContainer::GetContainer(LPOLECONTAINER * ppContainer)
  108. {
  109. return E_NOINTERFACE;
  110. }
  111. HRESULT CContainer::ShowObject()
  112. {
  113. return S_OK;
  114. }
  115. HRESULT CContainer::OnShowWindow(BOOL fShow)
  116. {
  117. return S_OK;
  118. }
  119. HRESULT CContainer::RequestNewObjectLayout()
  120. {
  121. return E_NOTIMPL;
  122. }
  123. // ***********************************************************************
  124. // IOleWindow
  125. // ***********************************************************************
  126. HRESULT CContainer::GetWindow(HWND * lphwnd)
  127. {
  128. if (!IsWindow(m_hwnd))
  129. return S_FALSE;
  130. *lphwnd = m_hwnd;
  131. return S_OK;
  132. }
  133. HRESULT CContainer::ContextSensitiveHelp(BOOL fEnterMode)
  134. {
  135. return E_NOTIMPL;
  136. }
  137. // ***********************************************************************
  138. // IOleInPlaceSite
  139. // ***********************************************************************
  140. HRESULT CContainer::CanInPlaceActivate(void)
  141. {
  142. return S_OK;
  143. }
  144. HRESULT CContainer::OnInPlaceActivate(void)
  145. {
  146. return S_OK;
  147. }
  148. HRESULT CContainer::OnUIActivate(void)
  149. {
  150. return S_OK;
  151. }
  152. HRESULT CContainer::GetWindowContext (IOleInPlaceFrame ** ppFrame, IOleInPlaceUIWindow ** ppIIPUIWin,
  153. LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
  154. {
  155. //~ *ppFrame = (IOleInPlaceFrame *)this;
  156. *ppFrame = NULL;
  157. *ppIIPUIWin = NULL;
  158. RECT rect;
  159. GetClientRect(m_hwnd, &rect);
  160. lprcPosRect->left = 0;
  161. lprcPosRect->top = 0;
  162. lprcPosRect->right = rect.right;
  163. lprcPosRect->bottom = rect.bottom;
  164. CopyRect(lprcClipRect, lprcPosRect);
  165. lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
  166. lpFrameInfo->fMDIApp = FALSE;
  167. lpFrameInfo->hwndFrame = m_hwnd;
  168. lpFrameInfo->haccel = 0;
  169. lpFrameInfo->cAccelEntries = 0;
  170. //~ (*ppFrame)->AddRef();
  171. return S_OK;
  172. }
  173. HRESULT CContainer::Scroll(SIZE scrollExtent)
  174. {
  175. return E_NOTIMPL;
  176. }
  177. HRESULT CContainer::OnUIDeactivate(BOOL fUndoable)
  178. {
  179. return E_NOTIMPL;
  180. }
  181. HRESULT CContainer::OnInPlaceDeactivate(void)
  182. {
  183. return S_OK;
  184. }
  185. HRESULT CContainer::DiscardUndoState(void)
  186. {
  187. return E_NOTIMPL;
  188. }
  189. HRESULT CContainer::DeactivateAndUndo(void)
  190. {
  191. return E_NOTIMPL;
  192. }
  193. HRESULT CContainer::OnPosRectChange(LPCRECT lprcPosRect)
  194. {
  195. return S_OK;
  196. }
  197. // ***********************************************************************
  198. // IOleInPlaceUIWindow
  199. // ***********************************************************************
  200. HRESULT CContainer::GetBorder(LPRECT lprectBorder)
  201. {
  202. return E_NOTIMPL;
  203. }
  204. HRESULT CContainer::RequestBorderSpace(LPCBORDERWIDTHS lpborderwidths)
  205. {
  206. return E_NOTIMPL;
  207. }
  208. HRESULT CContainer::SetBorderSpace(LPCBORDERWIDTHS lpborderwidths)
  209. {
  210. return E_NOTIMPL;
  211. }
  212. HRESULT CContainer::SetActiveObject(IOleInPlaceActiveObject * pActiveObject, LPCOLESTR lpszObjName)
  213. {
  214. return E_NOTIMPL;
  215. }
  216. // ***********************************************************************
  217. // IOleInPlaceFrame
  218. // ***********************************************************************
  219. HRESULT CContainer::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
  220. {
  221. return E_NOTIMPL;
  222. }
  223. HRESULT CContainer::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
  224. {
  225. return E_NOTIMPL;
  226. }
  227. HRESULT CContainer::RemoveMenus(HMENU hmenuShared)
  228. {
  229. return E_NOTIMPL;
  230. }
  231. HRESULT CContainer::SetStatusText(LPCOLESTR pszStatusText)
  232. {
  233. char status[MAX_PATH]; // ansi version of status text
  234. if (NULL == pszStatusText)
  235. return E_POINTER;
  236. WideCharToMultiByte(CP_ACP, 0, pszStatusText, -1, status, MAX_PATH, NULL, NULL);
  237. if (IsWindow(m_hwndStatus))
  238. SendMessage(m_hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)status);
  239. return (S_OK);
  240. }
  241. HRESULT CContainer::EnableModeless(BOOL fEnable)
  242. {
  243. return E_NOTIMPL;
  244. }
  245. HRESULT CContainer::TranslateAccelerator(LPMSG lpmsg, WORD wID)
  246. {
  247. return S_FALSE;
  248. }
  249. // ***********************************************************************
  250. // IOleControlSite
  251. // ***********************************************************************
  252. HRESULT CContainer::OnControlInfoChanged()
  253. {
  254. return E_NOTIMPL;
  255. }
  256. HRESULT CContainer::LockInPlaceActive(BOOL fLock)
  257. {
  258. return E_NOTIMPL;
  259. }
  260. HRESULT CContainer::GetExtendedControl(IDispatch **ppDisp)
  261. {
  262. if (ppDisp == NULL)
  263. return E_INVALIDARG;
  264. *ppDisp = (IDispatch *)this;
  265. (*ppDisp)->AddRef();
  266. return S_OK;
  267. }
  268. HRESULT CContainer::TransformCoords(POINTL *pptlHimetric, POINTF *pptfContainer, DWORD dwFlags)
  269. {
  270. return E_NOTIMPL;
  271. }
  272. HRESULT CContainer::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
  273. {
  274. return S_FALSE;
  275. }
  276. HRESULT CContainer::OnFocus(BOOL fGotFocus)
  277. {
  278. return E_NOTIMPL;
  279. }
  280. HRESULT CContainer::ShowPropertyFrame(void)
  281. {
  282. return E_NOTIMPL;
  283. }
  284. // ***********************************************************************
  285. // IDispatch
  286. // ***********************************************************************
  287. HRESULT CContainer::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
  288. {
  289. *rgdispid = DISPID_UNKNOWN;
  290. return DISP_E_UNKNOWNNAME;
  291. }
  292. HRESULT CContainer::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
  293. {
  294. return E_NOTIMPL;
  295. }
  296. HRESULT CContainer::GetTypeInfoCount(unsigned int FAR * pctinfo)
  297. {
  298. return E_NOTIMPL;
  299. }
  300. HRESULT CContainer::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
  301. {
  302. return DISP_E_MEMBERNOTFOUND;
  303. }
  304. // ***********************************************************************
  305. // IOleCommandTarget
  306. // ***********************************************************************
  307. HRESULT CContainer::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[ ], OLECMDTEXT *pCmdText)
  308. {
  309. HRESULT hres = OLECMDERR_E_UNKNOWNGROUP;
  310. const int SBCMDID_ADDTOFAVORITES = 8;
  311. #if 0
  312. if (pguidCmdGroup && IsEqualGUID(CGID_Explorer, *pguidCmdGroup))
  313. {
  314. for (ULONG i=0 ; i < cCmds ; i++)
  315. {
  316. switch (rgCmds[i].cmdID)
  317. {
  318. case SBCMDID_ADDTOFAVORITES:
  319. rgCmds[i].cmdf = OLECMDF_ENABLED | OLECMDF_SUPPORTED;
  320. break;
  321. default:
  322. rgCmds[i].cmdf = 0;
  323. break;
  324. }
  325. }
  326. hres = S_OK;
  327. }
  328. #endif
  329. return hres;
  330. }
  331. HRESULT CContainer::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
  332. {
  333. HRESULT hres = OLECMDERR_E_UNKNOWNGROUP;
  334. const int SBCMDID_ADDTOFAVORITES = 8;
  335. #if 0
  336. if (pguidCmdGroup && IsEqualGUID(CGID_Explorer, *pguidCmdGroup))
  337. {
  338. switch(nCmdID)
  339. {
  340. case SBCMDID_ADDTOFAVORITES:
  341. TCHAR szURL[2048];
  342. TCHAR szTitle[MAX_PATH];
  343. WideCharToMultiByte(CP_ACP, 0, pvaIn->bstrVal, -1, szURL, sizeof(szURL), NULL, NULL);
  344. WideCharToMultiByte(CP_ACP, 0, pvaOut->bstrVal, -1, szTitle, sizeof(szTitle), NULL, NULL);
  345. MessageBox(m_hwnd,
  346. szURL,
  347. szTitle,
  348. MB_OK);
  349. hres = S_OK;
  350. break;
  351. }
  352. }
  353. #endif
  354. return hres;
  355. }
  356. // ***********************************************************************
  357. // Public (non-interface) Methods
  358. // ***********************************************************************
  359. /**
  360. * This method will add an ActiveX control to the container. Note, for
  361. * now, this CContainer can only have one control.
  362. *
  363. * @param bstrClsid The CLSID or PROGID of the control.
  364. *
  365. * @return HRESULT S_OK, E_POINTER, E_NOINTERFACE
  366. */
  367. HRESULT CContainer::add(BSTR bstrClsid)
  368. {
  369. CLSID clsid; // CLSID of the control object
  370. HRESULT hr; // return code
  371. hr = CLSIDFromString(bstrClsid, &clsid);
  372. if (FAILED(hr))
  373. return hr;
  374. hr = CoCreateInstance(clsid,
  375. NULL,
  376. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
  377. IID_IUnknown,
  378. (PVOID *)&m_punk);
  379. if (FAILED(hr))
  380. return hr;
  381. ASSERT(NULL != m_punk);
  382. IOleObject *pioo;
  383. hr = m_punk->QueryInterface(IID_IOleObject, (PVOID *)&pioo);
  384. if (FAILED(hr))
  385. return hr;
  386. pioo->SetClientSite(this);
  387. pioo->Release();
  388. IPersistStreamInit *ppsi;
  389. hr = m_punk->QueryInterface(IID_IPersistStreamInit, (PVOID *)&ppsi);
  390. if (SUCCEEDED(hr))
  391. {
  392. ppsi->InitNew();
  393. ppsi->Release();
  394. }
  395. return hr;
  396. }
  397. /**
  398. * This method will remove the control from the container.
  399. *
  400. * @return No return value.
  401. */
  402. void CContainer::remove()
  403. {
  404. if (!m_punk)
  405. return;
  406. HRESULT hr;
  407. IOleObject *pioo;
  408. IOleInPlaceObject *pipo;
  409. hr = m_punk->QueryInterface(IID_IOleObject, (PVOID *)&pioo);
  410. if (SUCCEEDED(hr))
  411. {
  412. pioo->Close(OLECLOSE_NOSAVE);
  413. pioo->SetClientSite(NULL);
  414. pioo->Release();
  415. }
  416. hr = m_punk->QueryInterface(IID_IOleInPlaceObject, (PVOID *)&pipo);
  417. if (SUCCEEDED(hr))
  418. {
  419. pipo->UIDeactivate();
  420. pipo->InPlaceDeactivate();
  421. pipo->Release();
  422. }
  423. m_punk->Release();
  424. m_punk = NULL;
  425. }
  426. /**
  427. * This method sets the parent window. This is used by the container
  428. * so the control can parent itself.
  429. *
  430. * @param hwndParent The parent window handle.
  431. *
  432. * @return No return value.
  433. */
  434. void CContainer::setParent(HWND hwndParent)
  435. {
  436. m_hwnd = hwndParent;
  437. }
  438. /**
  439. * This method will set the location of the control.
  440. *
  441. * @param x The top left.
  442. * @param y The top right.
  443. * @param width The width of the control.
  444. * @param height The height of the control.
  445. */
  446. void CContainer::setLocation(int x, int y, int width, int height)
  447. {
  448. m_rect.left = x;
  449. m_rect.top = y;
  450. m_rect.right = x + width;
  451. m_rect.bottom = y + height;
  452. if (!m_punk)
  453. return;
  454. HRESULT hr;
  455. IOleInPlaceObject *pipo;
  456. hr = m_punk->QueryInterface(IID_IOleInPlaceObject, (PVOID *)&pipo);
  457. if (FAILED(hr))
  458. return;
  459. pipo->SetObjectRects(&m_rect, &m_rect);
  460. pipo->Release();
  461. }
  462. HRESULT CContainer::InPlaceActivate( void )
  463. {
  464. HRESULT hr = E_FAIL;
  465. if( m_punk )
  466. {
  467. CComQIPtr< IOleObject, &IID_IOleObject > spioo( m_punk );
  468. if( spioo != NULL )
  469. {
  470. spioo->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, m_hwnd, &m_rect);
  471. spioo->DoVerb(OLEIVERB_HIDE, NULL, this, 0, m_hwnd, &m_rect);
  472. }
  473. }
  474. return hr;
  475. }
  476. /**
  477. * Sets the visible state of the control.
  478. *
  479. * @param fVisible TRUE=visible, FALSE=hidden
  480. * @return No return value.
  481. */
  482. void CContainer::setVisible(BOOL fVisible)
  483. {
  484. if (!m_punk)
  485. return;
  486. HRESULT hr;
  487. IOleObject *pioo;
  488. hr = m_punk->QueryInterface(IID_IOleObject, (PVOID *)&pioo);
  489. if (FAILED(hr))
  490. return;
  491. if (fVisible)
  492. {
  493. pioo->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, 0, m_hwnd, &m_rect);
  494. pioo->DoVerb(OLEIVERB_SHOW, NULL, this, 0, m_hwnd, &m_rect);
  495. IOleInPlaceObject *pipo;
  496. HRESULT hr = m_punk->QueryInterface(IID_IOleInPlaceObject, (PVOID *)&pipo);
  497. if (SUCCEEDED(hr))
  498. {
  499. pipo->SetObjectRects(&m_rect, &m_rect);
  500. pipo->Release();
  501. }
  502. }
  503. else
  504. pioo->DoVerb(OLEIVERB_HIDE, NULL, this, 0, m_hwnd, NULL);
  505. pioo->Release();
  506. }
  507. /**
  508. * This sets the focus to the control (a.k.a. UIActivate)
  509. *
  510. * @param fFocus TRUE=set, FALSE=remove
  511. *
  512. * @return No return value.
  513. */
  514. void CContainer::setFocus(BOOL fFocus)
  515. {
  516. if (!m_punk)
  517. return;
  518. HRESULT hr;
  519. IOleObject *pioo;
  520. if (fFocus)
  521. {
  522. hr = m_punk->QueryInterface(IID_IOleObject, (PVOID *)&pioo);
  523. if (FAILED(hr))
  524. return;
  525. pioo->DoVerb(OLEIVERB_UIACTIVATE, NULL, this, 0, m_hwnd, &m_rect);
  526. pioo->Release();
  527. }
  528. }
  529. /**
  530. * If the container has an HWND for the status window (must be
  531. * common control), then this method is used to tell the container.
  532. *
  533. * @param hwndStatus Window handle of the status bar.
  534. *
  535. * @return No return value.
  536. */
  537. void CContainer::setStatusWindow(HWND hwndStatus)
  538. {
  539. m_hwndStatus = hwndStatus;
  540. }
  541. /**
  542. * This method gives the control the opportunity to translate and use
  543. * key strokes.
  544. *
  545. * @param msg Key message.
  546. *
  547. * @return No return value.
  548. */
  549. HRESULT CContainer::translateKey(MSG *pmsg)
  550. {
  551. if (!m_punk)
  552. return E_FAIL;
  553. HRESULT hr;
  554. IOleInPlaceActiveObject *pao;
  555. hr = m_punk->QueryInterface(IID_IOleInPlaceActiveObject, (PVOID *)&pao);
  556. if (FAILED(hr))
  557. return hr;
  558. hr = pao->TranslateAccelerator(pmsg);
  559. pao->Release();
  560. return hr;
  561. }
  562. /**
  563. * Returns the IDispatch pointer of the contained control. Note, the
  564. * caller is responsible for calling IDispatch::Release().
  565. *
  566. * @return Controls dispatch interface.
  567. */
  568. IDispatch * CContainer::getDispatch()
  569. {
  570. if (!m_punk)
  571. return NULL;
  572. HRESULT hr;
  573. IDispatch *pdisp;
  574. hr = m_punk->QueryInterface(IID_IDispatch, (PVOID *)&pdisp);
  575. return pdisp;
  576. }
  577. /**
  578. * Returns the IUnknown interface pointer for the containd control. Note,
  579. * the caller is responsible for calling IUnknown::Release().
  580. *
  581. * @return Controls unknown interface.
  582. */
  583. IUnknown * CContainer::getUnknown()
  584. {
  585. if (!m_punk)
  586. return NULL;
  587. m_punk->AddRef();
  588. return m_punk;
  589. }