 |
TE_handleEvent |
Function (ROM Call 0xA9) |
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