|
|
@@ -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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|