| @@ -834,7 +834,7 @@ private: | |||
| } | |||
| } | |||
| WinRTWrapper::ComPtr<IIterable<HSTRING>> iter; | |||
| ComSmartPtr<IIterable<HSTRING>> iter; | |||
| auto hr = requestedProperties->QueryInterface (__uuidof (IIterable<HSTRING>), (void**) iter.resetAndGetPointerAddress()); | |||
| if (FAILED (hr)) | |||
| @@ -924,7 +924,7 @@ private: | |||
| String getGUIDFromInspectable (IInspectable& inspectable) | |||
| { | |||
| WinRTWrapper::ComPtr<IReference<GUID>> guidRef; | |||
| ComSmartPtr<IReference<GUID>> guidRef; | |||
| auto hr = inspectable.QueryInterface (__uuidof (IReference<GUID>), | |||
| (void**) guidRef.resetAndGetPointerAddress()); | |||
| @@ -951,7 +951,7 @@ private: | |||
| bool getBoolFromInspectable (IInspectable& inspectable) | |||
| { | |||
| WinRTWrapper::ComPtr<IReference<bool>> boolRef; | |||
| ComSmartPtr<IReference<bool>> boolRef; | |||
| auto hr = inspectable.QueryInterface (__uuidof (IReference<bool>), | |||
| (void**) boolRef.resetAndGetPointerAddress()); | |||
| @@ -978,7 +978,7 @@ private: | |||
| struct DeviceEnumerationThread : public Thread | |||
| { | |||
| DeviceEnumerationThread (DeviceCallbackHandler& h, | |||
| WinRTWrapper::ComPtr<IDeviceWatcher>& w, | |||
| ComSmartPtr<IDeviceWatcher>& w, | |||
| EventRegistrationToken& added, | |||
| EventRegistrationToken& removed, | |||
| EventRegistrationToken& updated) | |||
| @@ -1012,12 +1012,12 @@ private: | |||
| } | |||
| DeviceCallbackHandler& handler; | |||
| WinRTWrapper::ComPtr<IDeviceWatcher>& watcher; | |||
| ComSmartPtr<IDeviceWatcher>& watcher; | |||
| EventRegistrationToken& deviceAddedToken, deviceRemovedToken, deviceUpdatedToken; | |||
| }; | |||
| //============================================================================== | |||
| WinRTWrapper::ComPtr<IDeviceWatcher> watcher; | |||
| ComSmartPtr<IDeviceWatcher> watcher; | |||
| EventRegistrationToken deviceAddedToken { 0 }, | |||
| deviceRemovedToken { 0 }, | |||
| @@ -1222,7 +1222,7 @@ private: | |||
| template <typename COMFactoryType> | |||
| struct MidiIODeviceWatcher final : private DeviceCallbackHandler | |||
| { | |||
| MidiIODeviceWatcher (WinRTWrapper::ComPtr<COMFactoryType>& comFactory) | |||
| MidiIODeviceWatcher (ComSmartPtr<COMFactoryType>& comFactory) | |||
| : factory (comFactory) | |||
| { | |||
| } | |||
| @@ -1407,7 +1407,7 @@ private: | |||
| return {}; | |||
| } | |||
| WinRTWrapper::ComPtr<COMFactoryType>& factory; | |||
| ComSmartPtr<COMFactoryType>& factory; | |||
| Array<WinRTMIDIDeviceInfo> connectedDevices; | |||
| CriticalSection deviceChanges; | |||
| @@ -1421,8 +1421,8 @@ private: | |||
| struct OpenMidiPortThread : public Thread | |||
| { | |||
| OpenMidiPortThread (String threadName, String midiDeviceID, | |||
| WinRTWrapper::ComPtr<COMFactoryType>& comFactory, | |||
| WinRTWrapper::ComPtr<COMInterfaceType>& comPort) | |||
| ComSmartPtr<COMFactoryType>& comFactory, | |||
| ComSmartPtr<COMInterfaceType>& comPort) | |||
| : Thread (threadName), | |||
| deviceID (midiDeviceID), | |||
| factory (comFactory), | |||
| @@ -1438,7 +1438,7 @@ private: | |||
| void run() override | |||
| { | |||
| WinRTWrapper::ScopedHString hDeviceId (deviceID); | |||
| WinRTWrapper::ComPtr<IAsyncOperation<COMType*>> asyncOp; | |||
| ComSmartPtr<IAsyncOperation<COMType*>> asyncOp; | |||
| auto hr = factory->FromIdAsync (hDeviceId.get(), asyncOp.resetAndGetPointerAddress()); | |||
| if (FAILED (hr)) | |||
| @@ -1466,8 +1466,8 @@ private: | |||
| } | |||
| const String deviceID; | |||
| WinRTWrapper::ComPtr<COMFactoryType>& factory; | |||
| WinRTWrapper::ComPtr<COMInterfaceType>& port; | |||
| ComSmartPtr<COMFactoryType>& factory; | |||
| ComSmartPtr<COMInterfaceType>& port; | |||
| WaitableEvent portOpened { true }; | |||
| }; | |||
| @@ -1552,7 +1552,7 @@ private: | |||
| BLEDeviceWatcher& bleDeviceWatcher; | |||
| WinRTMIDIDeviceInfo deviceInfo; | |||
| bool isBLEDevice = false; | |||
| WinRTWrapper::ComPtr<MIDIPort> midiPort; | |||
| ComSmartPtr<MIDIPort> midiPort; | |||
| }; | |||
| //============================================================================== | |||
| @@ -1637,19 +1637,19 @@ private: | |||
| if (! isStarted) | |||
| return S_OK; | |||
| WinRTWrapper::ComPtr<IMidiMessage> message; | |||
| ComSmartPtr<IMidiMessage> message; | |||
| auto hr = args->get_Message (message.resetAndGetPointerAddress()); | |||
| if (FAILED (hr)) | |||
| return hr; | |||
| WinRTWrapper::ComPtr<IBuffer> buffer; | |||
| ComSmartPtr<IBuffer> buffer; | |||
| hr = message->get_RawData (buffer.resetAndGetPointerAddress()); | |||
| if (FAILED (hr)) | |||
| return hr; | |||
| WinRTWrapper::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess; | |||
| ComSmartPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess; | |||
| hr = buffer->QueryInterface (bufferByteAccess.resetAndGetPointerAddress()); | |||
| if (FAILED (hr)) | |||
| @@ -1775,15 +1775,15 @@ private: | |||
| String getDeviceName() override { return deviceInfo.name; } | |||
| //============================================================================== | |||
| WinRTWrapper::ComPtr<IBuffer> buffer; | |||
| WinRTWrapper::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess; | |||
| ComSmartPtr<IBuffer> buffer; | |||
| ComSmartPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess; | |||
| uint8_t* bufferData = nullptr; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTOutputWrapper); | |||
| }; | |||
| WinRTWrapper::ComPtr<IMidiInPortStatics> midiInFactory; | |||
| WinRTWrapper::ComPtr<IMidiOutPortStatics> midiOutFactory; | |||
| ComSmartPtr<IMidiInPortStatics> midiInFactory; | |||
| ComSmartPtr<IMidiOutPortStatics> midiOutFactory; | |||
| std::unique_ptr<MidiIODeviceWatcher<IMidiInPortStatics>> inputDeviceWatcher; | |||
| std::unique_ptr<MidiIODeviceWatcher<IMidiOutPortStatics>> outputDeviceWatcher; | |||
| @@ -23,6 +23,36 @@ | |||
| namespace juce | |||
| { | |||
| WinRTWrapper::WinRTWrapper() | |||
| { | |||
| winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0"); | |||
| if (winRTHandle == nullptr) | |||
| return; | |||
| roInitialize = (RoInitializeFuncPtr) ::GetProcAddress (winRTHandle, "RoInitialize"); | |||
| 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 || roActivateInstance == nullptr || roGetActivationFactory == nullptr) | |||
| return; | |||
| HRESULT status = roInitialize (1); | |||
| initialised = ! (status != S_OK && status != S_FALSE && status != 0x80010106L); | |||
| } | |||
| WinRTWrapper::~WinRTWrapper() | |||
| { | |||
| if (winRTHandle != nullptr) | |||
| ::FreeLibrary (winRTHandle); | |||
| clearSingletonInstance(); | |||
| } | |||
| WinRTWrapper::ScopedHString::ScopedHString (String str) | |||
| { | |||
| if (WinRTWrapper::getInstance()->isInitialised()) | |||
| @@ -37,14 +67,6 @@ WinRTWrapper::ScopedHString::~ScopedHString() | |||
| WinRTWrapper::getInstance()->deleteHString (hstr); | |||
| } | |||
| WinRTWrapper::~WinRTWrapper() | |||
| { | |||
| if (winRTHandle != nullptr) | |||
| ::FreeLibrary (winRTHandle); | |||
| clearSingletonInstance(); | |||
| } | |||
| String WinRTWrapper::hStringToString (HSTRING hstr) | |||
| { | |||
| if (isInitialised()) | |||
| @@ -54,27 +76,6 @@ String WinRTWrapper::hStringToString (HSTRING hstr) | |||
| return {}; | |||
| } | |||
| WinRTWrapper::WinRTWrapper() | |||
| { | |||
| winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0"); | |||
| if (winRTHandle == nullptr) | |||
| return; | |||
| roInitialize = (RoInitializeFuncPtr) ::GetProcAddress (winRTHandle, "RoInitialize"); | |||
| 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 || roActivateInstance == nullptr || roGetActivationFactory == nullptr) | |||
| return; | |||
| HRESULT status = roInitialize (1); | |||
| initialised = ! (status != S_OK && status != S_FALSE && status != 0x80010106L); | |||
| } | |||
| JUCE_IMPLEMENT_SINGLETON (WinRTWrapper) | |||
| @@ -26,78 +26,21 @@ namespace juce | |||
| class WinRTWrapper : public DeletedAtShutdown | |||
| { | |||
| public: | |||
| class ScopedHString | |||
| { | |||
| public: | |||
| ScopedHString (String); | |||
| ~ScopedHString(); | |||
| HSTRING get() const noexcept { return hstr; } | |||
| private: | |||
| HSTRING hstr = nullptr; | |||
| 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* get() 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(); | |||
| bool isInitialised() const noexcept { return initialised; } | |||
| String hStringToString (HSTRING); | |||
| bool isInitialised() const noexcept { return initialised; } | |||
| JUCE_DECLARE_SINGLETON (WinRTWrapper, true) | |||
| //============================================================================== | |||
| template <class ComClass> | |||
| ComPtr<ComClass> activateInstance (const wchar_t* runtimeClassID, REFCLSID classUUID) | |||
| ComSmartPtr<ComClass> activateInstance (const wchar_t* runtimeClassID, REFCLSID classUUID) | |||
| { | |||
| ComPtr<ComClass> result; | |||
| ComSmartPtr<ComClass> result; | |||
| if (isInitialised()) | |||
| { | |||
| ComPtr<IInspectable> inspectable; | |||
| ComSmartPtr<IInspectable> inspectable; | |||
| ScopedHString runtimeClass (runtimeClassID); | |||
| auto hr = roActivateInstance (runtimeClass.get(), inspectable.resetAndGetPointerAddress()); | |||
| @@ -109,9 +52,9 @@ public: | |||
| } | |||
| template <class ComClass> | |||
| ComPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID) | |||
| ComSmartPtr<ComClass> getWRLFactory (const wchar_t* runtimeClassID) | |||
| { | |||
| ComPtr<ComClass> comPtr; | |||
| ComSmartPtr<ComClass> comPtr; | |||
| if (isInitialised()) | |||
| { | |||
| @@ -124,9 +67,27 @@ public: | |||
| return comPtr; | |||
| } | |||
| //============================================================================== | |||
| class ScopedHString | |||
| { | |||
| public: | |||
| ScopedHString (String); | |||
| ~ScopedHString(); | |||
| HSTRING get() const noexcept { return hstr; } | |||
| private: | |||
| HSTRING hstr = nullptr; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedHString) | |||
| }; | |||
| String hStringToString (HSTRING); | |||
| private: | |||
| WinRTWrapper(); | |||
| //============================================================================== | |||
| HMODULE winRTHandle = nullptr; | |||
| bool initialised = false; | |||
| @@ -143,6 +104,9 @@ private: | |||
| WindowsGetStringRawBufferFuncPtr getHStringRawBuffer = nullptr; | |||
| RoActivateInstanceFuncPtr roActivateInstance = nullptr; | |||
| RoGetActivationFactoryFuncPtr roGetActivationFactory = nullptr; | |||
| //============================================================================== | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTWrapper) | |||
| }; | |||
| } // namespace juce | |||