juce中的消息循环及其处理

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值