Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

juce_win32_Messaging.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. extern HWND juce_messageWindowHandle;
  18. typedef bool (*CheckEventBlockedByModalComps) (const MSG&);
  19. CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr;
  20. //==============================================================================
  21. namespace WindowsMessageHelpers
  22. {
  23. const unsigned int specialId = WM_APP + 0x4400;
  24. const unsigned int broadcastId = WM_APP + 0x4403;
  25. const TCHAR messageWindowName[] = _T("JUCEWindow");
  26. ScopedPointer<HiddenMessageWindow> messageWindow;
  27. void dispatchMessageFromLParam (LPARAM lParam)
  28. {
  29. MessageManager::MessageBase* const message = reinterpret_cast <MessageManager::MessageBase*> (lParam);
  30. JUCE_TRY
  31. {
  32. message->messageCallback();
  33. }
  34. JUCE_CATCH_EXCEPTION
  35. message->decReferenceCount();
  36. }
  37. //==============================================================================
  38. LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept
  39. {
  40. if (h == juce_messageWindowHandle)
  41. {
  42. if (message == specialId)
  43. {
  44. // (These are trapped early in our dispatch loop, but must also be checked
  45. // here in case some 3rd-party code is running the dispatch loop).
  46. dispatchMessageFromLParam (lParam);
  47. return 0;
  48. }
  49. else if (message == broadcastId)
  50. {
  51. const ScopedPointer<String> messageString ((String*) lParam);
  52. MessageManager::getInstance()->deliverBroadcastMessage (*messageString);
  53. return 0;
  54. }
  55. else if (message == WM_COPYDATA)
  56. {
  57. const COPYDATASTRUCT* const data = reinterpret_cast <const COPYDATASTRUCT*> (lParam);
  58. if (data->dwData == broadcastId)
  59. {
  60. const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData),
  61. data->cbData / sizeof (CharPointer_UTF32::CharType));
  62. PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString));
  63. return 0;
  64. }
  65. }
  66. }
  67. return DefWindowProc (h, message, wParam, lParam);
  68. }
  69. BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam)
  70. {
  71. if (hwnd != juce_messageWindowHandle)
  72. reinterpret_cast <Array<HWND>*> (lParam)->add (hwnd);
  73. return TRUE;
  74. }
  75. }
  76. //==============================================================================
  77. bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
  78. {
  79. using namespace WindowsMessageHelpers;
  80. MSG m;
  81. if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, 0))
  82. return false;
  83. if (GetMessage (&m, (HWND) 0, 0, 0) >= 0)
  84. {
  85. if (m.message == specialId && m.hwnd == juce_messageWindowHandle)
  86. {
  87. dispatchMessageFromLParam (m.lParam);
  88. }
  89. else if (m.message == WM_QUIT)
  90. {
  91. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  92. app->systemRequestedQuit();
  93. }
  94. else if (isEventBlockedByModalComps == nullptr || ! isEventBlockedByModalComps (m))
  95. {
  96. if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN)
  97. && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd))
  98. {
  99. // if it's someone else's window being clicked on, and the focus is
  100. // currently on a juce window, pass the kb focus over..
  101. HWND currentFocus = GetFocus();
  102. if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus))
  103. SetFocus (m.hwnd);
  104. }
  105. TranslateMessage (&m);
  106. DispatchMessage (&m);
  107. }
  108. }
  109. return true;
  110. }
  111. bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
  112. {
  113. message->incReferenceCount();
  114. return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0;
  115. }
  116. void MessageManager::broadcastMessage (const String& value)
  117. {
  118. Array<HWND> windows;
  119. EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows);
  120. const String localCopy (value);
  121. COPYDATASTRUCT data;
  122. data.dwData = WindowsMessageHelpers::broadcastId;
  123. data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType);
  124. data.lpData = (void*) localCopy.toUTF32().getAddress();
  125. for (int i = windows.size(); --i >= 0;)
  126. {
  127. HWND hwnd = windows.getUnchecked(i);
  128. TCHAR windowName [64]; // no need to read longer strings than this
  129. GetWindowText (hwnd, windowName, 64);
  130. windowName [63] = 0;
  131. if (String (windowName) == WindowsMessageHelpers::messageWindowName)
  132. {
  133. DWORD_PTR result;
  134. SendMessageTimeout (hwnd, WM_COPYDATA,
  135. (WPARAM) juce_messageWindowHandle,
  136. (LPARAM) &data,
  137. SMTO_BLOCK | SMTO_ABORTIFHUNG, 8000, &result);
  138. }
  139. }
  140. }
  141. //==============================================================================
  142. void MessageManager::doPlatformSpecificInitialisation()
  143. {
  144. OleInitialize (0);
  145. using namespace WindowsMessageHelpers;
  146. messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) messageWndProc);
  147. juce_messageWindowHandle = messageWindow->getHWND();
  148. }
  149. void MessageManager::doPlatformSpecificShutdown()
  150. {
  151. WindowsMessageHelpers::messageWindow = nullptr;
  152. OleUninitialize();
  153. }