mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
changed the juce startup/shutdown code in the ActiveX browser plugin to try to work around IE's leakiness; added a very obscure feature to ASIO
This commit is contained in:
parent
f2c0fda2e9
commit
337c67f66c
3 changed files with 155 additions and 94 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <AXBrowserPluginHolderComponent*> (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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue