[Home] [Prev] [Next] [Up]


YAAF_core: Event Management

Events are a big thing in any application framework.

YAAF provides three mechanisms for passing messages and events through parts of the system. The first is through dispatching to a hierarchy of event handler objects. The second is through globally broadcasting the message to all listeners interested. And the third is through a send/receive dispatch.

Dispatching Messages

This is conceptually the most difficult event mechanism. And it's the most often used.

Basically it works like this. Objects interested in receiving dispatched events are declared as children of the XGDispatch object. The XGDispatch objects in an application roughly corrispond to the objects on the display: both XGView and XGWindows are XGDispatch objects, as well as the application core.

These objects are arranged in a hierarchical tree:

MyApplication
  |
  +-----MyWindow
  |       |
  |       +-----MyView
  |       |       |
  |       |       +-----MyControl
  |       |
  |       +-----MyView
  |
  +-----MyWindow
          |
          +-----MyView
          |
          +-----MyView

Each of these objects are an XGDispatch object.

Now when a message is sent, it's sent to the current focus. The focus is the leaf object which currently is accepting keyboard and mouse input:

MyApplication
  |
  +-----MyWindow
  |       |
  |       +-----MyView
  |       |       |
  |       |       +-----(MyControl) <-- focus
  |       |
  |       +-----MyView
  |
  +-----MyWindow
          |
          +-----MyView
          |
          +-----MyView

If the message is not processed by the MyControl class, it is passed to the parent (MyView), and upwards until the message is either processed, or the message is ignored. In the latter case, the message returns the result 'zero'.

Messages may be sent to classes which are not the focus under certain circumstances. For example, if the control MyControl is clicked, it may send a 'clicked' message to the parent of that control.

Now, complicating this is the fact that there can be multiple 'focus' points. While there is only one actual focus, each window can have a different focus associated with it; when that window comes forward, the focus transfers to that focus point.

To facilitate this, the XGFocus object maintains a pointer to a focus. It is the responsibility of the XApplication object to return a pointer to the current XGFocus object--for a multi-window application, this would be a pointer to the XGFocus object associated with the front window.

Thus, our diagram would be:

[MyApplication]
  |
  +-----[MyWindow] <-- current XGFocus object
  |       |
  |       +-----MyView
  |       |       |
  |       |       +-----(MyControl)  <-- current focus
  |       |
  |       +-----MyView
  |
  +-----[MyWindow]
          |
          +-----MyView
          |
          +-----(MyView)

Classes shown in brackets are descendant of the XGFocus object; objects in parentesis are the current focus in the context of the owner's XGFocus object.

Note that messages from controls are sent to the parent view that owns that control; this is different from PowerPlant, which uses a complex system of send/receive messages to send the control message to the right place.

The difference, of course, means that a view that owns a series of controls needs to be customized to figure out how to dispatch those messages.

Broadcast Messages and Send/Receive Messages

Conceptually these are similar. The difference is that a broadcasted message is send globally to all created XGBroadcast messages, while the XGSend class only sends to those XGReceive classes attached to it.

Dispatch Classes

XGDispatch

The receiver of dispatched messages

XGFocus

This is the object which maintains the focus information as described above. This class is internal to YAAF.

Broadcast/Receive

XGBroadcast

This class receives broadcasted messages

XGSend

This class sends messages to registered XGReceive classes

XGReceive

This class receives messages from XGSend classes.

Predefined Messages

There are several predefined messages which are defined in the YAAF framework. Those messages losely are:

KEventPrePeriodic, KEventPostPeriodic

These events are broadcast just before and just after processing an even tin the event loop.

KEventAppActivate, KEventAppDeactivate

These messages are broadcast when the application is activated or deactivated

KEventIdle

This event is dispatched just before the event loop is processed, to allow insertion point blinking.

KEventDoMenuCommand, KEventGetMenuStatus

Menu management events dispached to handle the menu bar

KEventKey

This message is dispatched when a key is pressed

KEventWindowName, KEventWindowCreate, KEventWindowPreDestroy, KEventWindowDestroy

These messages are sent by a window being created or destroyed; normally these are processed by the XGApplication class and the XGDocument class to keep track of the associated windows.

KEventDialogMessage

These messages are sent by a dialog box being created or destroyed.

KEventWInternal

This is a Microsoft Win32 API specific message used for internal processing of Win32 messages.

Periodic messages

KEventPrePeriodic

(Broadcast) Sent just before handling the event in the event loop.

 arg  ignored; set to 0
 parg  ignored; set to 0

KEventPostPeriodic

(Broadcast) Sent just after handling the event in the event loop.

 arg  ignored; set to 0
 parg  ignored; set to 0

Application activation/deactivation

KEventAppActivate

(Broadcast) Sent when the application is activated.

 arg  ignored; set to 0
 parg  ignored; set to 0

KEventAppDeactivate

(Broadcast) Sent when the application is deactivated.

 arg  ignored; set to 0
 parg  ignored; set to 0

Idle Events

KEventIdle

(Dispatched) This message is sent periodically, just before the event loop is processed. This gives the view the opportunity to blink the keyboard insertion point.

 arg  ignored; set to 0
 parg  ignored; set to 0

Menu Processing

KEventDoMenuCommand

(Dispatch) Sent to the focus when the menu is selected. This gives the view or the view hierarchy the chance to execute this command.

 arg The menu command ID
 parg  ignored; set to 0

KEventGetMenuStatus

(Dispatch) Sent when the application queries the status of the command. This gives the application the chance to indicate if a command should be enabled, checked, or the symbol to use to check that command (Macintosh only).

 arg The menu command ID
 parg

Pointer to the structure XGSMenuStatusRecord:

  struct XGSMenuStatusRecord {
      bool enable;
      bool checked;
      char checkchar;
  };

The enable field is set if the menu should be enabled. The checked field should be set if the menu item should be checked. And the checkchar field should be set to the character to check the menu with, if not the default (which is a checkmark).

Keyboard Events

KEventAppActivate

(Dispatch) Sent when the application is activated.

 arg

GETLOWORD(arg) contains the character code of the character pressed.

GETHIWORD(arg) contains the modifier flags for the character when it was pressed.

 parg  ignored; set to 0

Note: The flags in the high word of the argument field is a bit-wise OR of the following flags:

KKeyShift Shift key pressed
KKeyControl Control key pressed
KKeyCommand (Mac) Apple key pressed
KKeyOption (Mac) Option key pressed
KKeyMenu (Windows) Alt key pressed
KKeyButton Mouse button pressed
KKeyRButton (Windows) Right button pressed
KKeyMButton (Windows) Middle button pressed
KSpecialKey Special keyboard code

If the KSpecialKey bit is set, then the keyboard code returned is one of the following constants:

KKeyUpCursor Up arrow
KKeyDownCursor Down arrow
KKeyLeftCursor Left arrow
KKeyRightCursor Right arrow
KKeyInsert Insert key
KKeyDelete Delete key
KKeyHome Home key pressed
KKeyEnd End key
KKeyPageUp Page up key
KKeyPageDown Page down key
KKeyEscape Escape key
KKeyHelp (Mac) Help key pressed
KKeyNumLock Num Lock key pressed
KKeyClear Clear key pressed
KKeyF1 F1
KKeyF2 F2
KKeyF3 F3
KKeyF4 F4
KKeyF5 F5
KKeyF6 F6
KKeyF7 F7
KKeyF8 F8
KKeyF9 F9
KKeyF10 F10
KKeyF11 F11
KKeyF12 F12
KKeyF13 F13
KKeyF14 F14
KKeyF15 F15

Window Management

KEventWindowName

(Dispatch) Sent when the window specified changes it's name. This is used to maintain the window menu.

 arg ignored; set to 0
 parg pointer to XGWidnow class being renamed

KEventWindowCreate

(Dispatch) Sent when this window is created. This is used to maintain the window menu and manage XGDocuments.

 arg  ignored; set to 0
 parg  pointer to XGWindow class being created

NOTE: If the window is not to be created, you can throw an error.

KEventWindowPreDestroy

(Dispatch) Sent just before the window is to be destroyed.

 arg  ignored; set to 0
 parg  pointer to XGWindow class being created

NOTE: If the window is not to be destroyed, you can throw an error.

KEventWindowDestroy

(Dispatch) Sent when the window is destroyed.

 arg  ignored; set to 0
 parg  pointer to XGWindow class being created

Dialog Management

KEventDialogMessage

(Dispatch) Sent when the dialog is either created or destroyed. This is sent to the default dialog handling callback.

 arg  Set to the constant KEventDMInitDialog when the dialog is being initialized, or KEventDMEndDialog when the dialog is being destroyed.
 parg  ignored; set to 0

NOTE: The event KEventDMInitDialog gives a callback the chance to initialize the controls in this dialog.

Internal window messages

KEventWInternal

(Dispatch) Sent to the owner of a control when a Win32 API message WM_HSCROLL, WM_VSCROLL, or WM_COMMAND is sent to a window, and specifies a separate control originally sent this message. This gives my control class the opportunity to convert this message into an internal dispatched message.

 arg  ignored; set to 0
 parg

 Points to a structure containing the message:

struct XGSWInternalRecord {
    HWND   w;
    UINT   msg;
    WPARAM wp;
    LPARAM lp;
};


[Home] [Prev] [Next] [Up]