juce中的消息循环及其处理

来源:互联网 发布:手机淘宝修改收货地址 编辑:程序博客网 时间:2024/06/15 08:17

START_JUCE_APPLICATION (PluginHostApp) 展开这个宏

#ifdef DOXYGEN #define START_JUCE_APPLICATION(AppClass)#elif JUCE_ANDROID #define START_JUCE_APPLICATION(AppClass) \   juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); }#else #if JUCE_WINDOWS && ! defined (_CONSOLE)  #define JUCE_MAIN_FUNCTION       int __stdcall WinMain (struct HINSTANCE__*, struct HINSTANCE__*, char*, int)  #define JUCE_MAIN_FUNCTION_ARGS #else  #define JUCE_MAIN_FUNCTION       int main (int argc, char* argv[])  #define JUCE_MAIN_FUNCTION_ARGS  argc, (const char**) argv #endif #define START_JUCE_APPLICATION(AppClass) \    static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \    extern "C" JUCE_MAIN_FUNCTION \    { \        juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \        return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \    }#endif

可以看到调用了main函数,同里还可以看到这里创建了应用程序的实例的创建函数指针,这个指针将在main函数中被调用
juce::JUCEApplicationBase::createInstance

这时一直找到了main函数
  1. int JUCEApplicationBase::main()
  2. {
  3. ScopedJuceInitialiser_GUI libraryInitialiser;
  4. jassert (createInstance != nullptr);
  5. const ScopedPointer<JUCEApplicationBase> app (createInstance());
  6. jassert (app != nullptr);
  7. if (! app->initialiseApp())
  8. return 0;
  9. JUCE_TRY
  10. {
  11. // loop until a quit message is received..
  12. MessageManager::getInstance()->runDispatchLoop();
  13. }
  14. JUCE_CATCH_EXCEPTION
  15. return app->shutdownApp();
  16. }
调用消息循环,同时这个地方还调用了app的初始化函数,这是个虚函数
  1. void MessageManager::runDispatchLoop()
  2. {
  3. runDispatchLoopUntil (-1);
  4. }
进入循环
  1. bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
  2. {
  3. jassert (isThisTheMessageThread()); // must only be called by the message thread
  4. const int64 endTime = Time::currentTimeMillis() + millisecondsToRunFor;
  5. while (! quitMessageReceived)
  6. {
  7. JUCE_TRY
  8. {
  9. if (! dispatchNextMessageOnSystemQueue (millisecondsToRunFor >= 0))
  10. Thread::sleep (1);
  11. }
  12. JUCE_CATCH_EXCEPTION
  13. if (millisecondsToRunFor >= 0 && Time::currentTimeMillis() >= endTime)
  14. break;
  15. }
  16. return ! quitMessageReceived;
  17. }

  1. //==============================================================================
  2. bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
  3. {
  4. using namespace WindowsMessageHelpers;
  5. MSG m;
  6. if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, PM_NOREMOVE))
  7. return false;
  8. if (GetMessage (&m, (HWND) 0, 0, 0) >= 0)
  9. {
  10. if (m.message == specialId && m.hwnd == juce_messageWindowHandle)
  11. {
  12. dispatchMessageFromLParam (m.lParam);
  13. }
  14. else if (m.message == WM_QUIT)
  15. {
  16. if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
  17. app->systemRequestedQuit();
  18. }
  19. else if (isEventBlockedByModalComps == nullptr || ! isEventBlockedByModalComps (m))
  20. {
  21. if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN)
  22. && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd))
  23. {
  24. // if it's someone else's window being clicked on, and the focus is
  25. // currently on a juce window, pass the kb focus over..
  26. HWND currentFocus = GetFocus();
  27. if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus))
  28. SetFocus (m.hwnd);
  29. }
  30. TranslateMessage (&m);
  31. DispatchMessage (&m);
  32. }
  33. }
  34. return true;
  35. }
这个边的代码看! PeekMessage (&m, (HWND) 0, 0, 0, PM_NOREMOVE) 这个用来检查是否有消息,然后使用GetMessage(&m,(HWND)0,0,0) 来取出消息
这里的specialId 是发送消息的时候设置的。
  1. const unsigned int specialId = WM_APP + 0x4400;
  2. const unsigned int broadcastId = WM_APP + 0x4403;
同时,这里还处理了
  1. if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN)
  2. && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd))
  3. {
  4. // if it's someone else's window being clicked on, and the focus is
  5. // currently on a juce window, pass the kb focus over..
  6. HWND currentFocus = GetFocus();
  7. if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus))
  8. SetFocus (m.hwnd);
  9. }
接边接着看两个分支语句是如何去处理的
  1. void dispatchMessageFromLParam (LPARAM lParam)
  2. {
  3. MessageManager::MessageBase* const message = reinterpret_cast <MessageManager::MessageBase*> (lParam);
  4. JUCE_TRY
  5. {
  6. message->messageCallback();
  7. }
  8. JUCE_CATCH_EXCEPTION
  9. message->decReferenceCount();
  10. }
message->decReferenceCount(); 如果计数为零的话则销毁消息


特别说明,在app的初始中进行了一系列的初始化操作,包括创口的创建等,具体可以参见juce的示例代码,窗口的具体创建过程请参见后续文章。

 void initialise (const String& commandLine)    {        // initialise our settings file..        PropertiesFile::Options options;        options.applicationName     = "Juce Audio Plugin Host";        options.filenameSuffix      = "settings";        options.osxLibrarySubFolder = "Preferences";        appProperties = new ApplicationProperties();        appProperties->setStorageParameters (options);        LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);        mainWindow = new MainHostWindow();        mainWindow->setUsingNativeTitleBar (true);        commandManager.registerAllCommandsForTarget (this);        commandManager.registerAllCommandsForTarget (mainWindow);        mainWindow->menuItemsChanged();        if (commandLine.isNotEmpty()             && ! commandLine.trimStart().startsWith ("-")             && mainWindow->getGraphEditor() != nullptr)            mainWindow->getGraphEditor()->graph.loadFrom (File::getCurrentWorkingDirectory()                                                            .getChildFile (commandLine), true);    }

说明:分析不一定正确,仅供参考。

juce群号:68016614

0 0
原创粉丝点击