mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
WinRT: Added a dedicated ComPtr class
This commit is contained in:
parent
1702fa04aa
commit
98def04379
4 changed files with 90 additions and 22 deletions
|
|
@ -679,7 +679,7 @@ public:
|
|||
bool isDefault = false;
|
||||
};
|
||||
|
||||
MidiIODeviceWatcher (ComSmartPtr<COMFactoryType>& comFactory) : factory (comFactory)
|
||||
MidiIODeviceWatcher (WinRTWrapper::ComPtr<COMFactoryType>& comFactory) : factory (comFactory)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -894,12 +894,12 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
ComSmartPtr<COMFactoryType>& factory;
|
||||
WinRTWrapper::ComPtr<COMFactoryType>& factory;
|
||||
|
||||
EventRegistrationToken deviceAddedToken { 0 },
|
||||
deviceRemovedToken { 0 };
|
||||
|
||||
ComSmartPtr<IDeviceWatcher> watcher;
|
||||
WinRTWrapper::ComPtr<IDeviceWatcher> watcher;
|
||||
|
||||
Array<DeviceInfo> connectedDevices;
|
||||
CriticalSection deviceChanges;
|
||||
|
|
@ -913,8 +913,8 @@ public:
|
|||
struct OpenMidiPortThread : public Thread
|
||||
{
|
||||
OpenMidiPortThread (String threadName, String midiDeviceID,
|
||||
ComSmartPtr<COMFactoryType>& comFactory,
|
||||
ComSmartPtr<COMInterfaceType>& comPort)
|
||||
WinRTWrapper::ComPtr<COMFactoryType>& comFactory,
|
||||
WinRTWrapper::ComPtr<COMInterfaceType>& comPort)
|
||||
: Thread (threadName),
|
||||
deviceID (midiDeviceID),
|
||||
factory (comFactory),
|
||||
|
|
@ -930,7 +930,7 @@ public:
|
|||
void run() override
|
||||
{
|
||||
WinRTWrapper::ScopedHString hDeviceId (deviceID);
|
||||
ComSmartPtr<IAsyncOperation<COMType*>> asyncOp;
|
||||
WinRTWrapper::ComPtr<IAsyncOperation<COMType*>> asyncOp;
|
||||
auto hr = factory->FromIdAsync (hDeviceId.get(), asyncOp.resetAndGetPointerAddress());
|
||||
|
||||
if (FAILED (hr))
|
||||
|
|
@ -959,8 +959,8 @@ public:
|
|||
}
|
||||
|
||||
const String deviceID;
|
||||
ComSmartPtr<COMFactoryType>& factory;
|
||||
ComSmartPtr<COMInterfaceType>& port;
|
||||
WinRTWrapper::ComPtr<COMFactoryType>& factory;
|
||||
WinRTWrapper::ComPtr<COMInterfaceType>& port;
|
||||
WaitableEvent portOpened { true };
|
||||
};
|
||||
|
||||
|
|
@ -1038,19 +1038,19 @@ public:
|
|||
if (! isStarted)
|
||||
return S_OK;
|
||||
|
||||
ComSmartPtr<IMidiMessage> message;
|
||||
WinRTWrapper::ComPtr<IMidiMessage> message;
|
||||
auto hr = args->get_Message (message.resetAndGetPointerAddress());
|
||||
|
||||
if (FAILED (hr))
|
||||
return hr;
|
||||
|
||||
ComSmartPtr<IBuffer> buffer;
|
||||
WinRTWrapper::ComPtr<IBuffer> buffer;
|
||||
hr = message->get_RawData (buffer.resetAndGetPointerAddress());
|
||||
|
||||
if (FAILED (hr))
|
||||
return hr;
|
||||
|
||||
ComSmartPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
WinRTWrapper::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
hr = buffer->QueryInterface (bufferByteAccess.resetAndGetPointerAddress());
|
||||
|
||||
if (FAILED (hr))
|
||||
|
|
@ -1101,7 +1101,7 @@ public:
|
|||
MidiInputCallback& callback;
|
||||
String deviceName;
|
||||
MidiDataConcatenator concatenator { 4096 };
|
||||
ComSmartPtr<IMidiInPort> midiInPort;
|
||||
WinRTWrapper::ComPtr<IMidiInPort> midiInPort;
|
||||
EventRegistrationToken midiInMessageToken { 0 };
|
||||
|
||||
double startTime = 0;
|
||||
|
|
@ -1175,16 +1175,16 @@ public:
|
|||
String getDeviceName() override { return deviceName; }
|
||||
|
||||
String deviceName;
|
||||
ComSmartPtr<IMidiOutPort> midiOutPort;
|
||||
ComSmartPtr<IBuffer> buffer;
|
||||
ComSmartPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
WinRTWrapper::ComPtr<IMidiOutPort> midiOutPort;
|
||||
WinRTWrapper::ComPtr<IBuffer> buffer;
|
||||
WinRTWrapper::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
|
||||
uint8_t* bufferData = nullptr;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTOutputWrapper);
|
||||
};
|
||||
|
||||
ComSmartPtr<IMidiInPortStatics> midiInFactory;
|
||||
ComSmartPtr<IMidiOutPortStatics> midiOutFactory;
|
||||
WinRTWrapper::ComPtr<IMidiInPortStatics> midiInFactory;
|
||||
WinRTWrapper::ComPtr<IMidiOutPortStatics> midiOutFactory;
|
||||
|
||||
std::unique_ptr<MidiIODeviceWatcher<IMidiInPortStatics>> inputDeviceWatcher;
|
||||
std::unique_ptr<MidiIODeviceWatcher<IMidiOutPortStatics>> outputDeviceWatcher;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@
|
|||
#endif
|
||||
|
||||
#if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER && JUCE_WINDOWS
|
||||
// If this header file is missing then you are probably attempting to use WinRT
|
||||
// functionality without the WinRT libraries installed on your system. Try installing
|
||||
// the latest Windows Standalone SDK and maybe also adding the path to the WinRT
|
||||
// headers to your build system. This path should have the form
|
||||
// "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt".
|
||||
#include <inspectable.h>
|
||||
#include <hstring.h>
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ String WinRTWrapper::hStringToString (HSTRING hstr)
|
|||
WinRTWrapper::WinRTWrapper()
|
||||
{
|
||||
winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0");
|
||||
|
||||
if (winRTHandle == nullptr)
|
||||
return;
|
||||
|
||||
|
|
@ -64,10 +65,11 @@ WinRTWrapper::WinRTWrapper()
|
|||
createHString = (WindowsCreateStringFuncPtr) ::GetProcAddress (winRTHandle, "WindowsCreateString");
|
||||
deleteHString = (WindowsDeleteStringFuncPtr) ::GetProcAddress (winRTHandle, "WindowsDeleteString");
|
||||
getHStringRawBuffer = (WindowsGetStringRawBufferFuncPtr) ::GetProcAddress (winRTHandle, "WindowsGetStringRawBuffer");
|
||||
roActivateInstance = (RoActivateInstanceFuncPtr) ::GetProcAddress (winRTHandle, "RoActivateInstance");
|
||||
roGetActivationFactory = (RoGetActivationFactoryFuncPtr) ::GetProcAddress (winRTHandle, "RoGetActivationFactory");
|
||||
|
||||
if (roInitialize == nullptr || createHString == nullptr || deleteHString == nullptr
|
||||
|| getHStringRawBuffer == nullptr || roGetActivationFactory == nullptr)
|
||||
|| getHStringRawBuffer == nullptr || roActivateInstance == nullptr || roGetActivationFactory == nullptr)
|
||||
return;
|
||||
|
||||
HRESULT status = roInitialize (1);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ namespace juce
|
|||
class WinRTWrapper : public DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
JUCE_DECLARE_SINGLETON (WinRTWrapper, true)
|
||||
|
||||
class ScopedHString
|
||||
{
|
||||
public:
|
||||
|
|
@ -43,6 +41,48 @@ public:
|
|||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedHString)
|
||||
};
|
||||
|
||||
template <class ComClass>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
ComPtr() noexcept {}
|
||||
ComPtr (ComClass* obj) : p (obj) { if (p) p->AddRef(); }
|
||||
ComPtr (const ComPtr& other) : p (other.p) { if (p) p->AddRef(); }
|
||||
~ComPtr() { release(); }
|
||||
|
||||
operator ComClass*() const noexcept { return p; }
|
||||
ComClass& operator*() const noexcept { return *p; }
|
||||
ComClass* operator->() const noexcept { return p; }
|
||||
|
||||
ComPtr& operator= (ComClass* const newP)
|
||||
{
|
||||
if (newP != nullptr)
|
||||
newP->AddRef();
|
||||
|
||||
release();
|
||||
p = newP;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ComPtr& operator= (const ComPtr& newP) { return operator= (newP.p); }
|
||||
|
||||
ComClass** resetAndGetPointerAddress()
|
||||
{
|
||||
release();
|
||||
p = nullptr;
|
||||
return &p;
|
||||
}
|
||||
|
||||
private:
|
||||
ComClass* p = nullptr;
|
||||
|
||||
void release() { if (p != nullptr) p->Release(); }
|
||||
|
||||
ComClass** operator&() noexcept; // private to avoid it being used accidentally
|
||||
};
|
||||
|
||||
JUCE_DECLARE_SINGLETON (WinRTWrapper, true)
|
||||
|
||||
~WinRTWrapper();
|
||||
|
||||
String hStringToString (HSTRING);
|
||||
|
|
@ -50,9 +90,27 @@ public:
|
|||
bool isInitialised() const noexcept { return initialised; }
|
||||
|
||||
template <class ComClass>
|
||||
ComSmartPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID)
|
||||
ComPtr<ComClass> activateInstance (const wchar_t* runtimeClassID, REFCLSID classUUID)
|
||||
{
|
||||
ComSmartPtr<ComClass> comPtr;
|
||||
ComPtr<ComClass> result;
|
||||
|
||||
if (isInitialised())
|
||||
{
|
||||
ComPtr<IInspectable> inspectable;
|
||||
ScopedHString runtimeClass (runtimeClassID);
|
||||
auto hr = roActivateInstance (runtimeClass.get(), inspectable.resetAndGetPointerAddress());
|
||||
|
||||
if (SUCCEEDED (hr))
|
||||
inspectable->QueryInterface (classUUID, (void**) result.resetAndGetPointerAddress());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class ComClass>
|
||||
ComPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID)
|
||||
{
|
||||
ComPtr<ComClass> comPtr;
|
||||
|
||||
if (isInitialised())
|
||||
{
|
||||
|
|
@ -75,12 +133,14 @@ private:
|
|||
typedef HRESULT (WINAPI* WindowsCreateStringFuncPtr) (LPCWSTR, UINT32, HSTRING*);
|
||||
typedef HRESULT (WINAPI* WindowsDeleteStringFuncPtr) (HSTRING);
|
||||
typedef PCWSTR (WINAPI* WindowsGetStringRawBufferFuncPtr) (HSTRING, UINT32*);
|
||||
typedef HRESULT (WINAPI* RoActivateInstanceFuncPtr) (HSTRING, IInspectable**);
|
||||
typedef HRESULT (WINAPI* RoGetActivationFactoryFuncPtr) (HSTRING, REFIID, void**);
|
||||
|
||||
RoInitializeFuncPtr roInitialize = nullptr;
|
||||
WindowsCreateStringFuncPtr createHString = nullptr;
|
||||
WindowsDeleteStringFuncPtr deleteHString = nullptr;
|
||||
WindowsGetStringRawBufferFuncPtr getHStringRawBuffer = nullptr;
|
||||
RoActivateInstanceFuncPtr roActivateInstance = nullptr;
|
||||
RoGetActivationFactoryFuncPtr roGetActivationFactory = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue