diff --git a/build/win32/platform_specific_code/juce_win32_ASIO.cpp b/build/win32/platform_specific_code/juce_win32_ASIO.cpp index b6005acbad..0ac2e89809 100644 --- a/build/win32/platform_specific_code/juce_win32_ASIO.cpp +++ b/build/win32/platform_specific_code/juce_win32_ASIO.cpp @@ -86,10 +86,12 @@ class JUCE_API ASIOAudioIODevice : public AudioIODevice, public: Component ourWindow; - ASIOAudioIODevice (const String& name_, const CLSID classId_, const int slotNumber) + ASIOAudioIODevice (const String& name_, const CLSID classId_, const int slotNumber, + const String& optionalDllForDirectLoading_) : AudioIODevice (name_, T("ASIO")), asioObject (0), classId (classId_), + optionalDllForDirectLoading (optionalDllForDirectLoading_), currentBitDepth (16), currentSampleRate (0), tempBuffer (0), @@ -813,6 +815,7 @@ private: void* windowHandle; CLSID classId; + const String optionalDllForDirectLoading; String error; long totalNumInputChans, totalNumOutputChans; @@ -875,11 +878,37 @@ private: { return true; } + + // If a class isn't registered but we have a path for it, we can fallback to + // doing a direct load of the COM object (only available via the juce_createASIOAudioIODeviceForGUID function). + if (optionalDllForDirectLoading.isNotEmpty()) + { + HMODULE h = LoadLibrary (optionalDllForDirectLoading); + + if (h != 0) + { + typedef HRESULT (CALLBACK* DllGetClassObjectFunc) (REFCLSID clsid, REFIID iid, LPVOID* ppv); + DllGetClassObjectFunc dllGetClassObject = (DllGetClassObjectFunc) GetProcAddress (h, "DllGetClassObject"); + + if (dllGetClassObject != 0) + { + IClassFactory* classFactory = 0; + HRESULT hr = dllGetClassObject (classId, IID_IClassFactory, (void**) &classFactory); + + if (classFactory != 0) + { + hr = classFactory->CreateInstance (0, classId, (void**) &asioObject); + classFactory->Release(); + } + + return asioObject != 0; + } + } + } } JUCE_CATCH_ALL asioObject = 0; - return false; } @@ -1804,7 +1833,7 @@ public: const int freeSlot = findFreeSlot(); if (freeSlot >= 0) - return new ASIOAudioIODevice (outputDeviceName, *(classIds [index]), freeSlot); + return new ASIOAudioIODevice (outputDeviceName, *(classIds [index]), freeSlot, String::empty); } return 0; @@ -1932,14 +1961,15 @@ AudioIODeviceType* juce_createASIOAudioIODeviceType() } AudioIODevice* juce_createASIOAudioIODeviceForGUID (const String& name, - void* guid) + void* guid, + const String& optionalDllForDirectLoading) { const int freeSlot = ASIOAudioIODeviceType::findFreeSlot(); if (freeSlot < 0) return 0; - return new ASIOAudioIODevice (name, *(CLSID*) guid, freeSlot); + return new ASIOAudioIODevice (name, *(CLSID*) guid, freeSlot, optionalDllForDirectLoading); } #undef log diff --git a/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp b/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp index 945439297f..b237aa2bf1 100644 --- a/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp +++ b/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp @@ -55,19 +55,12 @@ #endif //============================================================================== -#if JUCE_MAC && JUCE_DEBUG && 0 -static void log (const String& s) -{ - FILE* f = fopen ("/Users/jules/Desktop/log.txt", "a+"); - fprintf (f, (const char*) s); - fprintf (f, "\n"); - fflush (f); - fclose (f); -} -#else -#define log(a) DBG(a) +#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__) @@ -75,10 +68,6 @@ static void log (const String& s) static void juceVarToVariant (const var& v, VARIANT& dest); static const var variantTojuceVar (const VARIANT& v); -#if JUCE_DEBUG - static int numDOWID = 0, numJuceSO = 0; -#endif - //============================================================================== // Takes care of the logic in invoking var methods from IDispatch callbacks. class IDispatchHelper @@ -87,7 +76,7 @@ public: IDispatchHelper() {} ~IDispatchHelper() {} - var::identifier getId (int hash) const + var::identifier getId (const int hash) const { for (int i = knownIdentifiers.size(); --i >= 0;) if (knownIdentifiers.getUnchecked(i)->hashCode == hash) @@ -557,6 +546,52 @@ private: }; //============================================================================== +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) + { + void* const exeInfo = juce_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, queryStr, (void**) &result, &resultLen)) + { + // try the 1252 codepage (Windows Multilingual) + queryStr = "\\StringFileInfo\\040904E4\\" + fieldName; + VerQueryValue (exeInfo, queryStr, (void**) &result, &resultLen); + } + + resultString = String (result, resultLen); + } + + juce_free (exeInfo); + } + + return resultString; +} + +static int numActivePlugins = 0; + class JuceActiveXObject : public IUnknown, public IDispatch, public IObjectWithSite, @@ -574,7 +609,7 @@ public: ~JuceActiveXObject() { - deleteAndZero (holderComp); + deleteHolderComp(); log ("~JuceActiveXObject"); } @@ -633,27 +668,50 @@ public: if (inPlaceSite != 0) { - if (holderComp == 0) - holderComp = new AXBrowserPluginHolderComponent(); + createHolderComp(); holderComp->setWindow (inPlaceSite); - inPlaceSite->Release(); } else { - deleteAndZero (holderComp); + deleteHolderComp(); } } else { - deleteAndZero (holderComp); + 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; @@ -744,50 +802,6 @@ private: }; //============================================================================== -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) - { - void* const exeInfo = juce_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, queryStr, (void**) &result, &resultLen)) - { - // try the 1252 codepage (Windows Multilingual) - queryStr = "\\StringFileInfo\\040904E4\\" + fieldName; - VerQueryValue (exeInfo, queryStr, (void**) &result, &resultLen); - } - - resultString = String (result, resultLen); - } - - juce_free (exeInfo); - } - - return resultString; -} - const String getActiveXBrowserURL (const BrowserPluginComponent* comp) { AXBrowserPluginHolderComponent* const ax = dynamic_cast (comp->getParentComponent()); @@ -799,34 +813,21 @@ extern "C" BOOL WINAPI DllMain (HANDLE instance, DWORD reason, LPVOID) { #pragma EXPORTED_FUNCTION - static int numPluginInstances = 0; - switch (reason) { case DLL_PROCESS_ATTACH: log ("DLL_PROCESS_ATTACH"); - - if (numPluginInstances++ == 0) - { - log ("initialiseJuce_GUI()"); - initialiseJuce_GUI(); - - browserVersionDesc = "Internet Explorer " + getExeVersion (getExePath(), "FileVersion"); - } - PlatformUtilities::setCurrentModuleInstanceHandle (instance); break; case DLL_PROCESS_DETACH: log ("DLL_PROCESS_DETACH"); + browserVersionDesc = String::empty; - if (--numPluginInstances == 0) - { - log ("shutdownJuce_GUI()"); - browserVersionDesc = String::empty; - shutdownJuce_GUI(); - } - + // 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: diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 0b3feef96a..3af340affe 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -252351,10 +252351,12 @@ class JUCE_API ASIOAudioIODevice : public AudioIODevice, public: Component ourWindow; - ASIOAudioIODevice (const String& name_, const CLSID classId_, const int slotNumber) + ASIOAudioIODevice (const String& name_, const CLSID classId_, const int slotNumber, + const String& optionalDllForDirectLoading_) : AudioIODevice (name_, T("ASIO")), asioObject (0), classId (classId_), + optionalDllForDirectLoading (optionalDllForDirectLoading_), currentBitDepth (16), currentSampleRate (0), tempBuffer (0), @@ -253077,6 +253079,7 @@ private: void* windowHandle; CLSID classId; + const String optionalDllForDirectLoading; String error; long totalNumInputChans, totalNumOutputChans; @@ -253137,11 +253140,37 @@ private: { return true; } + + // If a class isn't registered but we have a path for it, we can fallback to + // doing a direct load of the COM object (only available via the juce_createASIOAudioIODeviceForGUID function). + if (optionalDllForDirectLoading.isNotEmpty()) + { + HMODULE h = LoadLibrary (optionalDllForDirectLoading); + + if (h != 0) + { + typedef HRESULT (CALLBACK* DllGetClassObjectFunc) (REFCLSID clsid, REFIID iid, LPVOID* ppv); + DllGetClassObjectFunc dllGetClassObject = (DllGetClassObjectFunc) GetProcAddress (h, "DllGetClassObject"); + + if (dllGetClassObject != 0) + { + IClassFactory* classFactory = 0; + HRESULT hr = dllGetClassObject (classId, IID_IClassFactory, (void**) &classFactory); + + if (classFactory != 0) + { + hr = classFactory->CreateInstance (0, classId, (void**) &asioObject); + classFactory->Release(); + } + + return asioObject != 0; + } + } + } } JUCE_CATCH_ALL asioObject = 0; - return false; } @@ -254058,7 +254087,7 @@ public: const int freeSlot = findFreeSlot(); if (freeSlot >= 0) - return new ASIOAudioIODevice (outputDeviceName, *(classIds [index]), freeSlot); + return new ASIOAudioIODevice (outputDeviceName, *(classIds [index]), freeSlot, String::empty); } return 0; @@ -254183,14 +254212,15 @@ AudioIODeviceType* juce_createASIOAudioIODeviceType() } AudioIODevice* juce_createASIOAudioIODeviceForGUID (const String& name, - void* guid) + void* guid, + const String& optionalDllForDirectLoading) { const int freeSlot = ASIOAudioIODeviceType::findFreeSlot(); if (freeSlot < 0) return 0; - return new ASIOAudioIODevice (name, *(CLSID*) guid, freeSlot); + return new ASIOAudioIODevice (name, *(CLSID*) guid, freeSlot, optionalDllForDirectLoading); } #undef log