|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-9 by Raw Material Software Ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the GNU General
- Public License (Version 2), as published by the Free Software Foundation.
- A copy of the license is included in the JUCE distribution, or can be found
- online at www.gnu.org/licenses.
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.rawmaterialsoftware.com/juce for more information.
-
- ==============================================================================
- */
-
- //==============================================================================
- /*
- This file contains all the gubbins to create an ActiveX browser plugin that
- wraps your BrowserPluginComponent object.
-
- */
- //==============================================================================
- #if _MSC_VER
-
- //==============================================================================
- #include <windows.h>
- #include <windowsx.h>
- #include <olectl.h>
- #include <objsafe.h>
- #include <exdisp.h>
- #pragma warning (disable:4584)
-
- #include "../../../juce_amalgamated.h"
- #include "juce_BrowserPluginComponent.h"
- #include "juce_IncludeBrowserPluginInfo.h"
-
- #ifndef JuceBrowserPlugin_ActiveXCLSID
- #error "For an activeX plugin, you need to define JuceBrowserPlugin_ActiveXCLSID in your BrowserPluginCharacteristics.h file!"
- #endif
-
- //==============================================================================
- #if JUCE_DEBUG
- static int numDOWID = 0, numJuceSO = 0;
- #endif
-
- #define log(a) DBG(a)
-
- // Cunning trick used to add functions to export list without messing about with .def files.
- #define EXPORTED_FUNCTION comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
-
- //==============================================================================
- static void juceVarToVariant (const var& v, VARIANT& dest);
- static const var variantTojuceVar (const VARIANT& v);
-
- //==============================================================================
- // Takes care of the logic in invoking var methods from IDispatch callbacks.
- class IDispatchHelper
- {
- public:
- IDispatchHelper() {}
- ~IDispatchHelper() {}
-
- var::identifier getId (const int hash) const
- {
- for (int i = knownIdentifiers.size(); --i >= 0;)
- if (knownIdentifiers.getUnchecked(i)->hashCode == hash)
- return *knownIdentifiers.getUnchecked(i);
-
- return var::identifier (String::empty);
- }
-
- var::identifier getId (const String& name)
- {
- for (int i = knownIdentifiers.size(); --i >= 0;)
- if (knownIdentifiers.getUnchecked(i)->name == name)
- return *knownIdentifiers.getUnchecked(i);
-
- const var::identifier v (name);
- knownIdentifiers.add (new var::identifier (v));
- return v;
- }
-
- HRESULT doGetIDsOfNames (LPOLESTR* rgszNames, UINT cNames, DISPID* rgDispId)
- {
- for (unsigned int i = 0; i < cNames; ++i)
- {
- var::identifier id (getId (rgszNames[i]));
- rgDispId[i] = (DISPID) id.hashCode;
- }
-
- return S_OK;
- }
-
- HRESULT doInvoke (const var& v,
- DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
- VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
- {
- const var::identifier memberId (getId ((int) dispIdMember));
-
- if (memberId.name.isEmpty() || v.getObject() == 0)
- return DISP_E_MEMBERNOTFOUND;
-
- if ((wFlags & DISPATCH_METHOD) != 0)
- {
- if (! v.getObject()->hasMethod (memberId))
- return DISP_E_MEMBERNOTFOUND;
-
- const int numArgs = pDispParams == 0 ? 0 : pDispParams->cArgs;
- var result;
-
- if (numArgs == 0)
- {
- result = v.call (memberId);
- }
- else
- {
- HeapBlock <var> args;
- args.calloc (numArgs);
-
- for (int j = 0; j < numArgs; ++j)
- args[(numArgs - 1) - j] = variantTojuceVar (pDispParams->rgvarg[j]);
-
- result = v.invoke (memberId, args, numArgs);
-
- for (int j = 0; j < numArgs; ++j)
- args[j] = var();
- }
-
- if (pVarResult != 0)
- juceVarToVariant (result, *pVarResult);
-
- return S_OK;
- }
- else if ((wFlags & DISPATCH_PROPERTYGET) != 0)
- {
- if (! v.getObject()->hasProperty (memberId))
- return DISP_E_MEMBERNOTFOUND;
-
- if (pVarResult != 0)
- {
- juceVarToVariant (v.getObject()->getProperty (memberId), *pVarResult);
- return S_OK;
- }
- }
- else if ((wFlags & DISPATCH_PROPERTYPUT) != 0)
- {
- if (pDispParams != 0 && pDispParams->cArgs > 0)
- {
- v.getObject()->setProperty (memberId, variantTojuceVar (pDispParams->rgvarg[0]));
- return S_OK;
- }
- }
-
- return DISP_E_MEMBERNOTFOUND;
- }
-
- private:
- OwnedArray <var::identifier> knownIdentifiers;
-
- IDispatchHelper (const IDispatchHelper&);
- const IDispatchHelper& operator= (const IDispatchHelper&);
- };
-
- //==============================================================================
- // Makes a var look like an IDispatch
- class IDispatchWrappingDynamicObject : public IDispatch
- {
- public:
- IDispatchWrappingDynamicObject (const var& object_)
- : object (object_),
- refCount (0)
- {
- DBG ("num Juce wrapper objs: " + String (++numJuceSO));
- }
-
- virtual ~IDispatchWrappingDynamicObject()
- {
- DBG ("num Juce wrapper objs: " + String (--numJuceSO));
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
- else if (id == IID_IDispatch) { AddRef(); *result = (IDispatch*) this; return S_OK; }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetTypeInfoCount (UINT*) { return E_NOTIMPL; }
- HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
-
- HRESULT __stdcall GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames,
- LCID lcid, DISPID* rgDispId)
- {
- return iDispatchHelper.doGetIDsOfNames (rgszNames, cNames, rgDispId);
- }
-
- HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
- DISPPARAMS* pDispParams, VARIANT* pVarResult,
- EXCEPINFO* pExcepInfo, UINT* puArgErr)
- {
- return iDispatchHelper.doInvoke (object, dispIdMember, riid, lcid, wFlags, pDispParams,
- pVarResult, pExcepInfo, puArgErr);
- }
-
- private:
- //==============================================================================
- var object;
- int refCount;
- IDispatchHelper iDispatchHelper;
- };
-
-
- //==============================================================================
- // Makes an IDispatch look like a var
- class DynamicObjectWrappingIDispatch : public DynamicObject
- {
- IDispatch* const source;
-
- public:
- DynamicObjectWrappingIDispatch (IDispatch* const source_)
- : source (source_)
- {
- source->AddRef();
- log ("num IDispatch wrapper objs: " + String (++numDOWID));
- }
-
- ~DynamicObjectWrappingIDispatch()
- {
- source->Release();
- log ("num IDispatch wrapper objs: " + String (--numDOWID));
- }
-
- const var getProperty (const var::identifier& propertyName) const
- {
- LPCOLESTR name = (LPCOLESTR) propertyName.name;
- DISPID id = 0;
- if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK)
- {
- EXCEPINFO excepInfo;
- DISPPARAMS params;
- zerostruct (params);
- UINT argError;
- VARIANT result;
- zerostruct (result);
-
- if (source->Invoke (id, IID_NULL, 0, DISPATCH_PROPERTYGET,
- ¶ms, &result, &excepInfo, &argError) == S_OK)
- {
- var v (variantTojuceVar (result));
- VariantClear (&result);
- return v;
- }
- }
-
- return var();
- }
-
- bool hasProperty (const var::identifier& propertyName) const
- {
- LPCOLESTR name = (LPCOLESTR) propertyName.name;
- DISPID id = 0;
- return source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK;
- }
-
- void setProperty (const var::identifier& propertyName, const var& newValue)
- {
- LPCOLESTR name = (LPCOLESTR) propertyName.name;
- DISPID id = 0;
- if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK)
- {
- VARIANT param;
- zerostruct (param);
- juceVarToVariant (newValue, param);
-
- DISPPARAMS dispParams;
- zerostruct (dispParams);
- dispParams.cArgs = 1;
- dispParams.rgvarg = ¶m;
- EXCEPINFO excepInfo;
- zerostruct (excepInfo);
-
- VARIANT result;
- zerostruct (result);
- UINT argError = 0;
-
- if (source->Invoke (id, IID_NULL, 0, DISPATCH_PROPERTYPUT,
- &dispParams, &result, &excepInfo, &argError) == S_OK)
- {
- VariantClear (&result);
- }
-
- VariantClear (¶m);
- }
- }
-
- void removeProperty (const var::identifier& propertyName)
- {
- setProperty (propertyName, var());
- }
-
- bool hasMethod (const var::identifier& methodName) const
- {
- LPCOLESTR name = (LPCOLESTR) methodName.name;
- DISPID id = 0;
- return source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK;
- }
-
- const var invokeMethod (const var::identifier& methodName,
- const var* parameters,
- int numParameters)
- {
- var returnValue;
- LPCOLESTR name = (LPCOLESTR) methodName.name;
- DISPID id = 0;
- if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK)
- {
- HeapBlock <VARIANT> params;
- params.calloc (numParameters + 1);
-
- for (int i = 0; i < numParameters; ++i)
- juceVarToVariant (parameters[(numParameters - 1) - i], params[i]);
-
- DISPPARAMS dispParams;
- zerostruct (dispParams);
- dispParams.cArgs = numParameters;
- dispParams.rgvarg = params;
-
- EXCEPINFO excepInfo;
- zerostruct (excepInfo);
-
- VARIANT result;
- zerostruct (result);
- UINT argError = 0;
-
- if (source->Invoke (id, IID_NULL, 0, DISPATCH_METHOD,
- &dispParams, &result, &excepInfo, &argError) == S_OK)
- {
- returnValue = variantTojuceVar (result);
- VariantClear (&result);
- }
- }
-
- return returnValue;
- }
- };
-
-
- //==============================================================================
- void juceVarToVariant (const var& v, VARIANT& dest)
- {
- if (v.isVoid())
- {
- dest.vt = VT_EMPTY;
- }
- else if (v.isInt())
- {
- dest.vt = VT_INT;
- dest.intVal = (int) v;
- }
- else if (v.isBool())
- {
- dest.vt = VT_BOOL;
- dest.boolVal = (int) v;
- }
- else if (v.isDouble())
- {
- dest.vt = VT_R8;
- dest.dblVal = (double) v;
- }
- else if (v.isString())
- {
- dest.vt = VT_BSTR;
- dest.bstrVal = SysAllocString (v.toString());
- }
- else if (v.isObject())
- {
- dest.vt = VT_DISPATCH;
- dest.pdispVal = new IDispatchWrappingDynamicObject (v);
- }
- else if (v.isMethod())
- {
- dest.vt = VT_EMPTY;
- }
- }
-
- const var variantTojuceVar (const VARIANT& v)
- {
- if ((v.vt & VT_ARRAY) != 0)
- {
- //xxx
- }
- else
- {
- switch (v.vt & ~VT_BYREF)
- {
- case VT_VOID:
- case VT_EMPTY: return var();
- case VT_I1: return var ((int) v.cVal);
- case VT_I2: return var ((int) v.iVal);
- case VT_I4: return var ((int) v.lVal);
- case VT_I8: return var (String (v.llVal));
- case VT_UI1: return var ((int) v.bVal);
- case VT_UI2: return var ((int) v.uiVal);
- case VT_UI4: return var ((int) v.ulVal);
- case VT_UI8: return var (String (v.ullVal));
- case VT_INT: return var ((int) v.intVal);
- case VT_UINT: return var ((int) v.uintVal);
- case VT_R4: return var ((double) v.fltVal);
- case VT_R8: return var ((double) v.dblVal);
- case VT_BSTR: return var (v.bstrVal);
- case VT_BOOL: return var (v.boolVal ? true : false);
- case VT_DISPATCH: return var (new DynamicObjectWrappingIDispatch (v.pdispVal));
- default:
- break;
- }
- }
-
- return var();
- }
-
- //==============================================================================
- // This acts as the embedded HWND
- class AXBrowserPluginHolderComponent : public Component
- {
- public:
- //==============================================================================
- AXBrowserPluginHolderComponent()
- : child (0),
- parentHWND (0),
- browser (0)
- {
- setOpaque (true);
- setWantsKeyboardFocus (false);
-
- addAndMakeVisible (child = createBrowserPlugin());
- jassert (child != 0); // You have to create one of these!
- }
-
- ~AXBrowserPluginHolderComponent()
- {
- setWindow (0);
- deleteAndZero (child);
- }
-
- //==============================================================================
- void paint (Graphics& g)
- {
- if (child == 0 || ! child->isOpaque())
- g.fillAll (Colours::white);
- }
-
- void resized()
- {
- if (child != 0)
- child->setBounds (0, 0, getWidth(), getHeight());
- }
-
- const var getObject() { return child->getJavascriptObject(); }
-
- void setWindow (IOleInPlaceSite* site)
- {
- if (browser != 0)
- {
- browser->Release();
- browser = 0;
- }
-
- HWND newHWND = 0;
-
- if (site != 0)
- {
- site->GetWindow (&newHWND);
-
- IServiceProvider* sp = 0;
- site->QueryInterface (IID_IServiceProvider, (void**) &sp);
-
- if (sp != 0)
- {
- sp->QueryService (IID_IWebBrowserApp, IID_IWebBrowser2, (void**) &browser);
- sp->Release();
- }
- }
-
- if (parentHWND != newHWND)
- {
- removeFromDesktop();
- setVisible (false);
-
- parentHWND = newHWND;
-
- if (parentHWND != 0)
- {
- addToDesktop (0);
-
- HWND ourHWND = (HWND) getWindowHandle();
- SetParent (ourHWND, parentHWND);
- DWORD val = GetWindowLong (ourHWND, GWL_STYLE);
- val = (val & ~WS_POPUP) | WS_CHILD;
- SetWindowLong (ourHWND, GWL_STYLE, val);
-
- setVisible (true);
- }
- }
-
- if (site != 0)
- site->OnInPlaceActivate();
- }
-
- const String getBrowserURL() const
- {
- if (browser == 0)
- return String::empty;
-
- BSTR url = 0;
- browser->get_LocationURL (&url);
- return URL::removeEscapeChars (url);
- }
-
- private:
- //==============================================================================
- BrowserPluginComponent* child;
- HWND parentHWND;
- IWebBrowser2* browser;
- };
-
- //==============================================================================
- extern String browserVersionDesc;
-
- static const String getExePath()
- {
- TCHAR moduleFile [2048];
- moduleFile[0] = 0;
- GetModuleFileName (0, moduleFile, 2048);
- return moduleFile;
- }
-
- static const String getExeVersion (const String& exeFileName, const String& fieldName)
- {
- String resultString;
- DWORD pointlessWin32Variable;
- DWORD size = GetFileVersionInfoSize (exeFileName, &pointlessWin32Variable);
-
- if (size > 0)
- {
- HeapBlock <char> exeInfo;
- exeInfo.calloc (size);
-
- if (GetFileVersionInfo (exeFileName, 0, size, exeInfo))
- {
- TCHAR* result = 0;
- unsigned int resultLen = 0;
-
- // try the 1200 codepage (Unicode)
- String queryStr ("\\StringFileInfo\\040904B0\\" + fieldName);
-
- if (! VerQueryValue (exeInfo, (LPTSTR) (LPCTSTR) queryStr, (void**) &result, &resultLen))
- {
- // try the 1252 codepage (Windows Multilingual)
- queryStr = "\\StringFileInfo\\040904E4\\" + fieldName;
- VerQueryValue (exeInfo, (LPTSTR) (LPCTSTR) queryStr, (void**) &result, &resultLen);
- }
-
- resultString = String (result, resultLen);
- }
- }
-
- return resultString;
- }
-
- static int numActivePlugins = 0;
-
- class JuceActiveXObject : public IUnknown,
- public IDispatch,
- public IObjectWithSite,
- public IObjectSafety,
- public IOleInPlaceObject
- {
- public:
- JuceActiveXObject()
- : refCount (0)
- {
- log ("JuceActiveXObject");
- site = 0;
- holderComp = 0;
- }
-
- ~JuceActiveXObject()
- {
- deleteHolderComp();
- log ("~JuceActiveXObject");
- }
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
- else if (id == IID_IDispatch) { AddRef(); *result = (IDispatch*) this; return S_OK; }
- else if (id == IID_IObjectWithSite) { AddRef(); *result = (IObjectWithSite*) this; return S_OK; }
- else if (id == IID_IObjectSafety) { AddRef(); *result = (IObjectSafety*) this; return S_OK; }
- else if (id == IID_IOleInPlaceObject) { AddRef(); *result = (IOleInPlaceObject*) this; return S_OK; }
- else if (id == IID_IOleWindow) { AddRef(); *result = (IOleWindow*) (IOleInPlaceObject*) this; return S_OK; }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall GetTypeInfoCount (UINT* pctinfo) { return E_NOTIMPL; }
- HRESULT __stdcall GetTypeInfo (UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }
-
- HRESULT __stdcall GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames,
- LCID lcid, DISPID* rgDispId)
- {
- return iDispatchHelper.doGetIDsOfNames (rgszNames, cNames, rgDispId);
- }
-
- HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
- DISPPARAMS* pDispParams, VARIANT* pVarResult,
- EXCEPINFO* pExcepInfo, UINT* puArgErr)
- {
- if (holderComp == 0)
- return DISP_E_MEMBERNOTFOUND;
-
- return iDispatchHelper.doInvoke (holderComp->getObject(),
- dispIdMember, riid, lcid, wFlags, pDispParams,
- pVarResult, pExcepInfo, puArgErr);
- }
-
- HRESULT __stdcall SetSite (IUnknown* newSite)
- {
- if (newSite != site)
- {
- if (site != 0)
- site->Release();
-
- site = newSite;
-
- if (site != 0)
- {
- site->AddRef();
-
- IOleInPlaceSite* inPlaceSite = 0;
- site->QueryInterface (IID_IOleInPlaceSite, (void**) &inPlaceSite);
-
- if (inPlaceSite != 0)
- {
- createHolderComp();
-
- holderComp->setWindow (inPlaceSite);
- inPlaceSite->Release();
- }
- else
- {
- deleteHolderComp();
- }
- }
- else
- {
- deleteHolderComp();
- }
- }
-
- return S_OK;
- }
-
- void createHolderComp()
- {
- if (numActivePlugins++ == 0)
- {
- log ("initialiseJuce_GUI()");
- initialiseJuce_GUI();
-
- browserVersionDesc = "Internet Explorer " + getExeVersion (getExePath(), "FileVersion");
- }
-
- if (holderComp == 0)
- holderComp = new AXBrowserPluginHolderComponent();
- }
-
- void deleteHolderComp()
- {
- deleteAndZero (holderComp);
-
- if (--numActivePlugins == 0)
- {
- log ("shutdownJuce_GUI()");
- shutdownJuce_GUI();
- }
- }
-
- HRESULT __stdcall GetSite (REFIID riid, void **ppvSite)
- {
- *ppvSite = site;
- return S_OK;
- }
-
- //==============================================================================
- HRESULT __stdcall SetObjectRects (LPCRECT r, LPCRECT c)
- {
- if (holderComp != 0)
- holderComp->setBounds (r->left, r->top, r->right - r->left, r->bottom - r->top);
-
- return S_OK;
- }
-
- HRESULT __stdcall GetWindow (HWND* phwnd)
- {
- if (holderComp == 0)
- return E_NOTIMPL;
-
- *phwnd = (HWND) holderComp->getWindowHandle();
- return S_OK;
- }
-
- //==============================================================================
- HRESULT __stdcall ContextSensitiveHelp (BOOL fEnterMode) { return E_NOTIMPL; }
- HRESULT __stdcall InPlaceDeactivate() { return E_NOTIMPL; }
- HRESULT __stdcall UIDeactivate() { return E_NOTIMPL; }
- HRESULT __stdcall ReactivateAndUndo() { return E_NOTIMPL; }
-
- //==============================================================================
- HRESULT __stdcall GetInterfaceSafetyOptions (REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
- {
- *pdwSupportedOptions = *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA;
- return S_OK;
- }
-
- HRESULT __stdcall SetInterfaceSafetyOptions (REFIID, DWORD, DWORD) { return S_OK; }
-
- private:
- IUnknown* site;
- int refCount;
- AXBrowserPluginHolderComponent* holderComp;
- IDispatchHelper iDispatchHelper;
-
- JuceActiveXObject (const JuceActiveXObject&);
- const JuceActiveXObject& operator= (const JuceActiveXObject&);
- };
-
- //==============================================================================
- class JuceActiveXObjectFactory : public IUnknown,
- public IClassFactory
- {
- public:
- JuceActiveXObjectFactory() : refCount (0) {}
- ~JuceActiveXObjectFactory() {}
-
- HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
- {
- if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
- else if (id == IID_IClassFactory) { AddRef(); *result = (IClassFactory*) this; return S_OK; }
-
- *result = 0;
- return E_NOINTERFACE;
- }
-
- ULONG __stdcall AddRef() { return ++refCount; }
- ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
-
- HRESULT __stdcall CreateInstance (IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
- {
- *ppvObject = 0;
-
- if (pUnkOuter != 0 && riid != IID_IUnknown)
- return CLASS_E_NOAGGREGATION;
-
- JuceActiveXObject* ax = new JuceActiveXObject();
- return ax->QueryInterface (riid, ppvObject);
- }
-
- HRESULT __stdcall LockServer (BOOL /*fLock*/) { return S_OK; }
-
- private:
- int refCount;
-
- JuceActiveXObjectFactory (const JuceActiveXObjectFactory&);
- const JuceActiveXObjectFactory& operator= (const JuceActiveXObjectFactory&);
- };
-
- //==============================================================================
- const String getActiveXBrowserURL (const BrowserPluginComponent* comp)
- {
- AXBrowserPluginHolderComponent* const ax = dynamic_cast <AXBrowserPluginHolderComponent*> (comp->getParentComponent());
- return ax != 0 ? ax->getBrowserURL() : String::empty;
- }
-
- //==============================================================================
- extern "C" BOOL WINAPI DllMain (HANDLE instance, DWORD reason, LPVOID)
- {
- #pragma EXPORTED_FUNCTION
-
- switch (reason)
- {
- case DLL_PROCESS_ATTACH:
- log ("DLL_PROCESS_ATTACH");
- PlatformUtilities::setCurrentModuleInstanceHandle (instance);
- break;
-
- case DLL_PROCESS_DETACH:
- log ("DLL_PROCESS_DETACH");
- browserVersionDesc = String::empty;
-
- // IE has a tendency to leak our objects, so although none of this should be
- // necessary, it's best to make sure..
- jassert (numActivePlugins == 0);
- shutdownJuce_GUI();
- break;
-
- default:
- break;
- }
-
- return TRUE;
- }
-
- static const String CLSIDToJuceString (REFCLSID clsid)
- {
- LPWSTR s = 0;
- StringFromIID (clsid, &s);
-
- if (s == 0)
- return String::empty;
-
- const String result (s);
- LPMALLOC malloc;
- CoGetMalloc (1, &malloc);
- if (malloc != 0)
- {
- malloc->Free (s);
- malloc->Release();
- }
-
- return result.removeCharacters (T("{}")).trim();
- }
-
- STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
- {
- #pragma EXPORTED_FUNCTION
-
- *ppv = 0;
-
- if (CLSIDToJuceString (rclsid).equalsIgnoreCase (String (JuceBrowserPlugin_ActiveXCLSID)))
- {
- JuceActiveXObjectFactory* afx = new JuceActiveXObjectFactory();
- if (afx->QueryInterface (riid, ppv) == S_OK)
- return S_OK;
-
- delete afx;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
- }
-
- STDAPI DllCanUnloadNow()
- {
- #pragma EXPORTED_FUNCTION
- return S_OK;
- }
-
- //==============================================================================
- static const String makeLegalRegistryName (const String& s)
- {
- return s.retainCharacters (T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."));
- }
-
- static HRESULT doRegistration (const bool unregister)
- {
- const String company (makeLegalRegistryName (JuceBrowserPlugin_Company));
- const String plugin (makeLegalRegistryName (JuceBrowserPlugin_Name));
- const String clsID ("{" + String (JuceBrowserPlugin_ActiveXCLSID).toUpperCase() + "}");
- const String root ("HKEY_CLASSES_ROOT\\");
- const String companyDotPlugin (company + "." + plugin);
- const String companyDotPluginCur (companyDotPlugin + ".1");
- const String clsIDRoot (root + "CLSID\\" + clsID + "\\");
- const String dllPath (File::getSpecialLocation (File::currentApplicationFile).getFullPathName());
-
- StringPairArray settings;
- settings.set (root + companyDotPluginCur + "\\", JuceBrowserPlugin_Name);
- settings.set (root + companyDotPluginCur + "\\CLSID\\", clsID);
- settings.set (root + companyDotPlugin + "\\", JuceBrowserPlugin_Name);
- settings.set (root + companyDotPlugin + "\\CLSID\\", clsID);
- settings.set (root + companyDotPlugin + "\\CurVer\\", companyDotPluginCur);
- settings.set (clsIDRoot, JuceBrowserPlugin_Name);
- settings.set (clsIDRoot + "Implemented Categories\\{7DD95801-9882-11CF-9FA9-00AA006C42C4}\\", String::empty);
- settings.set (clsIDRoot + "Implemented Categories\\{7DD95802-9882-11CF-9FA9-00AA006C42C4}\\", String::empty);
- settings.set (clsIDRoot + "ProgID\\", companyDotPluginCur);
- settings.set (clsIDRoot + "VersionIndependentProgID\\", companyDotPlugin);
- settings.set (clsIDRoot + "Programmable\\", String::empty);
- settings.set (clsIDRoot + "InProcServer32\\", dllPath);
- settings.set (clsIDRoot + "InProcServer32\\ThreadingModel", "Apartment");
- settings.set (clsIDRoot + "Control\\", String::empty);
- settings.set (clsIDRoot + "Insertable\\", String::empty);
- settings.set (clsIDRoot + "ToolboxBitmap32\\", dllPath + ", 101");
- settings.set (clsIDRoot + "TypeLib\\", "");
- settings.set (clsIDRoot + "Version\\", JuceBrowserPlugin_Version);
-
- if (unregister)
- {
- for (int i = 0; i < settings.getAllKeys().size(); ++i)
- PlatformUtilities::deleteRegistryValue (settings.getAllKeys()[i]);
-
- PlatformUtilities::deleteRegistryKey (root + companyDotPluginCur);
- PlatformUtilities::deleteRegistryKey (root + companyDotPlugin);
- PlatformUtilities::deleteRegistryKey (clsIDRoot);
-
- if (PlatformUtilities::registryValueExists (clsIDRoot + "InProcServer32"))
- return SELFREG_E_CLASS;
- }
- else
- {
- PlatformUtilities::deleteRegistryKey (clsIDRoot);
-
- for (int i = 0; i < settings.getAllKeys().size(); ++i)
- PlatformUtilities::setRegistryValue (settings.getAllKeys()[i],
- settings [settings.getAllKeys()[i]]);
-
- // check whether the registration actually worked - if not, we probably don't have
- // enough privileges to write to the registry..
- if (PlatformUtilities::getRegistryValue (clsIDRoot + "InProcServer32\\") != dllPath)
- return SELFREG_E_CLASS;
- }
-
- return S_OK;
- }
-
- STDAPI DllRegisterServer()
- {
- #pragma EXPORTED_FUNCTION
- return doRegistration (false);
- }
-
- STDAPI DllUnregisterServer()
- {
- #pragma EXPORTED_FUNCTION
- return doRegistration (true);
- }
-
- #endif
|