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.