diff --git a/modules/juce_events/native/juce_win32_Messaging.cpp b/modules/juce_events/native/juce_win32_Messaging.cpp index 36621acb69..c8fb937eb5 100644 --- a/modules/juce_events/native/juce_win32_Messaging.cpp +++ b/modules/juce_events/native/juce_win32_Messaging.cpp @@ -30,15 +30,15 @@ CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; //============================================================================== namespace WindowsMessageHelpers { - const unsigned int specialId = WM_APP + 0x4400; - const unsigned int broadcastId = WM_APP + 0x4403; + const unsigned int customMessageID = WM_USER + 123; + const unsigned int broadcastMessageMagicNumber = 0xc403; const TCHAR messageWindowName[] = _T("JUCEWindow"); ScopedPointer messageWindow; void dispatchMessageFromLParam (LPARAM lParam) { - if (MessageManager::MessageBase* const message = reinterpret_cast (lParam)) + if (MessageManager::MessageBase* message = reinterpret_cast (lParam)) { JUCE_TRY { @@ -50,12 +50,44 @@ namespace WindowsMessageHelpers } } + BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) + { + if (hwnd != juce_messageWindowHandle) + { + TCHAR windowName[64] = { 0 }; // no need to read longer strings than this + GetWindowText (hwnd, windowName, 63); + + if (String (windowName) == messageWindowName) + reinterpret_cast*> (lParam)->add (hwnd); + } + + return TRUE; + } + + void handleBroadcastMessage (const COPYDATASTRUCT* const data) + { + if (data != nullptr && data->dwData == broadcastMessageMagicNumber) + { + struct BroadcastMessage : public CallbackMessage + { + BroadcastMessage (CharPointer_UTF32 text, size_t length) : message (text, length) {} + void messageCallback() override { MessageManager::getInstance()->deliverBroadcastMessage (message); } + + String message; + }; + + (new BroadcastMessage (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), + data->cbData / sizeof (CharPointer_UTF32::CharType))) + ->post(); + } + } + //============================================================================== LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept { if (h == juce_messageWindowHandle) { - if (message == specialId) + if (message == customMessageID) { // (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). @@ -63,43 +95,15 @@ namespace WindowsMessageHelpers return 0; } - if (message == broadcastId) - { - if (String* const m = reinterpret_cast (lParam)) - { - const ScopedPointer messageString (m); - MessageManager::getInstance()->deliverBroadcastMessage (*m); - } - - return 0; - } - if (message == WM_COPYDATA) { - if (const COPYDATASTRUCT* const data = reinterpret_cast (lParam)) - { - if (data->dwData == broadcastId) - { - 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; - } - } + handleBroadcastMessage (reinterpret_cast (lParam)); + return 0; } } return DefWindowProc (h, message, wParam, lParam); } - - BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) - { - if (hwnd != juce_messageWindowHandle) - reinterpret_cast*> (lParam)->add (hwnd); - - return TRUE; - } } //============================================================================== @@ -113,7 +117,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend if (GetMessage (&m, (HWND) 0, 0, 0) >= 0) { - if (m.message == specialId && m.hwnd == juce_messageWindowHandle) + if (m.message == customMessageID && m.hwnd == juce_messageWindowHandle) { dispatchMessageFromLParam (m.lParam); } @@ -146,36 +150,28 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { message->incReferenceCount(); - return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0; + return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::customMessageID, 0, (LPARAM) message) != 0; } void MessageManager::broadcastMessage (const String& value) { - Array windows; - EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); - const String localCopy (value); - COPYDATASTRUCT data; - data.dwData = WindowsMessageHelpers::broadcastId; - data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); - data.lpData = (void*) localCopy.toUTF32().getAddress(); + Array windows; + EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); for (int i = windows.size(); --i >= 0;) { - HWND hwnd = windows.getUnchecked(i); - - TCHAR windowName[64] = { 0 }; // no need to read longer strings than this - GetWindowText (hwnd, windowName, 63); - - if (String (windowName) == WindowsMessageHelpers::messageWindowName) - { - DWORD_PTR result; - SendMessageTimeout (hwnd, WM_COPYDATA, - (WPARAM) juce_messageWindowHandle, - (LPARAM) &data, - SMTO_BLOCK | SMTO_ABORTIFHUNG, 8000, &result); - } + COPYDATASTRUCT data; + data.dwData = WindowsMessageHelpers::broadcastMessageMagicNumber; + data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); + data.lpData = (void*) localCopy.toUTF32().getAddress(); + + DWORD_PTR result; + SendMessageTimeout (windows.getUnchecked(i), WM_COPYDATA, + (WPARAM) juce_messageWindowHandle, + (LPARAM) &data, + SMTO_BLOCK | SMTO_ABORTIFHUNG, 8000, &result); } }