PrevNextUpHome BREW C++ Class Library & GUI Framework & XML Middleware : SophiaFramework 4.1

9.2. Event Handler

The events such as application start and stop, suspension, restart, or key input are notified to the appropriate responder by the Tracer.

Then, each event will be automatically processed by the function called Event Handler.

Related Information: Tracer

9.2.1. Declaring an Event Handler

An event handler is declared by using the macro of which name starts with HANDLER_DECLARE_.

The handler name is passed as argument.

Related Information: GUI Framework Macros: Macros for Declaring Event Handler

Table 9.3. Macros for Declaring Event Handler (Void type)

Macro Description
HANDLER_DECLARE_VOIDRENDER Drawing handler
HANDLER_DECLARE_VOIDSTART Application start handler
HANDLER_DECLARE_VOIDSTOP Application stop handler
HANDLER_DECLARE_VOIDRESUME Resume handler
HANDLER_DECLARE_VOIDSUSPEND Suspend handler
HANDLER_DECLARE_VOIDDIALOG Dialog handler
HANDLER_DECLARE_VOIDMENU Menu handler
HANDLER_DECLARE_VOIDCONTROL Control handler
HANDLER_DECLARE_VOIDVOID Generic handler
HANDLER_DECLARE_VOIDEVENT Generic handler

Example 9.4. Declare the drawing handler

// define MyWindow class
SFMTYPEDEFCLASS(MyWindow)
class MyWindow : public SFRTitleWindow {
    SFMSEALCOPY(MyWindow)
public:
    MyWindow(Void) static_throws;
    virtual ~MyWindow(Void)
    
    // declare drawing handler
    // handler name is passed as argument
    HANDLER_DECLARE_VOIDRENDER(OnRenderContent)
};

Table 9.4. Macros for Declaring an Event Handler (Bool type)

Macro Description
HANDLER_DECLARE_BOOLSTART Application start handler
HANDLER_DECLARE_BOOLSTOP Application stop handler
HANDLER_DECLARE_BOOLRESUME Resume handler
HANDLER_DECLARE_BOOLSUSPEND Suspend handler
HANDLER_DECLARE_BOOLDIALOG Dialog handler
HANDLER_DECLARE_BOOLMENU Menu handler
HANDLER_DECLARE_BOOLCONTROL Control handler
HANDLER_DECLARE_BOOLVOID Generic handler
HANDLER_DECLARE_BOOLEVENT Generic handler

Example 9.5. Declare the key handler

// define MyWindow class
SFMTYPEDEFCLASS(MyWindow)
class MyWindow : public SFRTitleWindow {
    SFMSEALCOPY(MyWindow)
public:
    MyWindow(Void) static_throws;
    virtual ~MyWindow(Void)
    
    // declare key handler
    // handler name is passed as argument
    HANDLER_DECLARE_BOOLEVENT(OnKey)
};
[Note] By Using the Handler Declaring Macro...

the pointer to the handler function and the identification number (reference value) are generated.

9.2.2. Implementing an Event Handler

An event handler is implemented by using the macro of which name starts with HANDLER_IMPLEMENT_.

1st argument: the class it belongs to, 2nd argument: handler name, 3rd argument: varies according to the handler.

Related Information: GUI Framework Macros: Macros for implementing Event Handler

Table 9.5. Macros for Implementing an Event Handler (Void type)

Macro Description 1st argument 2nd argument 3rd argument
HANDLER_IMPLEMENT_VOIDRENDER Drawing handler graphics (graphic object) none none
HANDLER_IMPLEMENT_VOIDSTART Application start handler environment none none
HANDLER_IMPLEMENT_VOIDSTOP Application stop handler quitable none none
HANDLER_IMPLEMENT_VOIDRESUME Resume handler environment none none
HANDLER_IMPLEMENT_VOIDSUSPEND Suspend handler reason info none
HANDLER_IMPLEMENT_VOIDDIALOG Dialog handler result dialog (pointer to dialog) none
HANDLER_IMPLEMENT_VOIDMENU Menu handler result menu (pointer to menu) none
HANDLER_IMPLEMENT_VOIDCONTROL Control handler result control (pointer to control) none
HANDLER_IMPLEMENT_VOIDVOID Generic handler none none none
HANDLER_IMPLEMENT_VOIDEVENT Generic handler event (event object) none none

Example 9.6. Implement the drawing handler

// 1st argument: class it belongs to, 2nd argument: handler name, 3rd argument: graphic object
HANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderContent, graphics)
{
    // draw "Hello World"
    graphics->DrawText("Hello World", GetContentWorld());
    return;
}

Table 9.6. Macros for Implementing an Event Handler (Bool type)

Macro Description 1st argument 2nd argument 3rd argument
HANDLER_IMPLEMENT_BOOLSTART Application start environment none none
HANDLER_IMPLEMENT_BOOLSTOP Application stop quitable none none
HANDLER_IMPLEMENT_BOOLRESUME Resume handler environment none none
HANDLER_IMPLEMENT_BOOLSUSPEND suspend handler reason info none
HANDLER_IMPLEMENT_BOOLDIALOG Dialog handler result dialog (pointer to dialog) none
HANDLER_IMPLEMENT_BOOLMENU Menu handler result menu (pointer to menu) none
HANDLER_IMPLEMENT_BOOLCONTROL Control handler result control (pointer to control) none
HANDLER_IMPLEMENT_BOOLVOID Generic handler none none none
HANDLER_IMPLEMENT_BOOLEVENT Generic handler event (event object) none none

Example 9.7. Implement the key handler

// a key is pressed on topmost window.
// 1st argument: class it belongs to, 2nd argument: handler name, 3rd argument: event value
HANDLER_IMPLEMENT_BOOLEVENT(MyWindow, OnKey, event)
{
    // processing according to type of pressed key.
    switch (event.GetP16()) {
        case AVK_CLR: // if "Clear" key has been pressed
           // close window
            return Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE,
                                   SRP16_TERMINATE_INVOKE, true));

        case AVK_1:   // if "1" key has been pressed

            ...

            return true;  // if pressed key was processed, return true
    }
    return false;         // if pressed key was not processed, return false
}

9.2.3. Registering an Event Handler

An handler is registered by using the RegisterHandler function, and canceled by using the UnregisterHandler function.

If more than one handler functions are registered with the same event, only one handler function registered lastly is effective.

Setting information necessary when registering an event handler

  1. The event type and the first parameter: same as BREW event
  2. Timing for event handling: whether the event will be handled before(HANDLER_BEFORE) or after(HANDLER_AFTER) dispatching it to the Child Responders

Figure 9.1. Event Flow

Event Flow

Table 9.7. Timing for event handling

Processing the Event Description
HANDLER_BEFORE Handle the event at the Parent Responder, and then dispatch and handle it at the Child Responder.
HANDLER_AFTER Dispatch and handle the event at the Child Responder, and then handle it at the Parent Responder.
[Note] Timing for event handling

When drawing the Responders(UI components), it is necessary to draw them sequentially and recursively from backmost (Parant Responder) to foreground (Child Responders). Therefore, HANDLER_BEFORE is specified as the timing for event handling in registering the drawing handler.

As for the key handler, HANDLER_AFTER is specified since the key event need to be handled from topmost (Child Responder) to background (Parant Responder).

Since there is order relation between Parent and Child Responders regarding their construction and destruction, HANDLER_BEFORE and HANDLER_AFTER are specified when registering the handlers for the resume and suspend events respectively. Also as for the start and end events of application, HANDLER_BEFORE and HANDLER_AFTER are specified respectively for the same reason.

Example 9.8. Handler Types

Bool (*SFRResponderSPP) (SFXEventConstRef event, VoidPtr reference);

Example 9.9. Register the handler that is processed before dispatching the event to the child Responder

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SREVT_CONTROL, 
                                   HANDLER_BEFORE, 
                                   HANDLER_FUNCTION(OnControl));

Example 9.10. Register the handler that is processed after dispatching the event to the child Responder and receiving it from the child Responder

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SFEVT_KEY, 
                                   SFEVT_KEY_RELEASE, 
                                   AVK_SELECT, 
                                   HANDLER_AFTER, 
                                   HANDLER_FUNCTION(OnKey));
[Note] Role of HANDLER_FUNCTION

By making the argument of HANDLER_DECLARE_????? macro be that of HANDLER_FUNCTION macro, the pointer to the handler function and the handler identification number (reference value) are passed to the RegisterHandler function.

The code below describes how to make the key event handler be handled with doing nothing.

Example 9.11. Make the key handler as if it were handled with doing nothing

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SFEVT_KEY, 
                                   SFEVT_KEY_RELEASE, 
                                   HANDLER_BEFORE, 
                                   HANDLER_NULL);
[Warning] Warning
The Tracer setting also has the influence on whether this key event handler will be handled or not.

The handler registered lastly is effective. The behaviors of the following two codes are different.

Example 9.12. Register the key handlers (1)

SFRResponderPtr responder;

responder->RegisterHandler(SFEVT_KEY, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnKey));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld1));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld2));

Example 9.13. Register the key handlers (2)

SFRResponderPtr responder;

responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld1));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld2));
responder->RegisterHandler(SFEVT_KEY, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnKey));