This topic describes various events processed by Pen or Mouse.
In order for the FEP control to receive drag events occurring
in its window, all that is needed is to call EnableDragEvents()
in
the control’s construction routine. Having done that, the control will receive
drag events as calls to its HandlePointerEventL()
virtual
function. The iType
member of HandlePointerEventL()
’s aPointerEvent
parameter
is set to TPointerEvent::EDrag
for drag events.
This method makes heavy use of IPC (inter-process communication) as the user drags the mouse/pen around the FEP control’s window, which means that the FEP does not get drag events at optimum frequency. This may be problematic for something like handwriting recognition software. If there is a requirement to follow the path traced by the mouse/pen as closely as possible, another method can be used, namely buffered drag events.
The advantage of buffered drag events over simple drag events is that the window server client can receive multiple mouse/pen positions in a single event, which reduces the IPC overhead. To enable this, the following code needs to be called in the FEP control’s construction routine:
User::LeaveIfError(DrawableWindow()->AllocPointerMoveBuffer(ENumberOfPointsInBuffer, 0));
This assumes that ENumberOfPointsInBuffer
has been defined
elsewhere; TFEP2Plugin sets this constant to 32. The control
then receives drag events as calls to its HandlePointerBufferReadyL()
virtual
function, rather than as calls to HandlePointerEventL()
.
To retrieve these drag events, include the following code at the start of
the FEP control’s HandlePointerBufferReadyL()
function:
TPoint arrayOfPoints[ENumberOfPointsInBuffer]; TPtr8 bufferOfPoints(REINTERPRET_CAST(TUint8*, arrayOfPoints), 0, ENumberOfPointsInBuffer*sizeof(TPoint)); User::LeaveIfError(DrawableWindow()->RetrievePointerMoveBuffer(bufferOfPoints)); const TInt numberOfPointsInBuffer=bufferOfPoints.Length()/sizeof(TPoint);
Having
done that, numberOfPointsInBuffer
of arrayOfPoints
can
be used for whatever purpose the FEP requires, for example handwriting recognition.
Note that AllocPointerMoveBuffer()
’s counterpart FreePointerMoveBuffer()
does
not need to be called in the FEP control’s destructor as this happens automatically
when the control’s window is destroyed.
In order to intercept mouse/pen
events anywhere on the screen it is necessary to write a plugin into the window
server (WSERV). This is in addition to the FEP plugin which plugs into the
FEP architecture. TFEP2plugin provides a working example of this (TFEP2be).
The details of how to write a window server plugin DLL are beyond the scope
of this document because the APIs involved belong to the window server. See CAnim
and CAnimDll
in
the SDK for information on this. The way mouse/pen events can be intercepted
is by returning ETrue
from the function overriding MEventHandler::OfferRawEvent()
(CAnim
derives
from MEventHandler
). Events which are handled in this way
will not be sent to the relevant window server client, in other words, the
client who would otherwise have received this event.
The sprite feature
of the window server (RWsSprite
, defined in epoc32\include\W32STD.H
)
can be used to display to the user the path on the screen being traced out
by their mouse/pen movements. However, care should be taken when using sprites
for this purpose. Sprites use bitmaps, which in this context would need to
be the size of the screen. Because each running application has its own FEP,
which would have its own sprite, which in turn would have its own screen-sized
bitmap, it becomes apparent that some optimization must be done to avoid huge
amounts of memory being consumed. TFEP2Plugin solves this problem by using
a single bitmap shared between each sprite. It uses the 4 byte thread-local
storage of the window server plugin DLL to store the identifier of this bitmap.
The code which constructs the sprite is protected by a mutex (RMutex
,
defined in epoc32\include\E32STD.H
) as it tests to see
if the bitmap to be used by the sprite has already been created by a FEP running
the same code in another thread. If it has then it merely calls CFbsBitmap::Duplicate()
which
simply increments the existing bitmap’s reference count, thus only one large
bitmap is created rather than one per running application.
Intercepting mouse/pen events anywhere on the screen is likely to be most useful to handwriting-interpreting FEPs. Given that using this feature involves two polymorphic DLLs (plugging into different frameworks) running in two separate threads in separate processes, there is a choice regarding where the bulk of the FEP’s processing is done. The advantage of the processing being done outside of the window server process (in other words, in the FEP architecture plugin) is that bugs in the processing code (for instance crashing or hanging) do not affect the whole machine. The advantage of the processing being done inside the window server process (in other words, in the window server plugin) is that the long lists of screen positions (tracing out the path of where the user has dragged the mouse/pen) do not need to be communicated between processes.