| @@ -788,7 +788,7 @@ public: | |||
| AudioEffectX::resume(); | |||
| #if JucePlugin_ProducesMidiOutput | |||
| outgoingEvents.ensureSize (64); | |||
| outgoingEvents.ensureSize (512); | |||
| #endif | |||
| #if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 | |||
| @@ -287,8 +287,8 @@ private: | |||
| } | |||
| private: | |||
| const String attributeToSort; | |||
| const int direction; | |||
| String attributeToSort; | |||
| int direction; | |||
| }; | |||
| //============================================================================== | |||
| @@ -877,8 +877,6 @@ private: | |||
| Drawable* image = iconsFromZipFile [iconNames.indexOf (filename)]->createCopy(); | |||
| return new ToolbarButton (itemId, text, image, 0); | |||
| return 0; | |||
| } | |||
| // Demonstrates how to put a custom component into a toolbar - this one contains | |||
| @@ -217544,7 +217544,6 @@ namespace ActiveXHelpers | |||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | |||
| { | |||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||
| *lplpFrame = frame; | |||
| *lplpDoc = 0; | |||
| lpFrameInfo->fMDIApp = FALSE; | |||
| @@ -217662,7 +217661,7 @@ namespace ActiveXHelpers | |||
| } | |||
| } | |||
| class ActiveXControlComponent::ActiveXControlData : public ComponentMovementWatcher | |||
| class ActiveXControlComponent::Pimpl : public ComponentMovementWatcher | |||
| { | |||
| ActiveXControlComponent* const owner; | |||
| bool wasShowing; | |||
| @@ -217673,8 +217672,7 @@ public: | |||
| IOleClientSite* clientSite; | |||
| IOleObject* control; | |||
| ActiveXControlData (HWND hwnd, | |||
| ActiveXControlComponent* const owner_) | |||
| Pimpl (HWND hwnd, ActiveXControlComponent* const owner_) | |||
| : ComponentMovementWatcher (owner_), | |||
| owner (owner_), | |||
| wasShowing (owner_ != 0 && owner_->isShowing()), | |||
| @@ -217685,7 +217683,7 @@ public: | |||
| { | |||
| } | |||
| ~ActiveXControlData() | |||
| ~Pimpl() | |||
| { | |||
| if (control != 0) | |||
| { | |||
| @@ -217727,20 +217725,15 @@ public: | |||
| componentPeerChanged(); | |||
| } | |||
| static bool doesWindowMatch (const ActiveXControlComponent* const ax, HWND hwnd) | |||
| { | |||
| return ((ActiveXControlData*) ax->control) != 0 | |||
| && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | |||
| } | |||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | |||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |||
| { | |||
| for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | |||
| { | |||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) ActiveXHelpers::activeXComps.getUnchecked(i); | |||
| const ActiveXControlComponent* const ax | |||
| = static_cast <const ActiveXControlComponent*> (ActiveXHelpers::activeXComps.getUnchecked(i)); | |||
| if (doesWindowMatch (ax, hwnd)) | |||
| if (ax->control != 0 && ax->control->controlHWND == hwnd) | |||
| { | |||
| switch (message) | |||
| { | |||
| @@ -217772,7 +217765,7 @@ public: | |||
| break; | |||
| } | |||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||
| return CallWindowProc ((WNDPROC) ax->originalWndProc, hwnd, message, wParam, lParam); | |||
| } | |||
| } | |||
| @@ -217782,7 +217775,6 @@ public: | |||
| ActiveXControlComponent::ActiveXControlComponent() | |||
| : originalWndProc (0), | |||
| control (0), | |||
| mouseEventsAllowed (true) | |||
| { | |||
| ActiveXHelpers::activeXComps.add (this); | |||
| @@ -217813,16 +217805,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | |||
| HWND hwnd = (HWND) peer->getNativeHandle(); | |||
| ScopedPointer <ActiveXControlData> info (new ActiveXControlData (hwnd, this)); | |||
| ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, this)); | |||
| HRESULT hr; | |||
| if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | |||
| info->clientSite, info->storage, | |||
| (void**) &(info->control))) == S_OK) | |||
| newControl->clientSite, newControl->storage, | |||
| (void**) &(newControl->control))) == S_OK) | |||
| { | |||
| info->control->SetHostNames (L"Juce", 0); | |||
| newControl->control->SetHostNames (L"Juce", 0); | |||
| if (OleSetContainedObject (info->control, TRUE) == S_OK) | |||
| if (OleSetContainedObject (newControl->control, TRUE) == S_OK) | |||
| { | |||
| RECT rect; | |||
| rect.left = pos.getX(); | |||
| @@ -217830,17 +217822,17 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| rect.right = pos.getX() + getWidth(); | |||
| rect.bottom = pos.getY() + getHeight(); | |||
| if (info->control->DoVerb (OLEIVERB_SHOW, 0, info->clientSite, 0, hwnd, &rect) == S_OK) | |||
| if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) | |||
| { | |||
| control = info.release(); | |||
| control = newControl; | |||
| setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | |||
| ((ActiveXControlData*) control)->controlHWND = ActiveXHelpers::getHWND (this); | |||
| control->controlHWND = ActiveXHelpers::getHWND (this); | |||
| if (((ActiveXControlData*) control)->controlHWND != 0) | |||
| if (control->controlHWND != 0) | |||
| { | |||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | |||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) ActiveXControlData::activeXHookWndProc); | |||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); | |||
| SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); | |||
| } | |||
| return true; | |||
| @@ -217854,24 +217846,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| void ActiveXControlComponent::deleteControl() | |||
| { | |||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||
| if (info != 0) | |||
| { | |||
| delete info; | |||
| control = 0; | |||
| originalWndProc = 0; | |||
| } | |||
| control = 0; | |||
| originalWndProc = 0; | |||
| } | |||
| void* ActiveXControlComponent::queryInterface (const void* iid) const | |||
| { | |||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||
| void* result = 0; | |||
| if (info != 0 && info->control != 0 | |||
| && info->control->QueryInterface (*(const IID*) iid, &result) == S_OK) | |||
| if (control != 0 && control->control != 0 | |||
| && SUCCEEDED (control->control->QueryInterface (*(const IID*) iid, &result))) | |||
| return result; | |||
| return 0; | |||
| @@ -217879,18 +217863,14 @@ void* ActiveXControlComponent::queryInterface (const void* iid) const | |||
| void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | |||
| { | |||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||
| if (hwnd != 0) | |||
| MoveWindow (hwnd, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||
| if (control->controlHWND != 0) | |||
| MoveWindow (control->controlHWND, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||
| } | |||
| void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | |||
| { | |||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||
| if (hwnd != 0) | |||
| ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||
| if (control->controlHWND != 0) | |||
| ShowWindow (control->controlHWND, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||
| } | |||
| void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | |||
| @@ -225858,8 +225838,7 @@ public: | |||
| minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | |||
| defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | |||
| FloatElementComparator<double> comparator; | |||
| rates.addSorted (comparator, defaultSampleRate); | |||
| rates.addUsingDefaultSort (defaultSampleRate); | |||
| static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | |||
| @@ -225873,7 +225852,7 @@ public: | |||
| if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | |||
| (WAVEFORMATEX*) &format, 0))) | |||
| if (! rates.contains (ratesToTest[i])) | |||
| rates.addSorted (comparator, ratesToTest[i]); | |||
| rates.addUsingDefaultSort (ratesToTest[i]); | |||
| } | |||
| } | |||
| @@ -226024,6 +226003,9 @@ private: | |||
| return false; | |||
| } | |||
| WASAPIDeviceBase (const WASAPIDeviceBase&); | |||
| WASAPIDeviceBase& operator= (const WASAPIDeviceBase&); | |||
| }; | |||
| class WASAPIInputDevice : public WASAPIDeviceBase | |||
| @@ -226169,6 +226151,10 @@ public: | |||
| ComSmartPtr <IAudioCaptureClient> captureClient; | |||
| MemoryBlock reservoir; | |||
| int reservoirSize, reservoirCapacity; | |||
| private: | |||
| WASAPIInputDevice (const WASAPIInputDevice&); | |||
| WASAPIInputDevice& operator= (const WASAPIInputDevice&); | |||
| }; | |||
| class WASAPIOutputDevice : public WASAPIDeviceBase | |||
| @@ -226260,6 +226246,10 @@ public: | |||
| } | |||
| ComSmartPtr <IAudioRenderClient> renderClient; | |||
| private: | |||
| WASAPIOutputDevice (const WASAPIOutputDevice&); | |||
| WASAPIOutputDevice& operator= (const WASAPIOutputDevice&); | |||
| }; | |||
| class WASAPIAudioIODevice : public AudioIODevice, | |||
| @@ -226321,16 +226311,15 @@ public: | |||
| sampleRates = d->rates; | |||
| } | |||
| IntegerElementComparator<int> comparator; | |||
| bufferSizes.addSorted (comparator, defaultBufferSize); | |||
| bufferSizes.addUsingDefaultSort (defaultBufferSize); | |||
| if (minBufferSize != defaultBufferSize) | |||
| bufferSizes.addSorted (comparator, minBufferSize); | |||
| bufferSizes.addUsingDefaultSort (minBufferSize); | |||
| int n = 64; | |||
| for (int i = 0; i < 40; ++i) | |||
| { | |||
| if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | |||
| bufferSizes.addSorted (comparator, n); | |||
| bufferSizes.addUsingDefaultSort (n); | |||
| n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | |||
| } | |||
| @@ -1860,24 +1860,15 @@ static int findInsertIndexInSortedArray (ElementComparator& comparator, | |||
| } | |||
| template <class ElementType> | |||
| class IntegerElementComparator | |||
| class DefaultElementComparator | |||
| { | |||
| public: | |||
| static int compareElements (const ElementType first, | |||
| const ElementType second) throw() | |||
| { | |||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||
| } | |||
| }; | |||
| private: | |||
| typedef PARAMETER_TYPE (ElementType) ParameterType; | |||
| template <class ElementType> | |||
| class FloatElementComparator | |||
| { | |||
| public: | |||
| static int compareElements (const ElementType first, | |||
| const ElementType second) throw() | |||
| static int compareElements (ParameterType first, ParameterType second) | |||
| { | |||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||
| return (first < second) ? -1 : ((first < second) ? 1 : 0); | |||
| } | |||
| }; | |||
| @@ -2297,6 +2288,12 @@ public: | |||
| insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | |||
| } | |||
| void addUsingDefaultSort (ParameterType newElement) | |||
| { | |||
| DefaultElementComparator <ElementType> comparator; | |||
| addSorted (comparator, newElement); | |||
| } | |||
| template <class ElementComparator> | |||
| int indexOfSorted (ElementComparator& comparator, ParameterType elementToLookFor) const | |||
| { | |||
| @@ -5890,9 +5887,8 @@ public: | |||
| { | |||
| removeRange (firstValue, numValuesToAdd); | |||
| IntegerElementComparator<Type> sorter; | |||
| values.addSorted (sorter, firstValue); | |||
| values.addSorted (sorter, firstValue + numValuesToAdd); | |||
| values.addUsingDefaultSort (firstValue); | |||
| values.addUsingDefaultSort (firstValue + numValuesToAdd); | |||
| simplify(); | |||
| } | |||
| @@ -5926,13 +5922,11 @@ public: | |||
| } | |||
| } | |||
| IntegerElementComparator<Type> sorter; | |||
| if (onAtStart) | |||
| values.addSorted (sorter, firstValue); | |||
| values.addUsingDefaultSort (firstValue); | |||
| if (onAtEnd) | |||
| values.addSorted (sorter, lastValue); | |||
| values.addUsingDefaultSort (lastValue); | |||
| simplify(); | |||
| } | |||
| @@ -26231,16 +26225,17 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class ActiveXControlData; | |||
| friend class ActiveXControlData; | |||
| void* control; | |||
| class Pimpl; | |||
| friend class Pimpl; | |||
| friend class ScopedPointer <Pimpl>; | |||
| ScopedPointer <Pimpl> control; | |||
| bool mouseEventsAllowed; | |||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||
| void setControlBounds (const Rectangle<int>& bounds) const; | |||
| void setControlVisible (bool b) const; | |||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||
| }; | |||
| #endif | |||
| @@ -329,7 +329,7 @@ public: | |||
| /** Appends a new element at the end of the array. | |||
| @param newElement the new object to add to the array | |||
| @see set, insert, addIfNotAlreadyThere, addSorted, addArray | |||
| @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray | |||
| */ | |||
| void add (ParameterType newElement) | |||
| { | |||
| @@ -348,7 +348,7 @@ public: | |||
| @param indexToInsertAt the index at which the new element should be | |||
| inserted (pass in -1 to add it to the end) | |||
| @param newElement the new object to add to the array | |||
| @see add, addSorted, set | |||
| @see add, addSorted, addUsingDefaultSort, set | |||
| */ | |||
| void insert (int indexToInsertAt, ParameterType newElement) | |||
| { | |||
| @@ -580,7 +580,7 @@ public: | |||
| @param comparator the comparator to use to compare the elements - see the sort() | |||
| method for details about the form this object should take | |||
| @param newElement the new element to insert to the array | |||
| @see add, sort | |||
| @see addUsingDefaultSort, add, sort | |||
| */ | |||
| template <class ElementComparator> | |||
| void addSorted (ElementComparator& comparator, ParameterType newElement) | |||
| @@ -589,6 +589,21 @@ public: | |||
| insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); | |||
| } | |||
| /** Inserts a new element into the array, assuming that the array is sorted. | |||
| This will use the DefaultElementComparator class for sorting, so your ElementType | |||
| must be suitable for use with that class. If the array isn't sorted, the behaviour of this | |||
| method will be unpredictable. | |||
| @param newElement the new element to insert to the array | |||
| @see addSorted, sort | |||
| */ | |||
| void addUsingDefaultSort (ParameterType newElement) | |||
| { | |||
| DefaultElementComparator <ElementType> comparator; | |||
| addSorted (comparator, newElement); | |||
| } | |||
| /** Finds the index of an element in the array, assuming that the array is sorted. | |||
| This will use a comparator to do a binary-chop to find the index of the given | |||
| @@ -258,58 +258,30 @@ static int findInsertIndexInSortedArray (ElementComparator& comparator, | |||
| //============================================================================== | |||
| /** | |||
| A simple ElementComparator class that can be used to sort an array of | |||
| integer primitive objects. | |||
| objects that support the '<' operator. | |||
| This will work for primitive types and objects that implement operator<(). | |||
| Example: @code | |||
| Array <int> myArray; | |||
| IntegerElementComparator<int> sorter; | |||
| DefaultElementComparator<int> sorter; | |||
| myArray.sort (sorter); | |||
| @endcode | |||
| For floating point values, see the FloatElementComparator class instead. | |||
| @see FloatElementComparator, ElementComparator | |||
| @see ElementComparator | |||
| */ | |||
| template <class ElementType> | |||
| class IntegerElementComparator | |||
| class DefaultElementComparator | |||
| { | |||
| public: | |||
| static int compareElements (const ElementType first, | |||
| const ElementType second) throw() | |||
| { | |||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| /** | |||
| A simple ElementComparator class that can be used to sort an array of numeric | |||
| double or floating point primitive objects. | |||
| private: | |||
| typedef PARAMETER_TYPE (ElementType) ParameterType; | |||
| Example: @code | |||
| Array <double> myArray; | |||
| FloatElementComparator<double> sorter; | |||
| myArray.sort (sorter); | |||
| @endcode | |||
| For integer values, see the IntegerElementComparator class instead. | |||
| @see IntegerElementComparator, ElementComparator | |||
| */ | |||
| template <class ElementType> | |||
| class FloatElementComparator | |||
| { | |||
| public: | |||
| static int compareElements (const ElementType first, | |||
| const ElementType second) throw() | |||
| static int compareElements (ParameterType first, ParameterType second) | |||
| { | |||
| return (first < second) ? -1 : ((first == second) ? 0 : 1); | |||
| return (first < second) ? -1 : ((first < second) ? 1 : 0); | |||
| } | |||
| }; | |||
| #endif // __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ | |||
| @@ -199,9 +199,8 @@ public: | |||
| { | |||
| removeRange (firstValue, numValuesToAdd); | |||
| IntegerElementComparator<Type> sorter; | |||
| values.addSorted (sorter, firstValue); | |||
| values.addSorted (sorter, firstValue + numValuesToAdd); | |||
| values.addUsingDefaultSort (firstValue); | |||
| values.addUsingDefaultSort (firstValue + numValuesToAdd); | |||
| simplify(); | |||
| } | |||
| @@ -242,13 +241,11 @@ public: | |||
| } | |||
| } | |||
| IntegerElementComparator<Type> sorter; | |||
| if (onAtStart) | |||
| values.addSorted (sorter, firstValue); | |||
| values.addUsingDefaultSort (firstValue); | |||
| if (onAtEnd) | |||
| values.addSorted (sorter, lastValue); | |||
| values.addUsingDefaultSort (lastValue); | |||
| simplify(); | |||
| } | |||
| @@ -264,6 +264,7 @@ public: | |||
| @param newIndex the index at which you'd like this item to end up. If this | |||
| is less than zero, the value will be moved to the end | |||
| of the list | |||
| @param undoManager the optional UndoManager to use to store this transaction | |||
| */ | |||
| void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); | |||
| @@ -116,16 +116,17 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class ActiveXControlData; | |||
| friend class ActiveXControlData; | |||
| void* control; | |||
| class Pimpl; | |||
| friend class Pimpl; | |||
| friend class ScopedPointer <Pimpl>; | |||
| ScopedPointer <Pimpl> control; | |||
| bool mouseEventsAllowed; | |||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||
| void setControlBounds (const Rectangle<int>& bounds) const; | |||
| void setControlVisible (bool b) const; | |||
| ActiveXControlComponent (const ActiveXControlComponent&); | |||
| ActiveXControlComponent& operator= (const ActiveXControlComponent&); | |||
| }; | |||
| #endif | |||
| @@ -171,7 +171,6 @@ namespace ActiveXHelpers | |||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | |||
| { | |||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||
| *lplpFrame = frame; | |||
| *lplpDoc = 0; | |||
| lpFrameInfo->fMDIApp = FALSE; | |||
| @@ -292,7 +291,7 @@ namespace ActiveXHelpers | |||
| } | |||
| //============================================================================== | |||
| class ActiveXControlComponent::ActiveXControlData : public ComponentMovementWatcher | |||
| class ActiveXControlComponent::Pimpl : public ComponentMovementWatcher | |||
| { | |||
| ActiveXControlComponent* const owner; | |||
| bool wasShowing; | |||
| @@ -304,8 +303,7 @@ public: | |||
| IOleObject* control; | |||
| //============================================================================== | |||
| ActiveXControlData (HWND hwnd, | |||
| ActiveXControlComponent* const owner_) | |||
| Pimpl (HWND hwnd, ActiveXControlComponent* const owner_) | |||
| : ComponentMovementWatcher (owner_), | |||
| owner (owner_), | |||
| wasShowing (owner_ != 0 && owner_->isShowing()), | |||
| @@ -316,7 +314,7 @@ public: | |||
| { | |||
| } | |||
| ~ActiveXControlData() | |||
| ~Pimpl() | |||
| { | |||
| if (control != 0) | |||
| { | |||
| @@ -359,20 +357,15 @@ public: | |||
| componentPeerChanged(); | |||
| } | |||
| static bool doesWindowMatch (const ActiveXControlComponent* const ax, HWND hwnd) | |||
| { | |||
| return ((ActiveXControlData*) ax->control) != 0 | |||
| && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | |||
| } | |||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | |||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |||
| { | |||
| for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | |||
| { | |||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) ActiveXHelpers::activeXComps.getUnchecked(i); | |||
| const ActiveXControlComponent* const ax | |||
| = static_cast <const ActiveXControlComponent*> (ActiveXHelpers::activeXComps.getUnchecked(i)); | |||
| if (doesWindowMatch (ax, hwnd)) | |||
| if (ax->control != 0 && ax->control->controlHWND == hwnd) | |||
| { | |||
| switch (message) | |||
| { | |||
| @@ -404,7 +397,7 @@ public: | |||
| break; | |||
| } | |||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||
| return CallWindowProc ((WNDPROC) ax->originalWndProc, hwnd, message, wParam, lParam); | |||
| } | |||
| } | |||
| @@ -414,7 +407,6 @@ public: | |||
| ActiveXControlComponent::ActiveXControlComponent() | |||
| : originalWndProc (0), | |||
| control (0), | |||
| mouseEventsAllowed (true) | |||
| { | |||
| ActiveXHelpers::activeXComps.add (this); | |||
| @@ -445,16 +437,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| const Point<int> pos (relativePositionToOtherComponent (getTopLevelComponent(), Point<int>())); | |||
| HWND hwnd = (HWND) peer->getNativeHandle(); | |||
| ScopedPointer <ActiveXControlData> info (new ActiveXControlData (hwnd, this)); | |||
| ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, this)); | |||
| HRESULT hr; | |||
| if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, | |||
| info->clientSite, info->storage, | |||
| (void**) &(info->control))) == S_OK) | |||
| newControl->clientSite, newControl->storage, | |||
| (void**) &(newControl->control))) == S_OK) | |||
| { | |||
| info->control->SetHostNames (L"Juce", 0); | |||
| newControl->control->SetHostNames (L"Juce", 0); | |||
| if (OleSetContainedObject (info->control, TRUE) == S_OK) | |||
| if (OleSetContainedObject (newControl->control, TRUE) == S_OK) | |||
| { | |||
| RECT rect; | |||
| rect.left = pos.getX(); | |||
| @@ -462,17 +454,17 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| rect.right = pos.getX() + getWidth(); | |||
| rect.bottom = pos.getY() + getHeight(); | |||
| if (info->control->DoVerb (OLEIVERB_SHOW, 0, info->clientSite, 0, hwnd, &rect) == S_OK) | |||
| if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) | |||
| { | |||
| control = info.release(); | |||
| control = newControl; | |||
| setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | |||
| ((ActiveXControlData*) control)->controlHWND = ActiveXHelpers::getHWND (this); | |||
| control->controlHWND = ActiveXHelpers::getHWND (this); | |||
| if (((ActiveXControlData*) control)->controlHWND != 0) | |||
| if (control->controlHWND != 0) | |||
| { | |||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | |||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) ActiveXControlData::activeXHookWndProc); | |||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); | |||
| SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); | |||
| } | |||
| return true; | |||
| @@ -486,24 +478,16 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| void ActiveXControlComponent::deleteControl() | |||
| { | |||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||
| if (info != 0) | |||
| { | |||
| delete info; | |||
| control = 0; | |||
| originalWndProc = 0; | |||
| } | |||
| control = 0; | |||
| originalWndProc = 0; | |||
| } | |||
| void* ActiveXControlComponent::queryInterface (const void* iid) const | |||
| { | |||
| ActiveXControlData* const info = (ActiveXControlData*) control; | |||
| void* result = 0; | |||
| if (info != 0 && info->control != 0 | |||
| && info->control->QueryInterface (*(const IID*) iid, &result) == S_OK) | |||
| if (control != 0 && control->control != 0 | |||
| && SUCCEEDED (control->control->QueryInterface (*(const IID*) iid, &result))) | |||
| return result; | |||
| return 0; | |||
| @@ -511,18 +495,14 @@ void* ActiveXControlComponent::queryInterface (const void* iid) const | |||
| void ActiveXControlComponent::setControlBounds (const Rectangle<int>& newBounds) const | |||
| { | |||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||
| if (hwnd != 0) | |||
| MoveWindow (hwnd, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||
| if (control->controlHWND != 0) | |||
| MoveWindow (control->controlHWND, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); | |||
| } | |||
| void ActiveXControlComponent::setControlVisible (const bool shouldBeVisible) const | |||
| { | |||
| HWND hwnd = ((ActiveXControlData*) control)->controlHWND; | |||
| if (hwnd != 0) | |||
| ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||
| if (control->controlHWND != 0) | |||
| ShowWindow (control->controlHWND, shouldBeVisible ? SW_SHOWNA : SW_HIDE); | |||
| } | |||
| void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachControl) | |||
| @@ -155,8 +155,7 @@ public: | |||
| minBufferSize = wasapi_refTimeToSamples (minPeriod, defaultSampleRate); | |||
| defaultBufferSize = wasapi_refTimeToSamples (defaultPeriod, defaultSampleRate); | |||
| FloatElementComparator<double> comparator; | |||
| rates.addSorted (comparator, defaultSampleRate); | |||
| rates.addUsingDefaultSort (defaultSampleRate); | |||
| static const double ratesToTest[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | |||
| @@ -170,7 +169,7 @@ public: | |||
| if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, | |||
| (WAVEFORMATEX*) &format, 0))) | |||
| if (! rates.contains (ratesToTest[i])) | |||
| rates.addSorted (comparator, ratesToTest[i]); | |||
| rates.addUsingDefaultSort (ratesToTest[i]); | |||
| } | |||
| } | |||
| @@ -321,6 +320,9 @@ private: | |||
| return false; | |||
| } | |||
| WASAPIDeviceBase (const WASAPIDeviceBase&); | |||
| WASAPIDeviceBase& operator= (const WASAPIDeviceBase&); | |||
| }; | |||
| //============================================================================== | |||
| @@ -467,6 +469,10 @@ public: | |||
| ComSmartPtr <IAudioCaptureClient> captureClient; | |||
| MemoryBlock reservoir; | |||
| int reservoirSize, reservoirCapacity; | |||
| private: | |||
| WASAPIInputDevice (const WASAPIInputDevice&); | |||
| WASAPIInputDevice& operator= (const WASAPIInputDevice&); | |||
| }; | |||
| //============================================================================== | |||
| @@ -559,6 +565,10 @@ public: | |||
| } | |||
| ComSmartPtr <IAudioRenderClient> renderClient; | |||
| private: | |||
| WASAPIOutputDevice (const WASAPIOutputDevice&); | |||
| WASAPIOutputDevice& operator= (const WASAPIOutputDevice&); | |||
| }; | |||
| //============================================================================== | |||
| @@ -621,16 +631,15 @@ public: | |||
| sampleRates = d->rates; | |||
| } | |||
| IntegerElementComparator<int> comparator; | |||
| bufferSizes.addSorted (comparator, defaultBufferSize); | |||
| bufferSizes.addUsingDefaultSort (defaultBufferSize); | |||
| if (minBufferSize != defaultBufferSize) | |||
| bufferSizes.addSorted (comparator, minBufferSize); | |||
| bufferSizes.addUsingDefaultSort (minBufferSize); | |||
| int n = 64; | |||
| for (int i = 0; i < 40; ++i) | |||
| { | |||
| if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) | |||
| bufferSizes.addSorted (comparator, n); | |||
| bufferSizes.addUsingDefaultSort (n); | |||
| n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); | |||
| } | |||