FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
FBControl.h
1 /**********************************************************\
2 Original Author: Richard Bateman (taxilian)
3 
4 Created: Sept 17, 2009
5 License: Dual license model; choose one of two:
6 New BSD License
7 http://www.opensource.org/licenses/bsd-license.php
8 - or -
9 GNU Lesser General Public License, version 2.1
10 http://www.gnu.org/licenses/lgpl-2.1.html
11 
12 Copyright 2009 Richard Bateman, Firebreath development team
13 \**********************************************************/
14 
15 // FBControl.h : Declaration of the CFBControl
16 #pragma once
17 #ifndef H_FBCONTROL
18 #define H_FBCONTROL
19 
20 #include "win_common.h"
21 #include "win_targetver.h"
22 #include <atlctl.h>
23 #include <ShlGuid.h>
24 #include <mshtml.h>
25 #include <boost/algorithm/string.hpp>
26 #include <boost/cast.hpp>
27 #include <boost/scoped_array.hpp>
28 #include "DOM/Window.h"
29 #include "FactoryBase.h"
30 #include "logging.h"
31 #include "JSAPI_IDispatchEx.h"
32 #include "PluginInfo.h"
33 #include "ShareableReference.h"
34 
35 #include "BrowserPlugin.h"
36 #include "PluginCore.h"
37 #include "Win/WindowContextWin.h"
38 #ifdef FBWIN_ASYNCSURFACE
39 #include "ActiveXAsyncDrawService.h"
40 #endif
41 
42 #include "registrymap.hpp"
43 
44 extern std::string g_dllPath;
45 
46 // CFBControl
47 namespace FB {
48  namespace ActiveX {
49  class ActiveXBrowserHost;
50  typedef boost::shared_ptr<ActiveXBrowserHost> ActiveXBrowserHostPtr;
51  void flagStaticInitialized(bool init = true);
52  bool isStaticInitialized();
53 
54  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
55  class ATL_NO_VTABLE CFBControl :
56  public CComObjectRootEx<CComMultiThreadModel>,
57  public CComCoClass<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid>, pFbCLSID >,
58  public CComControl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
59 
60  public JSAPI_IDispatchEx< CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid>, ICurObjInterface, piid>,
61 
62  // Required for standard events
63  public IProvideClassInfo2Impl<pFbCLSID, NULL, plibid>,
64  public IObjectSafety,
65 
66  //public IPersistStreamInitImpl<CFBControl<pFbCLSID,pMT> >,
67  public IOleControlImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
68  public IOleObjectImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
69  public IOleInPlaceActiveObjectImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
70  public IQuickActivateImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
71  public IViewObjectExImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
72  public IOleInPlaceObjectWindowlessImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
73 
74  public IObjectWithSiteImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >,
75 
76  // Provides methods for getting <params>
77  public IPersistPropertyBag,
78 #ifdef FBWIN_ASYNCSURFACE
79  public IViewObjectPresentNotify,
80 #endif
81  public FB::BrowserPlugin
82  {
83  public:
84  typedef CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> CFBControlX;
85 
86  protected:
87  boost::scoped_ptr<FB::PluginWindow> pluginWin;
88  CComQIPtr<IServiceProvider> m_serviceProvider;
89  CComQIPtr<IWebBrowser2> m_webBrowser;
90  const std::string m_mimetype;
91 
92  DWORD m_dwCurrentSafety;
93 
94  ActiveXBrowserHostPtr m_host;
95  bool m_setReadyDone;
96 #ifdef FBWIN_ASYNCSURFACE
97  CComPtr<IViewObjectPresentSite> m_viewObjectPresentSite;
98 #endif
99 
100  protected:
101 
102  public:
103  // The methods in this class are positioned in this file in the
104  // rough order that they will be called in.
105  CFBControl() : JSAPI_IDispatchEx<CFBControlX, ICurObjInterface, piid>(pMT), FB::BrowserPlugin(pMT),
106  m_mimetype(pMT),
107  m_setReadyDone(false)
108  {
109  setFSPath(g_dllPath);
110  }
111 
112  ~CFBControl()
113  {
114  }
115 
116  virtual FB::VariantMap getProperties(const CComQIPtr<IPropertyBag2>& pBag);
117 
118  virtual void setReady();
119  virtual void setWindow(HWND);
120  virtual void clientSiteSet();
121  virtual DWORD getSupportedObjectSafety();
122 
123  STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions,
124  DWORD *pdwEnabledOptions);
125 
126  STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask,
127  DWORD dwEnabledOptions);
128 
129  // Note that the window has not been created yet; this is where we get
130  // access to the DOM Document and Window
131  STDMETHOD(SetClientSite)(IOleClientSite *pClientSite);
132 
133  // This method will only be called if we are instantiated without a window
134  STDMETHOD(SetSite)(IUnknown *pUnkSite);
135 
136  STDMETHOD(SetObjectRects)(LPCRECT prcPos, LPCRECT prcClip);
137  STDMETHOD(InPlaceActivate)(LONG iVerb, const RECT* prcPosRect);
138 
139  // Called when the control is deactivated when it's time to shut down
140  STDMETHOD(InPlaceDeactivate)(void);
141 
142  STDMETHOD(Close)(DWORD dwSaveOption) {
143  shutdown();
144  return IOleObjectImpl<CFBControlX>::Close(dwSaveOption);
145  }
146 
147  /* IViewObjectPresentNotify calls */
148  STDMETHOD(OnPreRender)(void) {
149  return S_OK;
150  }
151 
152  /* IPersistPropertyBag calls */
153  // This will be called once when the browser initializes the property bag (PARAM tags)
154  // Often (always?) this is only called if there are no items in the property bag
155  STDMETHOD(InitNew)();
156 
157  // When this is called, we load any <param> tag values there are
158  STDMETHOD(Load)(IPropertyBag *pPropBag, IErrorLog *pErrorLog);
159 
160  // This is called on shutdown
161  void shutdown();
162 
163  // This is part of the event system
164  STDMETHOD(GetClassID)(CLSID *pClassID);
165 
166  // This is a required method for implementing IPersistPropertyBag, but it shouldn't
167  // ever get called
168  STDMETHOD(Save)(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
169 
170  virtual HRESULT OnDraw(ATL_DRAWINFO& di);
171 
172  void invalidateWindow( uint32_t left, uint32_t top, uint32_t right, uint32_t bottom );
173  public:
174  DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
175  OLEMISC_CANTLINKINSIDE |
176  OLEMISC_INSIDEOUT |
177  OLEMISC_ACTIVATEWHENVISIBLE |
178  OLEMISC_SETCLIENTSITEFIRST
179  )
180 
181  DECLARE_REGISTRY_RESOURCEID_EX(IDR_FBCONTROL)
182 
183  BEGIN_REGMAP(CFBControlX)
184  REGMAP_UUID("LIBID", (*plibid))
185  //REGMAP_ENTRY("THREADING", "Free")
186  REGMAP_ENTRY("THREADING", "Apartment")
187  //REGMAP_ENTRY("THREADING", "Single")
188  END_REGMAP()
189 
190  DECLARE_NOT_AGGREGATABLE(CFBControlX)
191 
192  BEGIN_COM_MAP(CFBControlX)
193  COM_INTERFACE_ENTRY_IID((*piid), ICurObjInterface)
194  COM_INTERFACE_ENTRY(IDispatch)
195  COM_INTERFACE_ENTRY(IDispatchEx)
196  COM_INTERFACE_ENTRY(IFireBreathObject)
197  COM_INTERFACE_ENTRY(IViewObjectEx)
198  COM_INTERFACE_ENTRY(IViewObject2)
199  COM_INTERFACE_ENTRY(IViewObject)
200  COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
201  COM_INTERFACE_ENTRY(IOleInPlaceObject)
202  COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
203  COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
204  COM_INTERFACE_ENTRY(IOleControl)
205  COM_INTERFACE_ENTRY(IOleObject)
206  COM_INTERFACE_ENTRY(IConnectionPointContainer)
207  COM_INTERFACE_ENTRY(IConnectionPoint)
208  COM_INTERFACE_ENTRY(IQuickActivate)
209  COM_INTERFACE_ENTRY(IObjectWithSite)
210  COM_INTERFACE_ENTRY(IObjectSafety)
211 
212  COM_INTERFACE_ENTRY(IPersistPropertyBag)
213  COM_INTERFACE_ENTRY(IProvideClassInfo)
214  COM_INTERFACE_ENTRY(IProvideClassInfo2)
215  END_COM_MAP()
216 
217  BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult,
218  DWORD dwMsgMapID = 0);
219 
220  // IViewObjectEx
221  DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
222 
223  // IFBControl
224  DECLARE_PROTECT_FINAL_CONSTRUCT()
225 
226  HRESULT FinalConstruct()
227  {
228  return S_OK;
229  }
230 
231  void FinalRelease()
232  {
233  }
234  };
235 
236  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
237  HRESULT FB::ActiveX::CFBControl<pFbCLSID, pMT, ICurObjInterface, piid, plibid>::OnDraw( ATL_DRAWINFO& di )
238  {
239  if (pluginWin && m_bWndLess && FB::pluginGuiEnabled()) {
240  LRESULT lRes(0);
241  PluginWindowlessWin* win = static_cast<PluginWindowlessWin*>(pluginWin.get());
242  FB::Rect bounds = { di.prcBounds->top, di.prcBounds->left, di.prcBounds->bottom, di.prcBounds->right };
243  win->HandleDraw(di.hdcDraw, bounds);
244  }
245  return S_OK;
246  }
247 
248  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
249  void FB::ActiveX::CFBControl<pFbCLSID, pMT, ICurObjInterface, piid, plibid>::invalidateWindow( uint32_t left, uint32_t top, uint32_t right, uint32_t bottom )
250  {
251  if (!m_host->isMainThread() && m_spInPlaceSite) {
252  boost::shared_ptr<FB::ShareableReference<CFBControlX> > ref(boost::make_shared<FB::ShareableReference<CFBControlX> >(this));
253  m_host->ScheduleOnMainThread(ref, boost::bind(&CFBControlX::invalidateWindow, this, left, top, right, bottom));
254  } else {
255  if (m_spInPlaceSite){
256  if(pluginWin){
257  FB::Rect pos = pluginWin->getWindowPosition();
258  RECT r = { left+pos.left, top+pos.top, right+pos.left, bottom+pos.top };
259  m_spInPlaceSite->InvalidateRect(&r, FALSE);
260  }else {
261  m_spInPlaceSite->InvalidateRect(NULL, FALSE);
262  }
263  }
264  }
265  }
266 
267  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
268  DWORD FB::ActiveX::CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::getSupportedObjectSafety()
269  {
270  return INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA/* | INTERFACE_USES_DISPEX*/;
271  }
272 
273 
274  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
275  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::SetSite(IUnknown *pUnkSite)
276  {
277  HRESULT hr = IObjectWithSiteImpl<CFBControl<pFbCLSID,pMT,ICurObjInterface,piid,plibid> >::SetSite(pUnkSite);
278  if (!pUnkSite || !pluginMain) {
279  shutdown();
280  return hr;
281  }
282  m_serviceProvider = pUnkSite;
283  if (!m_serviceProvider)
284  return E_FAIL;
285  m_serviceProvider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void**>(&m_webBrowser));
286  m_serviceProvider.Release();
287 
288  if (m_webBrowser) {
289  m_propNotify = m_spClientSite;
290  }
291 
292  // There will be no window this time!
293  clientSiteSet();
294  pluginMain->setScriptingOnly(true);
295  setReady();
296  return S_OK;
297  }
298 
299  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
300  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::SetClientSite( IOleClientSite *pClientSite )
301  {
302  HRESULT hr = IOleObjectImpl<CFBControlX>::SetClientSite (pClientSite);
303  if (!pClientSite || !pluginMain) {
304  shutdown();
305  return hr;
306  }
307 #ifdef FBWIN_ASYNCSURFACE
308  pClientSite->QueryInterface(__uuidof(IViewObjectPresentSite), (void **) &m_viewObjectPresentSite);
309 #endif
310  m_serviceProvider = pClientSite;
311  if (!m_serviceProvider)
312  return E_FAIL;
313  m_serviceProvider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void**>(&m_webBrowser));
314  m_serviceProvider.Release();
315 
316  if (m_webBrowser) {
317  m_propNotify = m_spClientSite;
318  }
319 
320  clientSiteSet();
321  return S_OK;
322  }
323 
324  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
325  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip)
326  {
327  HRESULT hr = IOleInPlaceObjectWindowlessImpl<CFBControlX>::SetObjectRects(prcPos, prcClip);
328 
329  if (m_bWndLess && pluginWin) {
330  FB::PluginWindowlessWin* ptr(static_cast<FB::PluginWindowlessWin*>(pluginWin.get()));
331  ptr->setWindowClipping(prcClip->top, prcClip->left, prcClip->bottom, prcClip->right);
332  ptr->setWindowPosition(prcPos->left, prcPos->top, prcPos->right-prcPos->left, prcPos->bottom-prcPos->top);
333  }
334  return hr;
335  }
336 
337  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
338  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::InPlaceActivate( LONG iVerb, const RECT* prcPosRect)
339  {
340  m_bWindowOnly = (FB::pluginGuiEnabled() && !pluginMain->isWindowless());
341  HRESULT hr = CComControl<CFBControlX>::InPlaceActivate(iVerb, prcPosRect);
342 
343  if (m_host)
344  m_host->resume(m_webBrowser, m_spClientSite);
345 
346  if (hr != S_OK)
347  return hr;
348 
349  if (pluginWin || !FB::pluginGuiEnabled() || !pluginMain) {
350  // window already created or gui disabled
351  return hr;
352  }
353 
354 #ifdef FBWIN_ASYNCSURFACE
355  std::string param = pluginMain->negotiateDrawingModel();
356  {
357  using namespace boost::algorithm;
358  std::vector<std::string> prefs;
359  split(prefs, param, !is_alnum());
360 
361  bool gotone = false;
362  for (size_t i = 0; !gotone && i < prefs.size(); i++) {
363  if (0 == strcmp(prefs[i].c_str(), "AsyncWindowsDXGISurface") &&
364  m_viewObjectPresentSite &&
365  m_host)
366  {
367  BOOL accelEnabled = FALSE;
368  HRESULT hr = m_viewObjectPresentSite->IsHardwareComposition(&accelEnabled);
369  if (SUCCEEDED(hr) && accelEnabled) {
370  hr = m_viewObjectPresentSite->SetCompositionMode(VIEW_OBJECT_COMPOSITION_MODE_SURFACEPRESENTER);
371  if (SUCCEEDED(hr)) {
372  AsyncDrawServicePtr asd = boost::make_shared<ActiveXAsyncDrawService>(m_host, m_viewObjectPresentSite);
373  boost::scoped_ptr<PluginWindow> pw(getFactoryInstance()->createPluginWindowless(FB::WindowContextWindowless(NULL, asd)));
374  pluginWin.swap(pw);
375  gotone = true;
376  }
377  }
378  }
379  }
380  }
381 #endif
382 
383  if (!pluginWin) {
384  PluginWindow* pw = 0;
385  if (m_bWndLess) {
387  pw = pww = getFactoryInstance()->createPluginWindowless(FB::WindowContextWindowless(NULL));
388  pww->setInvalidateWindowFunc(boost::bind(&CFBControlX::invalidateWindow, this, _1, _2, _3, _4));
389  if (m_spInPlaceSite) {
390  HWND hwnd = 0;
391  HRESULT hr = m_spInPlaceSite->GetWindow(&hwnd);
392  if (SUCCEEDED(hr)) {
393  pww->setHWND(hwnd);
394  }
395  }
396  } else {
397  PluginWindowWin* pww;
398  pw = pww = getFactoryInstance()->createPluginWindowWin(FB::WindowContextWin(m_hWnd));
399  pww->setCallOldWinProc(true);
400  }
401  pluginWin.swap(boost::scoped_ptr<PluginWindow>(pw));
402  }
403  pluginMain->SetWindow(pluginWin.get());
404  setReady();
405  return hr;
406  }
407 
408  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
409  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::InPlaceDeactivate( void )
410  {
411  if (pluginMain) {
412  pluginMain->ClearWindow();
413  pluginWin.reset();
414  }
415  // We have to release all event handlers and other held objects at this point, because
416  // if we don't the plugin won't shut down properly; normally it isn't an issue to do
417  // so, but note that this gets called if you move the plugin around in the DOM!
418  if (m_host) {
419  m_host->ReleaseAllHeldObjects();
420  m_connPtMap.clear();
421  m_host->suspend();
422  }
423  HRESULT hr = IOleInPlaceObjectWindowlessImpl<CFBControlX>::InPlaceDeactivate();
424  return hr;
425  }
426 
427  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
428  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::InitNew()
429  {
430  pluginMain->setParams(FB::VariantMap());
431  setReady();
432  return S_OK;
433  }
434 
435  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
436  FB::VariantMap CFBControl<pFbCLSID, pMT, ICurObjInterface, piid, plibid>::getProperties( const CComQIPtr<IPropertyBag2>& pBag )
437  {
438  ULONG pCount(0), pGot(0);
439  HRESULT hr = pBag->CountProperties(&pCount);
440  FB::VariantMap paramMap;
441  boost::scoped_array<PROPBAG2> pArr(new PROPBAG2[pCount]);
442  hr = pBag->GetPropertyInfo(0, pCount, pArr.get(), &pGot);
443 
444  boost::scoped_array<HRESULT> results(new HRESULT[pCount]);
445  boost::scoped_array<CComVariant> vals(new CComVariant[pCount]);
446  hr = pBag->Read(pGot, pArr.get(), NULL, vals.get(), results.get());
447  if (SUCCEEDED(hr)) {
448  for(ULONG i = 0; i < pGot; ++i) {
449  HRESULT curRes = results[i];
450  if (SUCCEEDED(curRes)) {
451  PROPBAG2* curInfo = &pArr[i];
452  VARIANT* curVal = &vals[i];
453  std::string name(FB::wstring_to_utf8(curInfo->pstrName));
454  FB::variant varval(m_host->getVariant(curVal));
455  paramMap[name] = varval;
456 
457  // Clean up
458  CoTaskMemFree(curInfo->pstrName);
459  }
460  }
461  }
462  return paramMap;
463  }
464 
465  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
466  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::Load( IPropertyBag *pPropBag, IErrorLog *pErrorLog )
467  {
468  pluginMain->setParams(getProperties(CComQIPtr<IPropertyBag2>(pPropBag)));
469  setReady();
470  return S_OK;
471  }
472 
473  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
474  void CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::clientSiteSet()
475  {
476  m_host = ActiveXBrowserHostPtr(new ActiveXBrowserHost(m_webBrowser, m_spClientSite));
477  pluginMain->SetHost(FB::ptr_cast<FB::BrowserHost>(m_host));
478  }
479 
480  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
481  void CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::setReady()
482  {
483  // This is when we can consider the plugin "ready".
484  // setReady is called at object activation, which can happen multiple times
485  // (eg: if the object is reparented in the dom); only act on the first one.
486  if (!m_setReadyDone) {
487  m_setReadyDone = true;
488  this->setAPI(pluginMain->getRootJSAPI(), m_host);
489  setReadyState(READYSTATE_COMPLETE);
490  pluginMain->setReady();
491  }
492  }
493 
494  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
495  void CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::setWindow( HWND hWnd )
496  {
497  }
498 
499  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
500  void CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::shutdown()
501  {
502  // the host must be shut down before the rest to prevent deadlocks on async calls
503  if (m_host)
504  m_host->shutdown();
505 
506  if (pluginMain) {
507  pluginMain->ClearWindow(); //Already done during InPlaceDeactivate
508  pluginMain->shutdown();
509  }
510 
511  if (pluginWin) {
512  pluginWin.reset();
513  }
514 
515  m_api.reset(); // Once we release this, pluginMain releasing should free it
516  pluginMain.reset(); // This should delete the plugin object
517  m_propNotify.Release();
518  m_webBrowser.Release();
519  m_serviceProvider.Release();
520  m_connPtMap.clear();
521  m_host.reset();
522  }
523 
524  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
525  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::GetClassID( CLSID *pClassID )
526  {
527  if (pClassID == NULL)
528  return E_POINTER;
529  *pClassID = GetObjectCLSID();
530  return S_OK;
531  }
532 
533  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
534  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::Save( IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties )
535  {
536  return S_OK;
537  }
538 
539  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
540  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
541  {
542  if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
543  return E_POINTER;
544 
545  HRESULT hr;
546  CComPtr<IUnknown> pUnk;
547  // Check if we support this interface
548  hr = GetUnknown()->QueryInterface(riid, (void**)&pUnk);
549  if (SUCCEEDED(hr)) {
550  *pdwSupportedOptions = getSupportedObjectSafety();
551  *pdwEnabledOptions = m_dwCurrentSafety;
552  } else {
553  // We don't support this interface
554  *pdwSupportedOptions = 0;
555  *pdwEnabledOptions = 0;
556  }
557  return hr;
558  }
559 
560  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
561  STDMETHODIMP CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
562  {
563  CComPtr<IUnknown> pUnk;
564  // Check if we support the interface and return E_NOINTEFACE if we don't
565  if (FAILED(GetUnknown()->QueryInterface(riid, (void**)&pUnk)))
566  return E_NOINTERFACE;
567 
568  // If we are asked to set options we don't support then fail
569  if (dwOptionSetMask & ~getSupportedObjectSafety())
570  return E_FAIL;
571 
572  m_dwCurrentSafety = (m_dwCurrentSafety & ~dwOptionSetMask) | (dwOptionSetMask & dwEnabledOptions);
573  return S_OK;
574  }
575 
576  template <const GUID* pFbCLSID, const char* pMT, class ICurObjInterface, const IID* piid, const GUID* plibid>
577  BOOL CFBControl<pFbCLSID, pMT,ICurObjInterface,piid,plibid>::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID)
578  {
579  BOOL bHandled = FALSE;
580  switch(dwMsgMapID)
581  {
582  case 0: {
583  // Set Focus & Capture whenever a button is pushed inside of the plugin instance.
584  switch(uMsg)
585  {
586  case WM_LBUTTONDOWN:
587  case WM_MBUTTONDOWN:
588  case WM_RBUTTONDOWN:
589  if (m_bNegotiatedWnd && m_bWndLess && m_spInPlaceSite) {
590  m_spInPlaceSite->SetFocus(true);
591  m_spInPlaceSite->SetCapture(true);
592  }
593  break;
594  case WM_LBUTTONUP:
595  case WM_MBUTTONUP:
596  case WM_RBUTTONUP:
597  if (m_bNegotiatedWnd && m_bWndLess && m_spInPlaceSite) {
598  m_spInPlaceSite->SetCapture(false);
599  }
600  break;
601  case WM_MOUSEACTIVATE:
602  break;
603  //lResult = ::DefWindowProc(hWnd, uMsg, wParam, lParam);
604  //return TRUE;
605  }
606 
607  if (bHandled)
608  return TRUE;
609  else if (m_bWndLess && pluginWin && static_cast<PluginWindowlessWin*>(pluginWin.get())->HandleEvent(uMsg, wParam, lParam, lResult))
610  return TRUE;
611  else if(CComControl<CFBControlX>::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult))
612  return TRUE;
613  else if(DefaultReflectionHandler(hWnd, uMsg, wParam, lParam, lResult))
614  return TRUE;
615  } break;
616 
617  }
618  return FALSE;
619  }
620 
621  }
622 }
623 
624 #endif
625 
Accepts any datatype, used in all interactions with javascript. Provides tools for getting back out t...
Definition: variant.h:198
Windows specific implementation of PluginWindow.
std::string wstring_to_utf8(const std::wstring &src)
Accepts a std::wstring and returns a UTF8-encoded std::string.
Definition: utf8_tools.cpp:37
Browser-specific plugin base class.
Definition: BrowserPlugin.h:38
std::map< std::string, variant > VariantMap
Defines an alias representing a string -> variant map.
Definition: APITypes.h:72