container.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 17k
Category:

Windows Kernel

Development Platform:

Visual C++

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