TE_handleEvent Function (ROM Call 0xA9)

textedit.h

short TE_handleEvent (TEXT_EDIT *te, EVENT *event);

Dispatches an event to the text editor to be processed by it.

The text editor is an event driven application (see events.h for more info about events). It does not have a "main loop" in which keypresses are collected and processed. Instead, the user need to collect keypresses, and to dispatch them to the editor using TE_handleEvent. The editor will then process the keypress (for example, it will insert a new character, delete a character, scroll the editor area upwards/downwards etc. depending of the concrete keypress). In other words, the "main loop" is part of the user program. This approach is much more flexible, because the user may decide which keys will be processed and which will not be, and the user may program a lot of special actions which are not pre-programmed in the editor. For example, the user can redefine keys, forbid all keys except uppercase letters, etc. TE_handleEvent returns TRUE if the event was sucessfully processed by the editor, else returns FALSE.

TE_handleEvent needs a pointer to the editor control structure te, and a pointer to the EVENT structure event which represents the event to be processed. Basically, after calling TE_open, the program should enter a loop which does keyboard reading, and sending (wanted) keypress events to the editor using TE_handleEvent. The keyboard may be read using ngetchx, but this requires manual converting of integer keycode to an event structure. It is better idea to use EV_getc which is similar to ngetchx but in addition to the returned keycode, it also fills as an event structure. So, the text editor operations should be programmed as follows:

EVENT ev;
TEXT_EDIT te;
HANDLE h = HeapAlloc (200);                     // initial buffer size
memset (HeapDeref (h), 0, 200);

TE_open (&te, DeskTop, MakeWinRect (30, 30, 130, 70), h, 0, 0, 3);

CU_start ();                                    // Enable the cursor

while (EV_getc (ACTIVITY_BUSY, &ev) != KEY_ESC) // Get keypress and translate it to
  {                                             //   the event (until ESC pressed)
    TE_handleEvent (&te, &ev);                  // Send the event to the editor
  }                                             //   to be processed
In this example, all keypresses are passed to the editor. This need not to be always true; in fact, the main loop may contain whatever the user wants. The editor can handle a lot of special keypresses, like marking with shift+arrows, cut, copy and paste operations etc, not only inserting, deleting and scrolling (note that you can later access the clipboard using CB_fetchTEXT and CB_replaceTEXT if necessary). However, TE_handleEvent can not handle keypresses which represents tokens (like "sin" etc.) nor system keypresses which open menus like "CHAR" etc. Fortunately, this problem can be solved easily (see the next example).

The example given above is not a typical example of event driven program. All events in this example are restricted to simple keypresses. Typical event driven program uses EV_eventLoop function, which is an endless loop in which all timers, I/O ports etc. are checked for every possible event, and when an event appears, it is dispatched to the active application. The program need to install an event handler using EV_captureEvents function, which will capture all events, and which need to decide what to do with every particular event. This approach is used in the following example, which is written in typical "event driven" maneer. In this example (extracted from the "Text Editor" example), all events are dispatched to the text editor, except pressing the ESC key (this event will exit the event loop), and all events which were not processed sucessfully by the editor are dispatched to the default event handler (see EV_defaultHandler) which for example split tokens to single characters, open menus, etc:
TEXT_EDIT te;

CALLBACK void EventHandler(EVENT *ev)
{
  if (ev->Type == CM_KEYPRESS && ev->extra.Key.Code == KEY_ESC)
    ER_throw (1);
  if (!TE_handleEvent (&te, ev))
    EV_defaultHandler (ev);
}

void _main(void)
{
  HANDLE h = HeapAlloc (200);
  ...
  memset (HeapDeref (h), 0, 200);
  TE_open (&te, DeskTop, MakeWinRect (30, 30, 130, 70), h, 0, 0, 3);
  CU_start ();
  EV_captureEvents (EventHandler);
  TRY
    EV_eventLoop ();           // The only way to exit from "EV_eventLoop" is
  ONERR                        //   to throw an error from the event handler
    EV_captureEvents (NULL);
  ENDTRY
  ...
}
So, event driven programs using the text edit manager typically process events in three phases. First, the application event handler examines the event for action it needs to take. Either the application handler handles the event and returns to the event manager or it proceeds further. Second, the application event handler calls TE_handleEvent to allow the text edit manager to process the event. Either TE_handleEvent handles the event and returns TRUE, or it does not understand the event and returns FALSE. If TE_handleEvent does not handle the event, the application proceeds further. Third, the application calls EV_defaultHandler to let the event manager have one last try at handling the event. System-wide default behavior is implemented in EV_defaultHandler. Programs may drive the text editor by calling TE_handleEvent with their own created event messages (as in previous example), but in practice, the application just forwards events it received from the event manager (i.e. from the EV_eventLoop loop). Also note that calling TE_handleEvent may cause the heap compression.

Beware that EV_eventLoop is an endless loop, so the only way to exit from it is to throw an error from the event handler. This error will be captured later by a TRY...ONERR...ENDTRY construction.

Note: For the most of applications, you need not to use any text editor functions except TE_open (or TE_openFixed) and TE_handleEvent, because TE_handleEvent can do even relatively complicated operations like cut/copy/paste, etc. Other text editor functions are needed only if the user wants to program some special actions.


Uses: TE_checkSlack, TE_focus, TE_pasteText, TE_select, TE_unfocus, HeapFree, HeapLock, HeapMoveHigh, HeapRealloc, HeapUnlock, HLock, Dialog, DlgMessage, ERD_dialog, display_statements, HToESI, EV_paintWindows, HS_getEntry, memmove, strlen, CB_fetchTEXT, CB_replaceTEXT, CU_start, CU_stop, XR_stringPtr, CTypeTable, EV_errorCode, sf_width, WinBegin, WinChar, WinFill, WinScrollV, _du16u16, _mu16u16, ROM Call 0x412, ROM Call 0x471
Used by: HomeExecute