JUCE中的消息送和listener

来源:互联网 发布:犀牛5.0破解软件 编辑:程序博客网 时间:2024/05/21 20:23
    //==============================================================================    /**        Used to receive callbacks when a button is clicked.        @see Button::addListener, Button::removeListener    */    class JUCE_API  Listener    {    public:        /** Destructor. */        virtual ~Listener()  {}        /** Called when the button is clicked. */        virtual void buttonClicked (Button*) = 0;        /** Called when the button's state changes. */        virtual void buttonStateChanged (Button*)  {}    };

上边是button类中定义的listener.

listener由发送消息者去定义,同时维护了一个listener的表,当事件发生的时候,先把消息发送到控件本身进行处理,处理完后,循环调用listoner进行消息处理,呵呵,一直不明白java的那个listener,没想到在这里明白了,真扯啊

enum { clickMessageId = 0x2f3f4f99 };void Button::triggerClick(){    postCommandMessage (clickMessageId);}

发送自定义消息

void Component::postCommandMessage (const int commandId){    class CustomCommandMessage   : public CallbackMessage    {    public:        CustomCommandMessage (Component* const c, const int command)            : target (c), commandId (command) {}        void messageCallback() override        {            if (target.get() != nullptr)  // (get() required for VS2003 bug)                target->handleCommandMessage (commandId);        }    private:        WeakReference<Component> target;        int commandId;    };    (new CustomCommandMessage (this, commandId))->post();}


当收到消息以后button先自己处理此消息,调用如下函数

void Component::postCommandMessage (const int commandId){    class CustomCommandMessage   : public CallbackMessage    {    public:        CustomCommandMessage (Component* const c, const int command)            : target (c), commandId (command) {}        void messageCallback() override        {            if (target.get() != nullptr)  // (get() required for VS2003 bug)                target->handleCommandMessage (commandId);        }    private:        WeakReference<Component> target;        int commandId;    };    (new CustomCommandMessage (this, commandId))->post();}


接着调用handleCommandMessage,这里更新了button的状态

//重写了这个消息

void Button::handleCommandMessage (int commandId){    if (commandId == clickMessageId)    {        if (isEnabled())        {            flashButtonState();            internalClickCallback (ModifierKeys::getCurrentModifiers());        }    }    else    {        Component::handleCommandMessage (commandId);    }}


但是到这个地方还没有listener任何事情,接着往下看

void Button::internalClickCallback (const ModifierKeys& modifiers){    if (clickTogglesState)    {        const bool shouldBeOn = (radioGroupId != 0 || ! lastToggleState);        if (shouldBeOn != getToggleState())        {            setToggleState (shouldBeOn, sendNotification);            return;        }    }    sendClickMessage (modifiers);}


最后又调用了sendClickMessage

void Button::sendClickMessage (const ModifierKeys& modifiers){    Component::BailOutChecker checker (this);    if (commandManagerToUse != nullptr && commandID != 0)    {        ApplicationCommandTarget::InvocationInfo info (commandID);        info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromButton;        info.originatingComponent = this;        commandManagerToUse->invoke (info, true);    }    clicked (modifiers);    if (! checker.shouldBailOut())        buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this);  // (can't use Button::Listener due to idiotic VC2005 bug)}


到这里,listener终于闪登场

    /** Calls a member function on each listener in the list, with no parameters and a bail-out-checker.        See the class description for info about writing a bail-out checker. */    template <class BailOutCheckerType>    void callChecked (const BailOutCheckerType& bailOutChecker,                      void (ListenerClass::*callbackFunction) ())    {        for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)            (iter.getListener()->*callbackFunction) ();    }


此处,循环调用就不说了。 这里作个说明BailOutChecker的作用是防止消息处理过程中把button给删除了,后边的callback又使用到button这种情况,其实就是做个检查,这个在其它界面库中也遇到过这种情况。

0 0