diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 392589f9f1..923c9fac62 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -731,6 +731,12 @@ public: return p->QueryInterface (classUUID, (void**) destObject.resetAndGetPointerAddress()); } + template + HRESULT QueryInterface (ComSmartPtr& destObject) const + { + return this->QueryInterface (__uuidof (OtherComClass), destObject); + } + private: ComClass* p; @@ -22781,12 +22787,9 @@ void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile, startSampleInFile = jmax ((int64) 0, startSampleInFile); numSamples = jmax ((int64) 0, jmin (numSamples, length - startSampleInFile)); - source->readMaxLevels (startSampleInFile + startSample, - numSamples, - lowestLeft, - highestLeft, - lowestRight, - highestRight); + source->readMaxLevels (startSampleInFile + startSample, numSamples, + lowestLeft, highestLeft, + lowestRight, highestRight); } END_JUCE_NAMESPACE @@ -23681,7 +23684,7 @@ END_JUCE_NAMESPACE #include #if JUCE_MSVC - #pragma warning (pop) + #pragma warning (pop) #endif #endif @@ -23708,10 +23711,11 @@ public: JUCE_AUTORELEASEPOOL bufferList.calloc (256, 1); -#if JUCE_WINDOWS + #if JUCE_WINDOWS if (InitializeQTML (0) != noErr) return; -#endif + #endif + if (EnterMovies() != noErr) return; @@ -23845,9 +23849,9 @@ public: DisposeMovie (movie); -#if JUCE_MAC + #if JUCE_MAC ExitMoviesOnThread (); -#endif + #endif } bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, @@ -23945,18 +23949,18 @@ private: void checkThreadIsAttached() { -#if JUCE_MAC + #if JUCE_MAC if (Thread::getCurrentThreadId() != lastThreadId) EnterMoviesOnThread (0); AttachMovieToCurrentThread (movie); -#endif + #endif } void detachThread() { -#if JUCE_MAC + #if JUCE_MAC DetachMovieFromCurrentThread (movie); -#endif + #endif } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QTAudioReader); @@ -29099,6 +29103,16 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_MidiOutput.cpp ***/ BEGIN_JUCE_NAMESPACE +struct MidiOutput::PendingMessage +{ + PendingMessage (const void* const data, const int len, const double timeStamp) + : message (data, len, timeStamp) + {} + + MidiMessage message; + PendingMessage* next; +}; + MidiOutput::MidiOutput() : Thread ("midi out"), internal (nullptr), @@ -29106,11 +29120,6 @@ MidiOutput::MidiOutput() { } -MidiOutput::PendingMessage::PendingMessage (const void* const data, const int len, const double timeStamp) - : message (data, len, timeStamp) -{ -} - void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, const double millisecondCounterToStartAt, double samplesPerSecondForBuffer) @@ -29132,8 +29141,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, { const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time; - PendingMessage* const m - = new PendingMessage (data, len, eventTime); + PendingMessage* const m = new PendingMessage (data, len, eventTime); const ScopedLock sl (lock); @@ -58644,7 +58652,7 @@ void TreeView::handleDrag (const StringArray& files, const SourceDetails& dragSo if (item != nullptr) { - if (scrolled || dragInsertPointHighlight == 0 + if (scrolled || dragInsertPointHighlight == nullptr || dragInsertPointHighlight->lastItem != item || dragInsertPointHighlight->lastIndex != insertIndex) { @@ -58666,7 +58674,13 @@ void TreeView::handleDrop (const StringArray& files, const SourceDetails& dragSo hideDragHighlight(); int insertIndex, x, y; - TreeViewItem* const item = getInsertPosition (x, y, insertIndex, files, dragSourceDetails); + TreeViewItem* item = getInsertPosition (x, y, insertIndex, files, dragSourceDetails); + + if (item == nullptr) + { + insertIndex = 0; + item = rootItem; + } if (item != nullptr) { @@ -61407,8 +61421,7 @@ public: owner (owner_), parentContentsList (parentContentsList_), indexInContentsList (indexInContentsList_), - subContentsList (nullptr), - canDeleteSubContentsList (false), + subContentsList (nullptr, false), thread (thread_) { DirectoryContentsList::FileInfo fileInfo; @@ -61429,11 +61442,7 @@ public: ~FileListTreeItem() { thread.removeTimeSliceClient (this); - clearSubItems(); - - if (canDeleteSubContentsList) - delete subContentsList; } bool mightContainSubItems() { return isDirectory; } @@ -61459,8 +61468,7 @@ public: DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); l->setDirectory (file, true, true); - setSubContentsList (l); - canDeleteSubContentsList = true; + setSubContentsList (l, true); } changeListenerCallback (nullptr); @@ -61468,10 +61476,10 @@ public: } } - void setSubContentsList (DirectoryContentsList* newList) + void setSubContentsList (DirectoryContentsList* newList, const bool canDeleteList) { - jassert (subContentsList == nullptr); - subContentsList = newList; + OptionalScopedPointer newPointer (newList, canDeleteList); + subContentsList = newPointer; newList->addChangeListener (this); } @@ -61543,8 +61551,8 @@ private: FileTreeComponent& owner; DirectoryContentsList* parentContentsList; int indexInContentsList; - DirectoryContentsList* subContentsList; - bool isDirectory, canDeleteSubContentsList; + OptionalScopedPointer subContentsList; + bool isDirectory; TimeSliceThread& thread; Image icon; String fileSize; @@ -61583,7 +61591,7 @@ FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow) = new FileListTreeItem (*this, 0, 0, listToShow.getDirectory(), listToShow.getTimeSliceThread()); - root->setSubContentsList (&listToShow); + root->setSubContentsList (&listToShow, false); setRootItemVisible (false); setRootItem (root); } @@ -245951,7 +245959,7 @@ File File::getLinkedTarget() const if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink))) { ComSmartPtr persistFile; - if (SUCCEEDED (shellLink.QueryInterface (IID_IPersistFile, persistFile))) + if (SUCCEEDED (shellLink.QueryInterface (persistFile))) { if (SUCCEEDED (persistFile->Load (p.toWideCharPointer(), STGM_READ)) && SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI))) @@ -246767,12 +246775,9 @@ namespace { HKEY rootKey = 0; - if (name.startsWithIgnoreCase ("HKEY_CURRENT_USER\\")) - rootKey = HKEY_CURRENT_USER; - else if (name.startsWithIgnoreCase ("HKEY_LOCAL_MACHINE\\")) - rootKey = HKEY_LOCAL_MACHINE; - else if (name.startsWithIgnoreCase ("HKEY_CLASSES_ROOT\\")) - rootKey = HKEY_CLASSES_ROOT; + if (name.startsWithIgnoreCase ("HKEY_CURRENT_USER\\")) rootKey = HKEY_CURRENT_USER; + else if (name.startsWithIgnoreCase ("HKEY_LOCAL_MACHINE\\")) rootKey = HKEY_LOCAL_MACHINE; + else if (name.startsWithIgnoreCase ("HKEY_CLASSES_ROOT\\")) rootKey = HKEY_CLASSES_ROOT; if (rootKey != 0) { @@ -246915,10 +246920,9 @@ bool juce_IsRunningInWine() String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() { - const String commandLine (GetCommandLineW()); - return String (CharacterFunctions::findEndOfToken (commandLine.getCharPointer(), - String (" ").getCharPointer(), - String ("\"").getCharPointer())).trimStart(); + return String (CharacterFunctions::findEndOfToken (CharPointer_UTF16 (GetCommandLineW()), + CharPointer_UTF16 (L" "), + CharPointer_UTF16 (L"\""))).trimStart(); } static void* currentModuleHandle = nullptr; @@ -246999,120 +247003,160 @@ private: LPCTSTR getClassNameFromAtom() noexcept { return (LPCTSTR) MAKELONG (atom, 0); } }; -static const unsigned int specialId = WM_APP + 0x4400; -static const unsigned int broadcastId = WM_APP + 0x4403; -static const unsigned int specialCallbackId = WM_APP + 0x4402; +HWND juce_messageWindowHandle = 0; // (this is referred to by other parts of the codebase) -static const TCHAR messageWindowName[] = _T("JUCEWindow"); -static ScopedPointer messageWindow; +class JuceWindowIdentifier +{ +public: + static bool isJUCEWindow (HWND hwnd) noexcept + { + return GetWindowLong (hwnd, GWLP_USERDATA) == improbableWindowNumber; + } -HWND juce_messageWindowHandle = 0; + static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept + { + SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? improbableWindowNumber : 0); + } -extern long improbableWindowNumber; // defined in windowing.cpp +private: + enum { improbableWindowNumber = 0xf965aa01 }; +}; -static LRESULT CALLBACK juce_MessageWndProc (HWND h, - const UINT message, - const WPARAM wParam, - const LPARAM lParam) noexcept +namespace WindowsMessageHelpers { - JUCE_TRY + const unsigned int specialId = WM_APP + 0x4400; + const unsigned int broadcastId = WM_APP + 0x4403; + const unsigned int specialCallbackId = WM_APP + 0x4402; + + const TCHAR messageWindowName[] = _T("JUCEWindow"); + ScopedPointer messageWindow; + + LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept { - if (h == juce_messageWindowHandle) + JUCE_TRY { - if (message == specialCallbackId) - { - MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam; - return (LRESULT) (*func) ((void*) lParam); - } - else if (message == specialId) + if (h == juce_messageWindowHandle) { - // these are trapped early in the dispatch call, but must also be checked - // here in case there are windows modal dialog boxes doing their own - // dispatch loop and not calling our version + if (message == specialCallbackId) + { + MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam; + return (LRESULT) (*func) ((void*) lParam); + } + else if (message == specialId) + { + // these are trapped early in the dispatch call, but must also be checked + // here in case there are windows modal dialog boxes doing their own + // dispatch loop and not calling our version - Message* const message = reinterpret_cast (lParam); - MessageManager::getInstance()->deliverMessage (message); - message->decReferenceCount(); - return 0; - } - else if (message == broadcastId) - { - const ScopedPointer messageString ((String*) lParam); - MessageManager::getInstance()->deliverBroadcastMessage (*messageString); - return 0; - } - else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId) - { - const COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam; + Message* const message = reinterpret_cast (lParam); + MessageManager::getInstance()->deliverMessage (message); + message->decReferenceCount(); + return 0; + } + else if (message == broadcastId) + { + const ScopedPointer messageString ((String*) lParam); + MessageManager::getInstance()->deliverBroadcastMessage (*messageString); + return 0; + } + else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId) + { + const COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam; - const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), - data->cbData / sizeof (CharPointer_UTF32::CharType)); + const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), + data->cbData / sizeof (CharPointer_UTF32::CharType)); - PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString)); - return 0; + PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString)); + return 0; + } } } + JUCE_CATCH_EXCEPTION + + return DefWindowProc (h, message, wParam, lParam); } - JUCE_CATCH_EXCEPTION - return DefWindowProc (h, message, wParam, lParam); -} + bool isHWNDBlockedByModalComponents (HWND h) noexcept + { + for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) + { + Component* const c = Desktop::getInstance().getComponent (i); -static bool isEventBlockedByModalComps (MSG& m) -{ - if (Component::getNumCurrentlyModalComponents() == 0 - || GetWindowLong (m.hwnd, GWLP_USERDATA) == improbableWindowNumber) - return false; + if (c != nullptr + && (! c->isCurrentlyBlockedByAnotherModalComponent()) + && IsChild ((HWND) c->getWindowHandle(), h)) + return false; + } + + return true; + } - switch (m.message) + bool isEventBlockedByModalComps (MSG& m) { - case WM_MOUSEMOVE: - case WM_NCMOUSEMOVE: - case 0x020A: /* WM_MOUSEWHEEL */ - case 0x020E: /* WM_MOUSEHWHEEL */ - case WM_KEYUP: - case WM_SYSKEYUP: - case WM_CHAR: - case WM_APPCOMMAND: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_MOUSEACTIVATE: - case WM_NCMOUSEHOVER: - case WM_MOUSEHOVER: - return true; + if (Component::getNumCurrentlyModalComponents() == 0 || JuceWindowIdentifier::isJUCEWindow (m.hwnd)) + return false; - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_KEYDOWN: - case WM_SYSKEYDOWN: + switch (m.message) { - Component* const modal = Component::getCurrentlyModalComponent (0); - if (modal != nullptr) - modal->inputAttemptWhenModal(); + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + case 0x020A: /* WM_MOUSEWHEEL */ + case 0x020E: /* WM_MOUSEHWHEEL */ + case WM_KEYUP: + case WM_SYSKEYUP: + case WM_CHAR: + case WM_APPCOMMAND: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_MOUSEACTIVATE: + case WM_NCMOUSEHOVER: + case WM_MOUSEHOVER: + return isHWNDBlockedByModalComponents (m.hwnd); - return true; + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONDBLCLK: + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (isHWNDBlockedByModalComponents (m.hwnd)) + { + Component* const modal = Component::getCurrentlyModalComponent (0); + if (modal != nullptr) + modal->inputAttemptWhenModal(); + + return true; + } + break; + + default: + break; } - default: - break; + return false; } - return false; + BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) + { + if (hwnd != juce_messageWindowHandle) + reinterpret_cast *> (lParam)->add (hwnd); + + return TRUE; + } } bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) { + using namespace WindowsMessageHelpers; MSG m; if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, 0)) @@ -247131,16 +247175,16 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend if (JUCEApplication::getInstance() != nullptr) JUCEApplication::getInstance()->systemRequestedQuit(); } - else if (! isEventBlockedByModalComps (m)) + else if (! WindowsMessageHelpers::isEventBlockedByModalComps (m)) { if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN) - && GetWindowLong (m.hwnd, GWLP_USERDATA) != improbableWindowNumber) + && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd)) { // if it's someone else's window being clicked on, and the focus is // currently on a juce window, pass the kb focus over.. HWND currentFocus = GetFocus(); - if (currentFocus == 0 || GetWindowLong (currentFocus, GWLP_USERDATA) == improbableWindowNumber) + if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus)) SetFocus (m.hwnd); } @@ -247155,7 +247199,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend bool MessageManager::postMessageToSystemQueue (Message* message) { message->incReferenceCount(); - return PostMessage (juce_messageWindowHandle, specialId, 0, (LPARAM) message) != 0; + return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0; } void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, @@ -247173,29 +247217,21 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); return (void*) SendMessage (juce_messageWindowHandle, - specialCallbackId, + WindowsMessageHelpers::specialCallbackId, (WPARAM) callback, (LPARAM) userData); } } -static BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) -{ - if (hwnd != juce_messageWindowHandle) - reinterpret_cast *> (lParam)->add (hwnd); - - return TRUE; -} - void MessageManager::broadcastMessage (const String& value) { Array windows; - EnumWindows (&broadcastEnumWindowProc, (LPARAM) &windows); + EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); const String localCopy (value); COPYDATASTRUCT data; - data.dwData = broadcastId; + data.dwData = WindowsMessageHelpers::broadcastId; data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); data.lpData = (void*) localCopy.toUTF32().getAddress(); @@ -247207,7 +247243,7 @@ void MessageManager::broadcastMessage (const String& value) GetWindowText (hwnd, windowName, 64); windowName [63] = 0; - if (String (windowName) == messageWindowName) + if (String (windowName) == WindowsMessageHelpers::messageWindowName) { DWORD_PTR result; SendMessageTimeout (hwnd, WM_COPYDATA, @@ -247222,13 +247258,14 @@ void MessageManager::doPlatformSpecificInitialisation() { OleInitialize (0); - messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) juce_MessageWndProc); + using namespace WindowsMessageHelpers; + messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) messageWndProc); juce_messageWindowHandle = messageWindow->getHWND(); } void MessageManager::doPlatformSpecificShutdown() { - messageWindow = nullptr; + WindowsMessageHelpers::messageWindow = nullptr; OleUninitialize(); } @@ -248898,8 +248935,6 @@ namespace IconConverters } } -long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp - class Win32ComponentPeer : public ComponentPeer { public: @@ -248946,7 +248981,7 @@ public: // do this before the next bit to avoid messages arriving for this window // before it's destroyed - SetWindowLongPtr (hwnd, GWLP_USERDATA, 0); + JuceWindowIdentifier::setAsJUCEWindow (hwnd, false); callFunctionIfNotLocked (&destroyWindowCallback, (void*) hwnd); @@ -249297,7 +249332,7 @@ public: static Win32ComponentPeer* getOwnerOfWindow (HWND h) noexcept { - if (h != 0 && GetWindowLongPtr (h, GWLP_USERDATA) == improbableWindowNumber) + if (h != 0 && JuceWindowIdentifier::isJUCEWindow (h)) return (Win32ComponentPeer*) (pointer_sized_int) GetWindowLongPtr (h, 8); return nullptr; @@ -249610,7 +249645,7 @@ private: { SetWindowLongPtr (hwnd, 0, 0); SetWindowLongPtr (hwnd, 8, (LONG_PTR) this); - SetWindowLongPtr (hwnd, GWLP_USERDATA, improbableWindowNumber); + JuceWindowIdentifier::setAsJUCEWindow (hwnd, true); if (dropTarget == nullptr) dropTarget = new JuceDropTarget (this); @@ -252123,8 +252158,6 @@ namespace ActiveXHelpers class JuceOleInPlaceFrame : public ComBaseClassHelper { - HWND window; - public: JuceOleInPlaceFrame (HWND window_) : window (window_) {} @@ -252139,14 +252172,14 @@ namespace ActiveXHelpers HRESULT __stdcall RemoveMenus (HMENU) { return E_NOTIMPL; } HRESULT __stdcall SetStatusText (LPCOLESTR) { return S_OK; } HRESULT __stdcall EnableModeless (BOOL) { return S_OK; } - HRESULT __stdcall TranslateAccelerator(LPMSG, WORD) { return E_NOTIMPL; } + HRESULT __stdcall TranslateAccelerator (LPMSG, WORD) { return E_NOTIMPL; } + + private: + HWND window; }; class JuceIOleInPlaceSite : public ComBaseClassHelper { - HWND window; - JuceOleInPlaceFrame* frame; - public: JuceIOleInPlaceSite (HWND window_) : window (window_), @@ -252184,12 +252217,14 @@ namespace ActiveXHelpers HRESULT __stdcall DiscardUndoState() { return E_NOTIMPL; } HRESULT __stdcall DeactivateAndUndo() { return E_NOTIMPL; } HRESULT __stdcall OnPosRectChange (LPCRECT) { return S_OK; } + + private: + HWND window; + JuceOleInPlaceFrame* frame; }; class JuceIOleClientSite : public ComBaseClassHelper { - JuceIOleInPlaceSite* inplaceSite; - public: JuceIOleClientSite (HWND window) : inplaceSite (new JuceIOleInPlaceSite (window)) @@ -252218,11 +252253,14 @@ namespace ActiveXHelpers HRESULT __stdcall ShowObject() { return S_OK; } HRESULT __stdcall OnShowWindow (BOOL) { return E_NOTIMPL; } HRESULT __stdcall RequestNewObjectLayout() { return E_NOTIMPL; } + + private: + JuceIOleInPlaceSite* inplaceSite; }; static Array activeXComps; - static HWND getHWND (const ActiveXControlComponent* const component) + HWND getHWND (const ActiveXControlComponent* const component) { HWND hwnd = 0; @@ -252238,7 +252276,7 @@ namespace ActiveXHelpers return hwnd; } - static void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) + void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) { RECT activeXRect, peerRect; GetWindowRect (hwnd, &activeXRect); @@ -252278,7 +252316,7 @@ public: controlHWND (0), storage (new ActiveXHelpers::JuceIStorage()), clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)), - control (0) + control (nullptr) { } @@ -252555,7 +252593,7 @@ void QuickTimeMovieComponent::createControlIfNeeded() const IID qtInterfaceIID = __uuidof (IQTControl); pimpl->qtControl = (IQTControl*) queryInterface (&qtInterfaceIID); - if (pimpl->qtControl != 0) + if (pimpl->qtControl != nullptr) { pimpl->qtControl->Release(); // it has one ref too many at this point @@ -252979,13 +253017,13 @@ namespace DirectShowHelpers hr = graphBuilder->AddFilter (baseFilter, L"VMR-7"); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IVMRFilterConfig, filterConfig); + hr = baseFilter.QueryInterface (filterConfig); if (SUCCEEDED (hr)) hr = filterConfig->SetRenderingMode (VMRMode_Windowless); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IVMRWindowlessControl, windowlessControl); + hr = baseFilter.QueryInterface (windowlessControl); if (SUCCEEDED (hr)) hr = windowlessControl->SetVideoClippingWindow (hwnd); @@ -253049,7 +253087,7 @@ namespace DirectShowHelpers hr = graphBuilder->AddFilter (baseFilter, L"EVR"); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IMFGetService, getService); + hr = baseFilter.QueryInterface (getService); if (SUCCEEDED (hr)) hr = getService->GetService (MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, @@ -253193,10 +253231,10 @@ public: HRESULT hr = graphBuilder.CoCreateInstance (CLSID_FilterGraph); // basic playback interfaces - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaControl, mediaControl); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaPosition, mediaPosition); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaEventEx, mediaEvent); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IBasicAudio, basicAudio); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaControl); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaPosition); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaEvent); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (basicAudio); // video renderer interface if (SUCCEEDED (hr)) @@ -260009,7 +260047,7 @@ EDataFlow getDataFlow (const ComSmartPtr& device) { EDataFlow flow = eRender; ComSmartPtr endPoint; - if (check (device.QueryInterface (__uuidof (IMMEndpoint), endPoint))) + if (check (device.QueryInterface (endPoint))) (void) check (endPoint->GetDataFlow (&flow)); return flow; @@ -261017,7 +261055,8 @@ private: { if (message == WM_DEVICECHANGE && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ - || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/)) + || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ + || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) { ((WASAPIAudioIODeviceType*) GetWindowLongPtr (h, GWLP_USERDATA))->handleDeviceChange(); } @@ -261095,7 +261134,7 @@ public: if (FAILED (hr)) return; - hr = graphBuilder.QueryInterface (IID_IMediaControl, mediaControl); + hr = graphBuilder.QueryInterface (mediaControl); if (FAILED (hr)) return; @@ -261134,7 +261173,7 @@ public: if (FAILED (hr)) return; - hr = sampleGrabberBase.QueryInterface (IID_ISampleGrabber, sampleGrabber); + hr = sampleGrabberBase.QueryInterface (sampleGrabber); if (FAILED (hr)) return; @@ -261235,7 +261274,7 @@ public: if (getPin (filter, PINDIR_OUTPUT, pin)) { ComSmartPtr pushSource; - HRESULT hr = pin.QueryInterface (IID_IAMPushSource, pushSource); + HRESULT hr = pin.QueryInterface (pushSource); if (pushSource != nullptr) { @@ -261308,7 +261347,7 @@ public: if (SUCCEEDED (hr)) { ComSmartPtr fileSink; - hr = asfWriter.QueryInterface (IID_IFileSinkFilter, fileSink); + hr = asfWriter.QueryInterface (fileSink); if (SUCCEEDED (hr)) { @@ -261321,7 +261360,7 @@ public: if (SUCCEEDED (hr)) { ComSmartPtr asfConfig; - hr = asfWriter.QueryInterface (IID_IConfigAsfWriter, asfConfig); + hr = asfWriter.QueryInterface (asfConfig); asfConfig->SetIndexMode (true); ComSmartPtr profileManager; hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress()); @@ -276747,7 +276786,7 @@ struct MessageDispatchSystem MessageQueue messageQueue; }; -static MessageDispatchSystem* dispatcher = nullptr; +static ScopedPointer dispatcher; void MessageManager::doPlatformSpecificInitialisation() { @@ -276757,7 +276796,7 @@ void MessageManager::doPlatformSpecificInitialisation() void MessageManager::doPlatformSpecificShutdown() { - deleteAndZero (dispatcher); + dispatcher = nullptr; } bool MessageManager::postMessageToSystemQueue (Message* message) diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 10241b4c1b..b5fe0aa639 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 105 +#define JUCE_BUILDNUMBER 107 /** Current Juce version number. @@ -41305,16 +41305,8 @@ public: protected: void* internal; - - struct PendingMessage - { - PendingMessage (const void* data, int len, double timeStamp); - - MidiMessage message; - PendingMessage* next; - }; - CriticalSection lock; + struct PendingMessage; PendingMessage* firstMessage; MidiOutput(); @@ -55445,6 +55437,8 @@ public: For this to work, you'll need to have also implemented isInterestedInFileDrag(). The insertIndex value indicates where in the list of sub-items the files were dropped. + If files are dropped onto an area of the tree where there are no visible items, this + method is called on the root item of the tree, with an insert index of 0. @see FileDragAndDropTarget::filesDropped, isInterestedInFileDrag */ virtual void filesDropped (const StringArray& files, int insertIndex); @@ -55462,6 +55456,8 @@ public: For this to work, you need to have also implemented isInterestedInDragSource(). The insertIndex value indicates where in the list of sub-items the new items should be placed. + If files are dropped onto an area of the tree where there are no visible items, this + method is called on the root item of the tree, with an insert index of 0. @see isInterestedInDragSource, DragAndDropTarget::itemDropped */ virtual void itemDropped (const DragAndDropTarget::SourceDetails& dragSourceDetails, int insertIndex); diff --git a/src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp b/src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp index 19f3381370..476ce0d931 100644 --- a/src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp +++ b/src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp @@ -85,12 +85,9 @@ void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile, startSampleInFile = jmax ((int64) 0, startSampleInFile); numSamples = jmax ((int64) 0, jmin (numSamples, length - startSampleInFile)); - source->readMaxLevels (startSampleInFile + startSample, - numSamples, - lowestLeft, - highestLeft, - lowestRight, - highestRight); + source->readMaxLevels (startSampleInFile + startSample, numSamples, + lowestLeft, highestLeft, + lowestRight, highestRight); } END_JUCE_NAMESPACE diff --git a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp index 6b7e0c6549..8131b5cb0e 100644 --- a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp @@ -53,7 +53,7 @@ #include #if JUCE_MSVC - #pragma warning (pop) + #pragma warning (pop) #endif #endif @@ -90,10 +90,11 @@ public: JUCE_AUTORELEASEPOOL bufferList.calloc (256, 1); -#if JUCE_WINDOWS + #if JUCE_WINDOWS if (InitializeQTML (0) != noErr) return; -#endif + #endif + if (EnterMovies() != noErr) return; @@ -227,9 +228,9 @@ public: DisposeMovie (movie); -#if JUCE_MAC + #if JUCE_MAC ExitMoviesOnThread (); -#endif + #endif } bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, @@ -328,18 +329,18 @@ private: //============================================================================== void checkThreadIsAttached() { -#if JUCE_MAC + #if JUCE_MAC if (Thread::getCurrentThreadId() != lastThreadId) EnterMoviesOnThread (0); AttachMovieToCurrentThread (movie); -#endif + #endif } void detachThread() { -#if JUCE_MAC + #if JUCE_MAC DetachMovieFromCurrentThread (movie); -#endif + #endif } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QTAudioReader); diff --git a/src/audio/midi/juce_MidiOutput.cpp b/src/audio/midi/juce_MidiOutput.cpp index cdd9684d47..6c01aad41c 100644 --- a/src/audio/midi/juce_MidiOutput.cpp +++ b/src/audio/midi/juce_MidiOutput.cpp @@ -32,6 +32,16 @@ BEGIN_JUCE_NAMESPACE //============================================================================== +struct MidiOutput::PendingMessage +{ + PendingMessage (const void* const data, const int len, const double timeStamp) + : message (data, len, timeStamp) + {} + + MidiMessage message; + PendingMessage* next; +}; + MidiOutput::MidiOutput() : Thread ("midi out"), internal (nullptr), @@ -39,11 +49,6 @@ MidiOutput::MidiOutput() { } -MidiOutput::PendingMessage::PendingMessage (const void* const data, const int len, const double timeStamp) - : message (data, len, timeStamp) -{ -} - void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, const double millisecondCounterToStartAt, double samplesPerSecondForBuffer) @@ -65,8 +70,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, { const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time; - PendingMessage* const m - = new PendingMessage (data, len, eventTime); + PendingMessage* const m = new PendingMessage (data, len, eventTime); const ScopedLock sl (lock); diff --git a/src/audio/midi/juce_MidiOutput.h b/src/audio/midi/juce_MidiOutput.h index ead287c71f..7c8e719b50 100644 --- a/src/audio/midi/juce_MidiOutput.h +++ b/src/audio/midi/juce_MidiOutput.h @@ -138,16 +138,8 @@ public: protected: //============================================================================== void* internal; - - struct PendingMessage - { - PendingMessage (const void* data, int len, double timeStamp); - - MidiMessage message; - PendingMessage* next; - }; - CriticalSection lock; + struct PendingMessage; PendingMessage* firstMessage; MidiOutput(); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 5f9f1a3ec4..18ca419b56 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 105 +#define JUCE_BUILDNUMBER 106 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index 2df44d6150..178394aafa 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -1036,7 +1036,7 @@ void TreeView::handleDrag (const StringArray& files, const SourceDetails& dragSo if (item != nullptr) { - if (scrolled || dragInsertPointHighlight == 0 + if (scrolled || dragInsertPointHighlight == nullptr || dragInsertPointHighlight->lastItem != item || dragInsertPointHighlight->lastIndex != insertIndex) { @@ -1058,7 +1058,13 @@ void TreeView::handleDrop (const StringArray& files, const SourceDetails& dragSo hideDragHighlight(); int insertIndex, x, y; - TreeViewItem* const item = getInsertPosition (x, y, insertIndex, files, dragSourceDetails); + TreeViewItem* item = getInsertPosition (x, y, insertIndex, files, dragSourceDetails); + + if (item == nullptr) + { + insertIndex = 0; + item = rootItem; + } if (item != nullptr) { diff --git a/src/gui/components/controls/juce_TreeView.h b/src/gui/components/controls/juce_TreeView.h index d13a16b6f5..7ed7fcda63 100644 --- a/src/gui/components/controls/juce_TreeView.h +++ b/src/gui/components/controls/juce_TreeView.h @@ -373,6 +373,8 @@ public: For this to work, you'll need to have also implemented isInterestedInFileDrag(). The insertIndex value indicates where in the list of sub-items the files were dropped. + If files are dropped onto an area of the tree where there are no visible items, this + method is called on the root item of the tree, with an insert index of 0. @see FileDragAndDropTarget::filesDropped, isInterestedInFileDrag */ virtual void filesDropped (const StringArray& files, int insertIndex); @@ -390,6 +392,8 @@ public: For this to work, you need to have also implemented isInterestedInDragSource(). The insertIndex value indicates where in the list of sub-items the new items should be placed. + If files are dropped onto an area of the tree where there are no visible items, this + method is called on the root item of the tree, with an insert index of 0. @see isInterestedInDragSource, DragAndDropTarget::itemDropped */ virtual void itemDropped (const DragAndDropTarget::SourceDetails& dragSourceDetails, int insertIndex); diff --git a/src/gui/components/filebrowser/juce_FileTreeComponent.cpp b/src/gui/components/filebrowser/juce_FileTreeComponent.cpp index a43732e5aa..052a637af7 100644 --- a/src/gui/components/filebrowser/juce_FileTreeComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileTreeComponent.cpp @@ -31,6 +31,7 @@ BEGIN_JUCE_NAMESPACE #include "../lookandfeel/juce_LookAndFeel.h" #include "../../graphics/imaging/juce_ImageCache.h" #include "../../../events/juce_AsyncUpdater.h" +#include "../../../memory/juce_OptionalScopedPointer.h" Image juce_createIconForFile (const File& file); @@ -52,8 +53,7 @@ public: owner (owner_), parentContentsList (parentContentsList_), indexInContentsList (indexInContentsList_), - subContentsList (nullptr), - canDeleteSubContentsList (false), + subContentsList (nullptr, false), thread (thread_) { DirectoryContentsList::FileInfo fileInfo; @@ -74,11 +74,7 @@ public: ~FileListTreeItem() { thread.removeTimeSliceClient (this); - clearSubItems(); - - if (canDeleteSubContentsList) - delete subContentsList; } //============================================================================== @@ -105,8 +101,7 @@ public: DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); l->setDirectory (file, true, true); - setSubContentsList (l); - canDeleteSubContentsList = true; + setSubContentsList (l, true); } changeListenerCallback (nullptr); @@ -114,10 +109,10 @@ public: } } - void setSubContentsList (DirectoryContentsList* newList) + void setSubContentsList (DirectoryContentsList* newList, const bool canDeleteList) { - jassert (subContentsList == nullptr); - subContentsList = newList; + OptionalScopedPointer newPointer (newList, canDeleteList); + subContentsList = newPointer; newList->addChangeListener (this); } @@ -189,8 +184,8 @@ private: FileTreeComponent& owner; DirectoryContentsList* parentContentsList; int indexInContentsList; - DirectoryContentsList* subContentsList; - bool isDirectory, canDeleteSubContentsList; + OptionalScopedPointer subContentsList; + bool isDirectory; TimeSliceThread& thread; Image icon; String fileSize; @@ -230,7 +225,7 @@ FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow) = new FileListTreeItem (*this, 0, 0, listToShow.getDirectory(), listToShow.getTimeSliceThread()); - root->setSubContentsList (&listToShow); + root->setSubContentsList (&listToShow, false); setRootItemVisible (false); setRootItem (root); } diff --git a/src/native/mac/juce_ios_MessageManager.mm b/src/native/mac/juce_ios_MessageManager.mm index 4de7a0a01c..05c760139c 100644 --- a/src/native/mac/juce_ios_MessageManager.mm +++ b/src/native/mac/juce_ios_MessageManager.mm @@ -125,7 +125,7 @@ struct MessageDispatchSystem MessageQueue messageQueue; }; -static MessageDispatchSystem* dispatcher = nullptr; +static ScopedPointer dispatcher; void MessageManager::doPlatformSpecificInitialisation() { @@ -135,7 +135,7 @@ void MessageManager::doPlatformSpecificInitialisation() void MessageManager::doPlatformSpecificShutdown() { - deleteAndZero (dispatcher); + dispatcher = nullptr; } bool MessageManager::postMessageToSystemQueue (Message* message) diff --git a/src/native/windows/juce_win32_ActiveXComponent.cpp b/src/native/windows/juce_win32_ActiveXComponent.cpp index 067a9246a8..965ab49a23 100644 --- a/src/native/windows/juce_win32_ActiveXComponent.cpp +++ b/src/native/windows/juce_win32_ActiveXComponent.cpp @@ -55,8 +55,6 @@ namespace ActiveXHelpers //============================================================================== class JuceOleInPlaceFrame : public ComBaseClassHelper { - HWND window; - public: JuceOleInPlaceFrame (HWND window_) : window (window_) {} @@ -71,15 +69,15 @@ namespace ActiveXHelpers HRESULT __stdcall RemoveMenus (HMENU) { return E_NOTIMPL; } HRESULT __stdcall SetStatusText (LPCOLESTR) { return S_OK; } HRESULT __stdcall EnableModeless (BOOL) { return S_OK; } - HRESULT __stdcall TranslateAccelerator(LPMSG, WORD) { return E_NOTIMPL; } + HRESULT __stdcall TranslateAccelerator (LPMSG, WORD) { return E_NOTIMPL; } + + private: + HWND window; }; //============================================================================== class JuceIOleInPlaceSite : public ComBaseClassHelper { - HWND window; - JuceOleInPlaceFrame* frame; - public: JuceIOleInPlaceSite (HWND window_) : window (window_), @@ -117,13 +115,15 @@ namespace ActiveXHelpers HRESULT __stdcall DiscardUndoState() { return E_NOTIMPL; } HRESULT __stdcall DeactivateAndUndo() { return E_NOTIMPL; } HRESULT __stdcall OnPosRectChange (LPCRECT) { return S_OK; } + + private: + HWND window; + JuceOleInPlaceFrame* frame; }; //============================================================================== class JuceIOleClientSite : public ComBaseClassHelper { - JuceIOleInPlaceSite* inplaceSite; - public: JuceIOleClientSite (HWND window) : inplaceSite (new JuceIOleInPlaceSite (window)) @@ -152,12 +152,15 @@ namespace ActiveXHelpers HRESULT __stdcall ShowObject() { return S_OK; } HRESULT __stdcall OnShowWindow (BOOL) { return E_NOTIMPL; } HRESULT __stdcall RequestNewObjectLayout() { return E_NOTIMPL; } + + private: + JuceIOleInPlaceSite* inplaceSite; }; //============================================================================== static Array activeXComps; - static HWND getHWND (const ActiveXControlComponent* const component) + HWND getHWND (const ActiveXControlComponent* const component) { HWND hwnd = 0; @@ -173,7 +176,7 @@ namespace ActiveXHelpers return hwnd; } - static void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) + void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) { RECT activeXRect, peerRect; GetWindowRect (hwnd, &activeXRect); @@ -214,7 +217,7 @@ public: controlHWND (0), storage (new ActiveXHelpers::JuceIStorage()), clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)), - control (0) + control (nullptr) { } @@ -309,6 +312,7 @@ public: IOleObject* control; }; +//============================================================================== ActiveXControlComponent::ActiveXControlComponent() : originalWndProc (0), mouseEventsAllowed (true) diff --git a/src/native/windows/juce_win32_CameraDevice.cpp b/src/native/windows/juce_win32_CameraDevice.cpp index 5382d41971..b5fcdab477 100644 --- a/src/native/windows/juce_win32_CameraDevice.cpp +++ b/src/native/windows/juce_win32_CameraDevice.cpp @@ -56,7 +56,7 @@ public: if (FAILED (hr)) return; - hr = graphBuilder.QueryInterface (IID_IMediaControl, mediaControl); + hr = graphBuilder.QueryInterface (mediaControl); if (FAILED (hr)) return; @@ -95,7 +95,7 @@ public: if (FAILED (hr)) return; - hr = sampleGrabberBase.QueryInterface (IID_ISampleGrabber, sampleGrabber); + hr = sampleGrabberBase.QueryInterface (sampleGrabber); if (FAILED (hr)) return; @@ -196,7 +196,7 @@ public: if (getPin (filter, PINDIR_OUTPUT, pin)) { ComSmartPtr pushSource; - HRESULT hr = pin.QueryInterface (IID_IAMPushSource, pushSource); + HRESULT hr = pin.QueryInterface (pushSource); if (pushSource != nullptr) { @@ -269,7 +269,7 @@ public: if (SUCCEEDED (hr)) { ComSmartPtr fileSink; - hr = asfWriter.QueryInterface (IID_IFileSinkFilter, fileSink); + hr = asfWriter.QueryInterface (fileSink); if (SUCCEEDED (hr)) { @@ -282,7 +282,7 @@ public: if (SUCCEEDED (hr)) { ComSmartPtr asfConfig; - hr = asfWriter.QueryInterface (IID_IConfigAsfWriter, asfConfig); + hr = asfWriter.QueryInterface (asfConfig); asfConfig->SetIndexMode (true); ComSmartPtr profileManager; hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress()); diff --git a/src/native/windows/juce_win32_DirectShowComponent.cpp b/src/native/windows/juce_win32_DirectShowComponent.cpp index 416a1cdb5c..21e8e2d8c6 100644 --- a/src/native/windows/juce_win32_DirectShowComponent.cpp +++ b/src/native/windows/juce_win32_DirectShowComponent.cpp @@ -69,13 +69,13 @@ namespace DirectShowHelpers hr = graphBuilder->AddFilter (baseFilter, L"VMR-7"); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IVMRFilterConfig, filterConfig); + hr = baseFilter.QueryInterface (filterConfig); if (SUCCEEDED (hr)) hr = filterConfig->SetRenderingMode (VMRMode_Windowless); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IVMRWindowlessControl, windowlessControl); + hr = baseFilter.QueryInterface (windowlessControl); if (SUCCEEDED (hr)) hr = windowlessControl->SetVideoClippingWindow (hwnd); @@ -141,7 +141,7 @@ namespace DirectShowHelpers hr = graphBuilder->AddFilter (baseFilter, L"EVR"); if (SUCCEEDED (hr)) - hr = baseFilter.QueryInterface (IID_IMFGetService, getService); + hr = baseFilter.QueryInterface (getService); if (SUCCEEDED (hr)) hr = getService->GetService (MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, @@ -292,10 +292,10 @@ public: HRESULT hr = graphBuilder.CoCreateInstance (CLSID_FilterGraph); // basic playback interfaces - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaControl, mediaControl); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaPosition, mediaPosition); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IMediaEventEx, mediaEvent); - if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (IID_IBasicAudio, basicAudio); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaControl); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaPosition); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (mediaEvent); + if (SUCCEEDED (hr)) hr = graphBuilder.QueryInterface (basicAudio); // video renderer interface if (SUCCEEDED (hr)) diff --git a/src/native/windows/juce_win32_Files.cpp b/src/native/windows/juce_win32_Files.cpp index 4dfb74e483..bbc414adc8 100644 --- a/src/native/windows/juce_win32_Files.cpp +++ b/src/native/windows/juce_win32_Files.cpp @@ -598,7 +598,7 @@ File File::getLinkedTarget() const if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink))) { ComSmartPtr persistFile; - if (SUCCEEDED (shellLink.QueryInterface (IID_IPersistFile, persistFile))) + if (SUCCEEDED (shellLink.QueryInterface (persistFile))) { if (SUCCEEDED (persistFile->Load (p.toWideCharPointer(), STGM_READ)) && SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI))) diff --git a/src/native/windows/juce_win32_Messaging.cpp b/src/native/windows/juce_win32_Messaging.cpp index 3f2c726ad8..45a5f109af 100644 --- a/src/native/windows/juce_win32_Messaging.cpp +++ b/src/native/windows/juce_win32_Messaging.cpp @@ -71,122 +71,165 @@ private: //============================================================================== -static const unsigned int specialId = WM_APP + 0x4400; -static const unsigned int broadcastId = WM_APP + 0x4403; -static const unsigned int specialCallbackId = WM_APP + 0x4402; +HWND juce_messageWindowHandle = 0; // (this is referred to by other parts of the codebase) -static const TCHAR messageWindowName[] = _T("JUCEWindow"); -static ScopedPointer messageWindow; +//============================================================================== +class JuceWindowIdentifier +{ +public: + static bool isJUCEWindow (HWND hwnd) noexcept + { + return GetWindowLong (hwnd, GWLP_USERDATA) == improbableWindowNumber; + } -HWND juce_messageWindowHandle = 0; + static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept + { + SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? improbableWindowNumber : 0); + } -extern long improbableWindowNumber; // defined in windowing.cpp +private: + enum { improbableWindowNumber = 0xf965aa01 }; +}; //============================================================================== -static LRESULT CALLBACK juce_MessageWndProc (HWND h, - const UINT message, - const WPARAM wParam, - const LPARAM lParam) noexcept +namespace WindowsMessageHelpers { - JUCE_TRY + const unsigned int specialId = WM_APP + 0x4400; + const unsigned int broadcastId = WM_APP + 0x4403; + const unsigned int specialCallbackId = WM_APP + 0x4402; + + const TCHAR messageWindowName[] = _T("JUCEWindow"); + ScopedPointer messageWindow; + + //============================================================================== + LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept { - if (h == juce_messageWindowHandle) + JUCE_TRY { - if (message == specialCallbackId) + if (h == juce_messageWindowHandle) { - MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam; - return (LRESULT) (*func) ((void*) lParam); - } - else if (message == specialId) - { - // these are trapped early in the dispatch call, but must also be checked - // here in case there are windows modal dialog boxes doing their own - // dispatch loop and not calling our version - - Message* const message = reinterpret_cast (lParam); - MessageManager::getInstance()->deliverMessage (message); - message->decReferenceCount(); - return 0; - } - else if (message == broadcastId) - { - const ScopedPointer messageString ((String*) lParam); - MessageManager::getInstance()->deliverBroadcastMessage (*messageString); - return 0; - } - else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId) - { - const COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam; - - const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), - data->cbData / sizeof (CharPointer_UTF32::CharType)); - - PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString)); - return 0; + if (message == specialCallbackId) + { + MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam; + return (LRESULT) (*func) ((void*) lParam); + } + else if (message == specialId) + { + // these are trapped early in the dispatch call, but must also be checked + // here in case there are windows modal dialog boxes doing their own + // dispatch loop and not calling our version + + Message* const message = reinterpret_cast (lParam); + MessageManager::getInstance()->deliverMessage (message); + message->decReferenceCount(); + return 0; + } + else if (message == broadcastId) + { + const ScopedPointer messageString ((String*) lParam); + MessageManager::getInstance()->deliverBroadcastMessage (*messageString); + return 0; + } + else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId) + { + const COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam; + + const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), + data->cbData / sizeof (CharPointer_UTF32::CharType)); + + PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString)); + return 0; + } } } + JUCE_CATCH_EXCEPTION + + return DefWindowProc (h, message, wParam, lParam); } - JUCE_CATCH_EXCEPTION - return DefWindowProc (h, message, wParam, lParam); -} + bool isHWNDBlockedByModalComponents (HWND h) noexcept + { + for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) + { + Component* const c = Desktop::getInstance().getComponent (i); -static bool isEventBlockedByModalComps (MSG& m) -{ - if (Component::getNumCurrentlyModalComponents() == 0 - || GetWindowLong (m.hwnd, GWLP_USERDATA) == improbableWindowNumber) - return false; + if (c != nullptr + && (! c->isCurrentlyBlockedByAnotherModalComponent()) + && IsChild ((HWND) c->getWindowHandle(), h)) + return false; + } - switch (m.message) + return true; + } + + bool isEventBlockedByModalComps (MSG& m) { - case WM_MOUSEMOVE: - case WM_NCMOUSEMOVE: - case 0x020A: /* WM_MOUSEWHEEL */ - case 0x020E: /* WM_MOUSEHWHEEL */ - case WM_KEYUP: - case WM_SYSKEYUP: - case WM_CHAR: - case WM_APPCOMMAND: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_MOUSEACTIVATE: - case WM_NCMOUSEHOVER: - case WM_MOUSEHOVER: - return true; - - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - Component* const modal = Component::getCurrentlyModalComponent (0); - if (modal != nullptr) - modal->inputAttemptWhenModal(); + if (Component::getNumCurrentlyModalComponents() == 0 || JuceWindowIdentifier::isJUCEWindow (m.hwnd)) + return false; - return true; + switch (m.message) + { + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + case 0x020A: /* WM_MOUSEWHEEL */ + case 0x020E: /* WM_MOUSEHWHEEL */ + case WM_KEYUP: + case WM_SYSKEYUP: + case WM_CHAR: + case WM_APPCOMMAND: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_MOUSEACTIVATE: + case WM_NCMOUSEHOVER: + case WM_MOUSEHOVER: + return isHWNDBlockedByModalComponents (m.hwnd); + + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONDBLCLK: + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (isHWNDBlockedByModalComponents (m.hwnd)) + { + Component* const modal = Component::getCurrentlyModalComponent (0); + if (modal != nullptr) + modal->inputAttemptWhenModal(); + + return true; + } + break; + + default: + break; } - default: - break; + return false; } - return false; + BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) + { + if (hwnd != juce_messageWindowHandle) + reinterpret_cast *> (lParam)->add (hwnd); + + return TRUE; + } } +//============================================================================== bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) { + using namespace WindowsMessageHelpers; MSG m; if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, 0)) @@ -205,16 +248,16 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend if (JUCEApplication::getInstance() != nullptr) JUCEApplication::getInstance()->systemRequestedQuit(); } - else if (! isEventBlockedByModalComps (m)) + else if (! WindowsMessageHelpers::isEventBlockedByModalComps (m)) { if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN) - && GetWindowLong (m.hwnd, GWLP_USERDATA) != improbableWindowNumber) + && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd)) { // if it's someone else's window being clicked on, and the focus is // currently on a juce window, pass the kb focus over.. HWND currentFocus = GetFocus(); - if (currentFocus == 0 || GetWindowLong (currentFocus, GWLP_USERDATA) == improbableWindowNumber) + if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus)) SetFocus (m.hwnd); } @@ -226,14 +269,12 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend return true; } -//============================================================================== bool MessageManager::postMessageToSystemQueue (Message* message) { message->incReferenceCount(); - return PostMessage (juce_messageWindowHandle, specialId, 0, (LPARAM) message) != 0; + return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0; } -//============================================================================== void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* userData) { @@ -249,30 +290,21 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); return (void*) SendMessage (juce_messageWindowHandle, - specialCallbackId, + WindowsMessageHelpers::specialCallbackId, (WPARAM) callback, (LPARAM) userData); } } -//============================================================================== -static BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) -{ - if (hwnd != juce_messageWindowHandle) - reinterpret_cast *> (lParam)->add (hwnd); - - return TRUE; -} - void MessageManager::broadcastMessage (const String& value) { Array windows; - EnumWindows (&broadcastEnumWindowProc, (LPARAM) &windows); + EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); const String localCopy (value); COPYDATASTRUCT data; - data.dwData = broadcastId; + data.dwData = WindowsMessageHelpers::broadcastId; data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); data.lpData = (void*) localCopy.toUTF32().getAddress(); @@ -284,7 +316,7 @@ void MessageManager::broadcastMessage (const String& value) GetWindowText (hwnd, windowName, 64); windowName [63] = 0; - if (String (windowName) == messageWindowName) + if (String (windowName) == WindowsMessageHelpers::messageWindowName) { DWORD_PTR result; SendMessageTimeout (hwnd, WM_COPYDATA, @@ -300,13 +332,14 @@ void MessageManager::doPlatformSpecificInitialisation() { OleInitialize (0); - messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) juce_MessageWndProc); + using namespace WindowsMessageHelpers; + messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) messageWndProc); juce_messageWindowHandle = messageWindow->getHWND(); } void MessageManager::doPlatformSpecificShutdown() { - messageWindow = nullptr; + WindowsMessageHelpers::messageWindow = nullptr; OleUninitialize(); } diff --git a/src/native/windows/juce_win32_NativeIncludes.h b/src/native/windows/juce_win32_NativeIncludes.h index 475c3a9a0d..0493f04c31 100644 --- a/src/native/windows/juce_win32_NativeIncludes.h +++ b/src/native/windows/juce_win32_NativeIncludes.h @@ -254,6 +254,12 @@ public: return p->QueryInterface (classUUID, (void**) destObject.resetAndGetPointerAddress()); } + template + HRESULT QueryInterface (ComSmartPtr& destObject) const + { + return this->QueryInterface (__uuidof (OtherComClass), destObject); + } + private: ComClass* p; diff --git a/src/native/windows/juce_win32_PlatformUtils.cpp b/src/native/windows/juce_win32_PlatformUtils.cpp index 1577c321f1..ce02b53465 100644 --- a/src/native/windows/juce_win32_PlatformUtils.cpp +++ b/src/native/windows/juce_win32_PlatformUtils.cpp @@ -35,12 +35,9 @@ namespace { HKEY rootKey = 0; - if (name.startsWithIgnoreCase ("HKEY_CURRENT_USER\\")) - rootKey = HKEY_CURRENT_USER; - else if (name.startsWithIgnoreCase ("HKEY_LOCAL_MACHINE\\")) - rootKey = HKEY_LOCAL_MACHINE; - else if (name.startsWithIgnoreCase ("HKEY_CLASSES_ROOT\\")) - rootKey = HKEY_CLASSES_ROOT; + if (name.startsWithIgnoreCase ("HKEY_CURRENT_USER\\")) rootKey = HKEY_CURRENT_USER; + else if (name.startsWithIgnoreCase ("HKEY_LOCAL_MACHINE\\")) rootKey = HKEY_LOCAL_MACHINE; + else if (name.startsWithIgnoreCase ("HKEY_CLASSES_ROOT\\")) rootKey = HKEY_CLASSES_ROOT; if (rootKey != 0) { @@ -186,10 +183,9 @@ bool juce_IsRunningInWine() //============================================================================== String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() { - const String commandLine (GetCommandLineW()); - return String (CharacterFunctions::findEndOfToken (commandLine.getCharPointer(), - String (" ").getCharPointer(), - String ("\"").getCharPointer())).trimStart(); + return String (CharacterFunctions::findEndOfToken (CharPointer_UTF16 (GetCommandLineW()), + CharPointer_UTF16 (L" "), + CharPointer_UTF16 (L"\""))).trimStart(); } //============================================================================== diff --git a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp index 53bb7a38ea..b2e19a2e79 100644 --- a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp +++ b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp @@ -99,7 +99,7 @@ void QuickTimeMovieComponent::createControlIfNeeded() const IID qtInterfaceIID = __uuidof (IQTControl); pimpl->qtControl = (IQTControl*) queryInterface (&qtInterfaceIID); - if (pimpl->qtControl != 0) + if (pimpl->qtControl != nullptr) { pimpl->qtControl->Release(); // it has one ref too many at this point diff --git a/src/native/windows/juce_win32_WASAPI.cpp b/src/native/windows/juce_win32_WASAPI.cpp index da8f2cd5d6..2cd4d09187 100644 --- a/src/native/windows/juce_win32_WASAPI.cpp +++ b/src/native/windows/juce_win32_WASAPI.cpp @@ -109,7 +109,7 @@ EDataFlow getDataFlow (const ComSmartPtr& device) { EDataFlow flow = eRender; ComSmartPtr endPoint; - if (check (device.QueryInterface (__uuidof (IMMEndpoint), endPoint))) + if (check (device.QueryInterface (endPoint))) (void) check (endPoint->GetDataFlow (&flow)); return flow; @@ -1134,7 +1134,8 @@ private: { if (message == WM_DEVICECHANGE && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ - || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/)) + || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ + || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) { ((WASAPIAudioIODeviceType*) GetWindowLongPtr (h, GWLP_USERDATA))->handleDeviceChange(); } diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index 069a3412d4..ee4665b050 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -415,10 +415,6 @@ namespace IconConverters } } -//============================================================================== -long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp - - //============================================================================== class Win32ComponentPeer : public ComponentPeer { @@ -467,7 +463,7 @@ public: // do this before the next bit to avoid messages arriving for this window // before it's destroyed - SetWindowLongPtr (hwnd, GWLP_USERDATA, 0); + JuceWindowIdentifier::setAsJUCEWindow (hwnd, false); callFunctionIfNotLocked (&destroyWindowCallback, (void*) hwnd); @@ -820,7 +816,7 @@ public: //============================================================================== static Win32ComponentPeer* getOwnerOfWindow (HWND h) noexcept { - if (h != 0 && GetWindowLongPtr (h, GWLP_USERDATA) == improbableWindowNumber) + if (h != 0 && JuceWindowIdentifier::isJUCEWindow (h)) return (Win32ComponentPeer*) (pointer_sized_int) GetWindowLongPtr (h, 8); return nullptr; @@ -1140,7 +1136,7 @@ private: { SetWindowLongPtr (hwnd, 0, 0); SetWindowLongPtr (hwnd, 8, (LONG_PTR) this); - SetWindowLongPtr (hwnd, GWLP_USERDATA, improbableWindowNumber); + JuceWindowIdentifier::setAsJUCEWindow (hwnd, true); if (dropTarget == nullptr) dropTarget = new JuceDropTarget (this);