| @@ -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<HiddenMessageWindow> messageWindow; | |||
| void dispatchMessageFromLParam (LPARAM lParam) | |||
| { | |||
| if (MessageManager::MessageBase* const message = reinterpret_cast<MessageManager::MessageBase*> (lParam)) | |||
| if (MessageManager::MessageBase* message = reinterpret_cast<MessageManager::MessageBase*> (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<Array<HWND>*> (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<String*> (lParam)) | |||
| { | |||
| const ScopedPointer<String> messageString (m); | |||
| MessageManager::getInstance()->deliverBroadcastMessage (*m); | |||
| } | |||
| return 0; | |||
| } | |||
| if (message == WM_COPYDATA) | |||
| { | |||
| if (const COPYDATASTRUCT* const data = reinterpret_cast<const COPYDATASTRUCT*> (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<const COPYDATASTRUCT*> (lParam)); | |||
| return 0; | |||
| } | |||
| } | |||
| return DefWindowProc (h, message, wParam, lParam); | |||
| } | |||
| BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) | |||
| { | |||
| if (hwnd != juce_messageWindowHandle) | |||
| reinterpret_cast<Array<HWND>*> (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<HWND> 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<HWND> 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); | |||
| } | |||
| } | |||