diff --git a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp index 08a88fa526..ea7f9aab8c 100644 --- a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp @@ -53,7 +53,7 @@ void ActionBroadcaster::CallbackReceiver::handleMessage (const Message& message) ActionBroadcaster::ActionBroadcaster() { // are you trying to create this object before or after juce has been intialised?? - jassert (MessageManager::instance != nullptr); + jassert (MessageManager::getInstanceWithoutCreating() != nullptr); callback.owner = this; } @@ -61,7 +61,7 @@ ActionBroadcaster::ActionBroadcaster() ActionBroadcaster::~ActionBroadcaster() { // all event-based objects must be deleted BEFORE juce is shut down! - jassert (MessageManager::instance != nullptr); + jassert (MessageManager::getInstanceWithoutCreating() != nullptr); } void ActionBroadcaster::addActionListener (ActionListener* const listener) diff --git a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp index b71a68ecdb..90c3baf20a 100644 --- a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp @@ -26,7 +26,7 @@ ChangeBroadcaster::ChangeBroadcaster() noexcept { // are you trying to create this object before or after juce has been intialised?? - jassert (MessageManager::instance != nullptr); + jassert (MessageManager::getInstanceWithoutCreating() != nullptr); callback.owner = this; } @@ -34,7 +34,7 @@ ChangeBroadcaster::ChangeBroadcaster() noexcept ChangeBroadcaster::~ChangeBroadcaster() { // all event-based objects must be deleted BEFORE juce is shut down! - jassert (MessageManager::instance != nullptr); + jassert (MessageManager::getInstanceWithoutCreating() != nullptr); } void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) diff --git a/modules/juce_events/messages/juce_CallbackMessage.h b/modules/juce_events/messages/juce_CallbackMessage.h index 8390954445..bd77ea0dcd 100644 --- a/modules/juce_events/messages/juce_CallbackMessage.h +++ b/modules/juce_events/messages/juce_CallbackMessage.h @@ -26,33 +26,34 @@ #ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__ #define __JUCE_CALLBACKMESSAGE_JUCEHEADER__ -#include "juce_Message.h" +#include "juce_MessageManager.h" //============================================================================== /** - A message that calls a custom function when it gets delivered. + A message that invokes a callback method when it gets delivered. You can use this class to fire off actions that you want to be performed later on the message thread. - Unlike other Message objects, these don't get sent to a MessageListener, you - just call the post() method to send them, and when they arrive, your - messageCallback() method will automatically be invoked. + To use it, create a subclass of CallbackMessage which implements the messageCallback() + method, then call post() to dispatch it. The event thread will then invoke your + messageCallback() method later on, and will automatically delete the message object + afterwards. - Always create an instance of a CallbackMessage on the heap, as it will be + Always create a new instance of a CallbackMessage on the heap, as it will be deleted automatically after the message has been delivered. - @see MessageListener, MessageManager, ActionListener, ChangeListener + @see MessageManager, MessageListener, ActionListener, ChangeListener */ -class JUCE_API CallbackMessage : public Message +class JUCE_API CallbackMessage : public MessageManager::MessageBase { public: //============================================================================== - CallbackMessage() noexcept; + CallbackMessage() noexcept {} /** Destructor. */ - ~CallbackMessage(); + ~CallbackMessage() {} //============================================================================== /** Called when the message is delivered. @@ -65,17 +66,7 @@ public: */ virtual void messageCallback() = 0; - /** Instead of sending this message to a MessageListener, just call this method - to post it to the event queue. - - After you've called this, this object will belong to the MessageManager, - which will delete it later. So make sure you don't delete the object yourself, - call post() more than once, or call post() on a stack-based obect! - */ - void post(); - private: - //============================================================================== // Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. JUCE_DECLARE_NON_COPYABLE (CallbackMessage); diff --git a/modules/juce_events/messages/juce_Message.h b/modules/juce_events/messages/juce_Message.h index f680723bd5..0946f4ab2b 100644 --- a/modules/juce_events/messages/juce_Message.h +++ b/modules/juce_events/messages/juce_Message.h @@ -27,39 +27,35 @@ #define __JUCE_MESSAGE_JUCEHEADER__ class MessageListener; -class MessageManager; //============================================================================== -/** The base class for objects that can be delivered to a MessageListener. +/** The base class for objects that can be sent to a MessageListener. If you want to send a message that carries some kind of custom data, just create a subclass of Message with some appropriate member variables to hold your data. + Always create a new instance of a Message object on the heap, as it will be + deleted automatically after the message has been delivered. + @see MessageListener, MessageManager, ActionListener, ChangeListener */ -class JUCE_API Message : public ReferenceCountedObject +class JUCE_API Message : public MessageManager::MessageBase { public: //============================================================================== - /** Creates an uninitialised message. - - The class's variables will also be left uninitialised. - */ + /** Creates an uninitialised message. */ Message() noexcept; + ~Message(); - /** Destructor. */ - virtual ~Message(); - - /** A typedef for pointers to messages. */ - typedef ReferenceCountedObjectPtr Ptr; + typedef ReferenceCountedObjectPtr Ptr; //============================================================================== private: friend class MessageListener; - friend class MessageManager; - MessageListener* messageRecipient; + WeakReference recipient; + void messageCallback(); // Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. diff --git a/modules/juce_events/messages/juce_MessageListener.cpp b/modules/juce_events/messages/juce_MessageListener.cpp index 09400ba840..5c21e42ccf 100644 --- a/modules/juce_events/messages/juce_MessageListener.cpp +++ b/modules/juce_events/messages/juce_MessageListener.cpp @@ -23,33 +23,29 @@ ============================================================================== */ +Message::Message() noexcept {} +Message::~Message() {} + +void Message::messageCallback() +{ + MessageListener* const r = recipient; + if (r != nullptr) + r->handleMessage (*this); +} + MessageListener::MessageListener() noexcept { - // are you trying to create a messagelistener before or after juce has been intialised?? - jassert (MessageManager::instance != nullptr); - - if (MessageManager::instance != nullptr) - MessageManager::instance->messageListeners.add (this); + // Are you trying to create a messagelistener before or after juce has been intialised?? + jassert (MessageManager::getInstanceWithoutCreating() != nullptr); } MessageListener::~MessageListener() { - if (MessageManager::instance != nullptr) - MessageManager::instance->messageListeners.removeValue (this); + masterReference.clear(); } void MessageListener::postMessage (Message* const message) const { - message->messageRecipient = const_cast (this); - - if (MessageManager::instance == nullptr) - MessageManager::getInstance(); - - MessageManager::instance->postMessageToQueue (message); -} - -bool MessageListener::isValidMessageListener() const noexcept -{ - return MessageManager::instance != nullptr - && MessageManager::instance->messageListeners.contains (this); + message->recipient = const_cast (this); + message->post(); } diff --git a/modules/juce_events/messages/juce_MessageListener.h b/modules/juce_events/messages/juce_MessageListener.h index a88b4fbbce..abd1ae05c0 100644 --- a/modules/juce_events/messages/juce_MessageListener.h +++ b/modules/juce_events/messages/juce_MessageListener.h @@ -26,7 +26,7 @@ #ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ #define __JUCE_MESSAGELISTENER_JUCEHEADER__ -#include "juce_Message.h" +#include "juce_MessageManager.h" //============================================================================== @@ -37,19 +37,11 @@ */ class JUCE_API MessageListener { -protected: - //============================================================================== - /** Creates a MessageListener. */ - MessageListener() noexcept; - public: //============================================================================== - /** Destructor. + MessageListener() noexcept; - When a MessageListener is deleted, it removes itself from a global list - of registered listeners, so that the isValidMessageListener() method - will no longer return true. - */ + /** Destructor. */ virtual ~MessageListener(); //============================================================================== @@ -68,25 +60,15 @@ public: This method can be called safely by any thread. @param message the message object to send - this will be deleted - automatically by the message queue, so don't keep any - references to it after calling this method. + automatically by the message queue, so make sure it's + allocated on the heap, not the stack! @see handleMessage */ void postMessage (Message* message) const; - //============================================================================== - /** Checks whether this MessageListener has been deleted. - - Although not foolproof, this method is safe to call on dangling or null - pointers. A list of active MessageListeners is kept internally, so this - checks whether the object is on this list or not. - - Note that it's possible to get a false-positive here, if an object is - deleted and another is subsequently created that happens to be at the - exact same memory location, but I can't think of a good way of avoiding - this. - */ - bool isValidMessageListener() const noexcept; +private: + WeakReference::Master masterReference; + friend class WeakReference; }; diff --git a/modules/juce_events/messages/juce_MessageManager.cpp b/modules/juce_events/messages/juce_MessageManager.cpp index 51dd3b2fa9..77dac7363c 100644 --- a/modules/juce_events/messages/juce_MessageManager.cpp +++ b/modules/juce_events/messages/juce_MessageManager.cpp @@ -23,22 +23,7 @@ ============================================================================== */ -Message::Message() noexcept : messageRecipient (nullptr) {} -Message::~Message() {} - -//============================================================================== -CallbackMessage::CallbackMessage() noexcept {} -CallbackMessage::~CallbackMessage() {} - -void CallbackMessage::post() -{ - MessageManager* const mm = MessageManager::instance; - if (mm != nullptr) - mm->postMessageToQueue (this); -} - -//============================================================================== -class MessageManager::QuitMessage : public CallbackMessage +class MessageManager::QuitMessage : public MessageManager::MessageBase { public: QuitMessage() {} @@ -55,8 +40,6 @@ private: }; //============================================================================== -MessageManager* MessageManager::instance = nullptr; - MessageManager::MessageManager() noexcept : quitMessagePosted (false), quitMessageReceived (false), @@ -73,13 +56,12 @@ MessageManager::~MessageManager() noexcept doPlatformSpecificShutdown(); - // If you hit this assertion, then you've probably leaked some kind of MessageListener object.. - jassert (messageListeners.size() == 0); - jassert (instance == this); instance = nullptr; // do this last in case this instance is still needed by doPlatformSpecificShutdown() } +MessageManager* MessageManager::instance = nullptr; + MessageManager* MessageManager::getInstance() { if (instance == nullptr) @@ -91,37 +73,23 @@ MessageManager* MessageManager::getInstance() return instance; } +inline MessageManager* MessageManager::getInstanceWithoutCreating() noexcept +{ + return instance; +} + void MessageManager::deleteInstance() { deleteAndZero (instance); } -void MessageManager::postMessageToQueue (Message* const message) -{ - if (quitMessagePosted || ! postMessageToSystemQueue (message)) - Message::Ptr deleter (message); // (this will delete messages that were just created with a 0 ref count) -} - //============================================================================== -void MessageManager::deliverMessage (Message* const message) +void MessageManager::MessageBase::post() { - JUCE_TRY - { - MessageListener* const recipient = message->messageRecipient; + MessageManager* const mm = MessageManager::instance; - if (recipient == nullptr) - { - CallbackMessage* const callbackMessage = dynamic_cast (message); - - if (callbackMessage != nullptr) - callbackMessage->messageCallback(); - } - else if (messageListeners.contains (recipient)) - { - recipient->handleMessage (*message); - } - } - JUCE_CATCH_EXCEPTION + if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this)) + Ptr deleter (this); // (this will delete messages that were just created with a 0 ref count) } //============================================================================== @@ -166,7 +134,7 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) #endif //============================================================================== -class AsyncFunctionCallback : public CallbackMessage +class AsyncFunctionCallback : public MessageManager::MessageBase { public: AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param) @@ -258,10 +226,10 @@ bool MessageManager::currentThreadHasLockedMessageManager() const noexcept accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens in Cocoa). */ -class MessageManagerLock::BlockingMessage : public CallbackMessage +class MessageManagerLock::BlockingMessage : public MessageManager::MessageBase { public: - BlockingMessage() {} + BlockingMessage() noexcept {} void messageCallback() { diff --git a/modules/juce_events/messages/juce_MessageManager.h b/modules/juce_events/messages/juce_MessageManager.h index 3797905fce..2caaa5dbbb 100644 --- a/modules/juce_events/messages/juce_MessageManager.h +++ b/modules/juce_events/messages/juce_MessageManager.h @@ -26,7 +26,6 @@ #ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__ #define __JUCE_MESSAGEMANAGER_JUCEHEADER__ -#include "juce_CallbackMessage.h" class MessageManagerLock; class ThreadPoolJob; class ActionListener; @@ -40,9 +39,10 @@ typedef void* (MessageCallbackFunction) (void* userData); //============================================================================== -/** Delivers Message objects to MessageListeners, and handles the event-dispatch loop. +/** + This class is in charge of the application's event-dispatch loop. - @see Message, MessageListener, MessageManagerLock, JUCEApplication + @see Message, CallbackMessage, MessageManagerLock, JUCEApplication */ class JUCE_API MessageManager { @@ -51,6 +51,9 @@ public: /** Returns the global instance of the MessageManager. */ static MessageManager* getInstance(); + /** Returns the global instance of the MessageManager, or nullptr if it doesn't exist. */ + static MessageManager* getInstanceWithoutCreating() noexcept; + /** Deletes the global MessageManager instance. Does nothing if no instance had been created. */ @@ -156,10 +159,28 @@ public: /** Deregisters a broadcast listener. */ void deregisterBroadcastListener (ActionListener* listener); + //============================================================================== + /** Internal class used as the base class for all message objects. + You shouldn't need to use this directly - see the CallbackMessage or Message + classes instead. + */ + class JUCE_API MessageBase : public ReferenceCountedObject + { + public: + MessageBase() noexcept {} + virtual ~MessageBase() {} + + virtual void messageCallback() = 0; + void post(); + + typedef ReferenceCountedObjectPtr Ptr; + + JUCE_DECLARE_NON_COPYABLE (MessageBase); + }; + //============================================================================== #ifndef DOXYGEN // Internal methods - do not use! - void deliverMessage (Message*); void deliverBroadcastMessage (const String&); ~MessageManager() noexcept; #endif @@ -168,26 +189,20 @@ private: //============================================================================== MessageManager() noexcept; - friend class MessageListener; - friend class ChangeBroadcaster; - friend class ActionBroadcaster; - friend class CallbackMessage; static MessageManager* instance; - SortedSet messageListeners; - ScopedPointer broadcaster; - + friend class MessageBase; class QuitMessage; friend class QuitMessage; + friend class MessageManagerLock; + + ScopedPointer broadcaster; bool quitMessagePosted, quitMessageReceived; Thread::ThreadID messageThreadId; - - friend class MessageManagerLock; Thread::ThreadID volatile threadWithLock; CriticalSection lockingLock; - void postMessageToQueue (Message*); - static bool postMessageToSystemQueue (Message*); + static bool postMessageToSystemQueue (MessageBase*); static void* exitModalLoopCallback (void*); static void doPlatformSpecificInitialisation(); static void doPlatformSpecificShutdown(); diff --git a/modules/juce_events/native/juce_android_Messaging.cpp b/modules/juce_events/native/juce_android_Messaging.cpp index 523ab11546..6a5d44b949 100644 --- a/modules/juce_events/native/juce_android_Messaging.cpp +++ b/modules/juce_events/native/juce_android_Messaging.cpp @@ -36,7 +36,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend } //============================================================================== -bool MessageManager::postMessageToSystemQueue (Message* message) +bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { message->incReferenceCount(); getEnv()->CallVoidMethod (android.activity, JuceAppActivity.postMessage, (jlong) (pointer_sized_uint) message); @@ -45,9 +45,13 @@ bool MessageManager::postMessageToSystemQueue (Message* message) JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (jobject activity, jlong value)) { - Message* const message = (Message*) (pointer_sized_uint) value; - MessageManager::getInstance()->deliverMessage (message); - message->decReferenceCount(); + JUCE_TRY + { + MessageManager::MessageBase* const message = (MessageManager::MessageBase*) (pointer_sized_uint) value; + message->messageCallback(); + message->decReferenceCount(); + } + JUCE_CATCH_EXCEPTION } //============================================================================== diff --git a/modules/juce_events/native/juce_ios_MessageManager.mm b/modules/juce_events/native/juce_ios_MessageManager.mm index 2aa6f7bec5..a6476aba98 100644 --- a/modules/juce_events/native/juce_ios_MessageManager.mm +++ b/modules/juce_events/native/juce_ios_MessageManager.mm @@ -58,45 +58,27 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) } //============================================================================== -struct MessageDispatchSystem -{ - MessageDispatchSystem() - : juceCustomMessageHandler (nil) - { - juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init]; - } - - ~MessageDispatchSystem() - { - [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler]; - [juceCustomMessageHandler release]; - } - - JuceCustomMessageHandler* juceCustomMessageHandler; - MessageQueue messageQueue; -}; - -static ScopedPointer dispatcher; +static ScopedPointer messageQueue; void MessageManager::doPlatformSpecificInitialisation() { - if (dispatcher == nullptr) - dispatcher = new MessageDispatchSystem(); + if (messageQueue == nullptr) + messageQueue = new MessageQueue(); } void MessageManager::doPlatformSpecificShutdown() { - dispatcher = nullptr; + messageQueue = nullptr; } -bool MessageManager::postMessageToSystemQueue (Message* message) +bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { - if (dispatcher != nullptr) - dispatcher->messageQueue.post (message); + if (messageQueue != nullptr) + messageQueue->post (message); return true; } -void MessageManager::broadcastMessage (const String& value) +void MessageManager::broadcastMessage (const String&) { } diff --git a/modules/juce_events/native/juce_linux_Messaging.cpp b/modules/juce_events/native/juce_linux_Messaging.cpp index f369dba00f..3e65f10625 100644 --- a/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/modules/juce_events/native/juce_linux_Messaging.cpp @@ -59,7 +59,7 @@ public: } //============================================================================== - void postMessage (Message* msg) + void postMessage (MessageManager::MessageBase* const msg) { const int maxBytesInSocketQueue = 128; @@ -133,7 +133,7 @@ public: private: CriticalSection lock; - ReferenceCountedArray queue; + ReferenceCountedArray queue; int fd[2]; int bytesInSocket; int totalEventCount; @@ -173,7 +173,7 @@ private: return true; } - Message::Ptr popNextMessage() + MessageManager::MessageBase::Ptr popNextMessage() { const ScopedLock sl (lock); @@ -192,12 +192,17 @@ private: bool dispatchNextInternalMessage() { - const Message::Ptr msg (popNextMessage()); + const MessageManager::MessageBase::Ptr msg (popNextMessage()); if (msg == nullptr) return false; - MessageManager::getInstance()->deliverMessage (msg); + JUCE_TRY + { + msg->messageCallback(); + } + JUCE_CATCH_EXCEPTION + return true; } }; @@ -346,7 +351,7 @@ void MessageManager::doPlatformSpecificShutdown() } } -bool MessageManager::postMessageToSystemQueue (Message* message) +bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { if (LinuxErrorHandling::errorOccurred) return false; diff --git a/modules/juce_events/native/juce_mac_MessageManager.mm b/modules/juce_events/native/juce_mac_MessageManager.mm index 1803315350..89dceed735 100644 --- a/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/modules/juce_events/native/juce_mac_MessageManager.mm @@ -96,7 +96,7 @@ public: delete this; } - void postMessage (Message* const m) + void postMessage (MessageManager::MessageBase* const m) { messageQueue.post (m); } @@ -360,7 +360,7 @@ void MessageManager::doPlatformSpecificShutdown() } } -bool MessageManager::postMessageToSystemQueue (Message* message) +bool MessageManager::postMessageToSystemQueue (MessageBase* message) { juceAppDelegate->redirector->postMessage (message); return true; diff --git a/modules/juce_events/native/juce_osx_MessageQueue.h b/modules/juce_events/native/juce_osx_MessageQueue.h index fdc8b9642e..d478424d96 100644 --- a/modules/juce_events/native/juce_osx_MessageQueue.h +++ b/modules/juce_events/native/juce_osx_MessageQueue.h @@ -53,7 +53,7 @@ public: CFRelease (runLoopSource); } - void post (Message* const message) + void post (MessageManager::MessageBase* const message) { messages.add (message); CFRunLoopSourceSignal (runLoopSource); @@ -61,20 +61,26 @@ public: } private: - ReferenceCountedArray messages; + ReferenceCountedArray messages; CriticalSection lock; CFRunLoopRef runLoop; CFRunLoopSourceRef runLoopSource; bool deliverNextMessage() { - const Message::Ptr nextMessage (messages.removeAndReturn (0)); + const MessageManager::MessageBase::Ptr nextMessage (messages.removeAndReturn (0)); if (nextMessage == nullptr) return false; JUCE_AUTORELEASEPOOL - MessageManager::getInstance()->deliverMessage (nextMessage); + + JUCE_TRY + { + nextMessage->messageCallback(); + } + JUCE_CATCH_EXCEPTION + return true; } diff --git a/modules/juce_events/native/juce_win32_Messaging.cpp b/modules/juce_events/native/juce_win32_Messaging.cpp index d55f8afaaf..2e8ecb73b0 100644 --- a/modules/juce_events/native/juce_win32_Messaging.cpp +++ b/modules/juce_events/native/juce_win32_Messaging.cpp @@ -31,40 +31,49 @@ CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; //============================================================================== namespace WindowsMessageHelpers { - const unsigned int specialId = WM_APP + 0x4400; - const unsigned int broadcastId = WM_APP + 0x4403; + const unsigned int specialId = WM_APP + 0x4400; + const unsigned int broadcastId = WM_APP + 0x4403; const TCHAR messageWindowName[] = _T("JUCEWindow"); ScopedPointer messageWindow; + void dispatchMessageFromLParam (LPARAM lParam) + { + MessageManager::MessageBase* const message = reinterpret_cast (lParam); + + JUCE_TRY + { + message->messageCallback(); + } + JUCE_CATCH_EXCEPTION + + message->decReferenceCount(); + } + //============================================================================== LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept { - JUCE_TRY + if (h == juce_messageWindowHandle) { - if (h == juce_messageWindowHandle) + if (message == specialId) { - 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 + // (These are trapped early in our dispatch loop, but must also be checked + // here in case some 3rd-party code is running the dispatch loop). + dispatchMessageFromLParam (lParam); + return 0; + } + else if (message == broadcastId) + { + const ScopedPointer messageString ((String*) lParam); + MessageManager::getInstance()->deliverBroadcastMessage (*messageString); + return 0; + } + else if (message == WM_COPYDATA) + { + const COPYDATASTRUCT* const data = reinterpret_cast (lParam); - Message* const message = reinterpret_cast (lParam); - MessageManager::getInstance()->deliverMessage (message); - message->decReferenceCount(); - return 0; - } - else if (message == broadcastId) + if (data->dwData == 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)); @@ -73,7 +82,6 @@ namespace WindowsMessageHelpers } } } - JUCE_CATCH_EXCEPTION return DefWindowProc (h, message, wParam, lParam); } @@ -100,19 +108,18 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend { if (m.message == specialId && m.hwnd == juce_messageWindowHandle) { - Message* const message = reinterpret_cast (m.lParam); - MessageManager::getInstance()->deliverMessage (message); - message->decReferenceCount(); + dispatchMessageFromLParam (m.lParam); } else if (m.message == WM_QUIT) { - if (JUCEApplicationBase::getInstance() != nullptr) - JUCEApplicationBase::getInstance()->systemRequestedQuit(); + JUCEApplicationBase* const app = JUCEApplicationBase::getInstance(); + if (app != nullptr) + app->systemRequestedQuit(); } else if (isEventBlockedByModalComps == nullptr || ! isEventBlockedByModalComps (m)) { if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN) - && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd)) + && ! 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.. @@ -130,7 +137,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend return true; } -bool MessageManager::postMessageToSystemQueue (Message* message) +bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { message->incReferenceCount(); return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0;