| 
							- /*
 -   ==============================================================================
 - 
 -    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
 
 
  |