=====Using the EVENTLIB library=====
//by Richard Russell, August 2014//\\ \\ (This article is an extended version of the [[http://bb4w.conforums.com/index.cgi?board=libraries&action=display&num=1331378257|forum message]] announcing the EVENTLIB library).\\ \\ The **EVENTLIB** library is designed to circumvent some limitations in the built-in ON MOUSE, ON MOVE, ON SYS and ON TIME event-handing mechanism in //BBC BASIC for Windows//, in particular the fact that event handlers are called **asynchronously** (which can be useful but can cause [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin6.html#interrupts|complications]]). It consists of only three procedures as follows:\\ \\
==== PROC_eventinit ====
This initialises the library and sets up a 32-event FIFO queue. Importantly, it can be called multiple times so in a modular program each section of code needing to receive event notifications can call it independently. All the ON... events except ON CLOSE are trapped (ON MOUSE, ON MOVE, ON SYS and ON TIME).\\ \\ Note that if your program calls **FN_setproc** (in WINLIB5 and WINLIB5A) to set up a menu-selection or button-click event handler, you should make sure that you call PROC_eventinit **afterwards**. In general you should call PROC_eventinit **after** any conventional ON MOUSE, ON MOVE, ON SYS and ON TIME statements, so that they receive 'unregistered' events.\\ \\
==== PROC_eventregister(WM_xxxx, PROChandler()) ====
This registers a procedure to be called when the specified event occurs; the event is identified by its @msg% value. PROC_eventregister can be called multiple times with the same event identifier, in which case all the specified handlers will be called sequentially. The handler needs to be defined to receive three parameters as follows:\\
DEF PROChandler(msg%, wparam%, lparam%)
\\
==== PROC_eventpoll ====
This simply polls the queue to see if any events are pending, and if so calls their registered handlers (if any) in the sequence in which the events occurred. If multiple handlers are registered for an event, they are all called (the last one registered is called first). Typically a program will wait in a polling loop such as:\\
REPEAT
PROC_eventpoll
WAIT 0
UNTIL FALSE
\\ If you need to be informed that the event queue overflowed, you can register a handler for that by specifying an event ID of zero:\\
PROC_eventregister(0, PROCoverflow())
\\ Despite the library's simplicity it is quite powerful, and goes a long way to solving the problem of distributing events to multiple handlers (potentially in multiple libraries) and ensuring they are called synchronously. It is designed to use only a small amount of memory.\\ \\ Here's a simple test program illustrating its use:\\
WM_MOVE = 3
WM_SIZE = 5
WM_TIMER = 275
WM_LBUTTONDOWN = 513
WM_RBUTTONDOWN = 516
INSTALL @lib$+"EVENTLIB"
PROC_eventinit
PROC_eventregister(WM_TIMER, PROCtimer())
PROC_eventregister(WM_TIMER, PROCanothertimer())
PROC_eventregister(WM_MOVE, PROCmove())
PROC_eventregister(WM_SIZE, PROCsize())
PROC_eventinit
PROC_eventregister(WM_LBUTTONDOWN, PROCmouse())
PROC_eventregister(WM_RBUTTONDOWN, PROCmouse())
PROC_eventregister(0, PROCoverflow())
REPEAT
PROC_eventpoll
WAIT 0
UNTIL FALSE
END
DEF PROCtimer(M%, W%, L%)
PRINT "Timer fired: "~ M% W% L%
ENDPROC
DEF PROCanothertimer(M%, W%, L%)
PRINT "Timer fired (2) ";
ENDPROC
DEF PROCmove(M%, W%, L%)
PRINT "Window moved: "~ M% W% L%
ENDPROC
DEF PROCsize(M%, W%, L%)
PRINT "Window resized: "~ M% W% L%
ENDPROC
DEF PROCmouse(M%, W%, L%)
PRINT "Mouse clicked: "~ M% W% L%
ENDPROC
DEF PROCoverflow(M%, W%, L%)
PRINT "Event queue overflowed!!"
ENDPROC