REM V1.00 9-Feb-2016 Rewritten, enlarged buffer and over 900 controls and menu inputs. Unhandles events handed to ON SYS line.
REM Any ON SYS line must preceed any Event library command.
REM All PROC_initxxx calls must be made after any ON SYS line.
REM Events normally routed to ON SYS will be handled by specific handlers via the libraries. Unhandled ON SYS events will be route to the ON SYS line if it exists.
REM If no ON SYS line exists then any unhandled events will be ignored. (As usual)
REM Control IDs automatically assigned to &7FFE and decreasing.
DEF PROC_initonmove(RETURN F%)
LOCAL E%
E%=FN_regevent(7,F%) :REM All move/resize events linked to "ID" slot 7.
!396=!400 :REM Redirect the ON MOVE to the new ON SYS queue.
ENDPROC
DEF PROC_initonmouse(RETURN F%)
LOCAL E%
E%=FN_regevent(6,F%)
!404=!400
ENDPROC
DEF PROC_initontimer(RETURN F%)
LOCAL E%
E%=FN_regevent(5,F%)
!388=!400
ENDPROC
DEF PROC_initsweeper(RETURN F%) :REM SYS 1 less WM_Notify mesages
REM a link to the remaining events, mainly non control related. @msg% 287,279,278,123,83,786,563
LOCAL E%
E%=FN_regevent(4,F%)
ENDPROC
DEF PROC_initkb(RETURN F%) :REM Simulates an interrupt from key press. Scans KB buffer as part of PROC_DoEvents.
E%=FN_regevent(3,F%)
ENDPROC
DEF PROC_trapcancel(RETURN F%) :REM traps ID_CANCEL to defined procedure. Needed with WINLIB2B. If not used then Cancel routed to legacy ON SYS
E%=FN_regevent(2,F%)
ENDPROC
DEF PROC_trapok(RETURN F%) :REM traps ID_OK to defined procedure. Optional. ID of 1. If not called routes ID value of 1 to legacy ON SYS.
E%=FN_regevent(1,F%)
ENDPROC
DEF FN_regproc(RETURN F%)
REM Used within libs to allocate control and menu IDs
IF F%=0: =0
REM top 7 slots reserved for the above.
PRIVATE E% :LOCAL D%: E%+=1 D%=E%+8: IF D% = &3F0 ERROR 100, "Too many controls."
DEF FN_regevent(D%,F%) :REM force particular handlers that are not control ID dependent. Used to direct non ON SYS events from the common buffer to special handlers.
LOCAL S%: S%=!400 :REM Save current ON SYS vector prior to this buffer.
DIM F@%(&400), Z@%(99) :REM Define 32 event buffer and space for 1000 controls.
F@%(D%)=F% :REM Store the handler PROC address in an array indexed by the control ID.
ON SYS Z@%()=Z@%(0)+(3 AND Z@%(0)<99),@msg%,@wparam%,@lparam%,Z@%(1),Z@%(2),Z@%(3),Z@%(4),Z@%(5),Z@%(6),Z@%(7),Z@%(8),Z@%(9),Z@%(10),Z@%(11),Z@%(12),Z@%(13),Z@%(14),Z@%(15),Z@%(16),Z@%(17),Z@%(18),Z@%(19),Z@%(20),Z@%(21), \
\ Z@%(22),Z@%(23),Z@%(24),Z@%(25),Z@%(26),Z@%(27),Z@%(28),Z@%(29),Z@%(30),Z@%(31),Z@%(32),Z@%(33),Z@%(34),Z@%(35),Z@%(36),Z@%(37),Z@%(38),Z@%(39),Z@%(40),Z@%(41),Z@%(42),Z@%(43),Z@%(44),Z@%(45),Z@%(46), \
\ Z@%(47),Z@%(48),Z@%(49),Z@%(50),Z@%(51),Z@%(52),Z@%(53),Z@%(54),Z@%(55),Z@%(56),Z@%(57),Z@%(58),Z@%(59),Z@%(60),Z@%(61),Z@%(62),Z@%(63),Z@%(64),Z@%(65),Z@%(66),Z@%(67),Z@%(68),Z@%(69),Z@%(70),Z@%(71), \
\ Z@%(72),Z@%(73),Z@%(74),Z@%(75),Z@%(76),Z@%(77),Z@%(78),Z@%(79),Z@%(80),Z@%(81),Z@%(82),Z@%(83),Z@%(84),Z@%(85),Z@%(86),Z@%(87),Z@%(88),Z@%(89),Z@%(90),Z@%(91),Z@%(92),Z@%(93),Z@%(94),Z@%(95),Z@%(96): RETURN
s@ys%+=0 : IF S%<>!400 s@ys%=S% :REM Save a previous ON SYS vector as a global variable.
=NOT D% AND &7FFF
REM MSDN limits IDs to &7FFF
;
DEF PROC_DoEvents
REM Event handler in main program loop.
LOCAL P%, M%,W%,L%,K%, E%()
DIM E%(2)
WHILE Z@%(0) :REM Z@%(0) is 0 if no event in the queue otherwise it points to the interrupt parameter list @msg%, @wparam% and @lparam%
E%()=Z@%(Z@%(0)-2),Z@%(Z@%(0)-1),Z@%(Z@%(0)) :REM get all data from queue in one statament to maintain synchronism with no data loss.
Z@%(0) -= 3 :REM Adjust pointer to next interrupt in queue, if any
M%=E%(0):W%=E%(1):L%=E%(2) :REM Extract @msg%, wparam% and lparam%
CASE M% OF
WHEN 3,5,276,277:P%=F@%(7) :IF P% PROC(^P%)(M%,W%,L%) :REM Move/Size handler.
WHEN 513,515,516,518,519,521:P%=F@%(6) :IF P% PROC(^P%)(M%,W%,L%) :REM Mouse handler
WHEN 275:P%=F@%(5) :IF ?P%=&28 PROC(^P%)(W%) ELSE PROC(^P%) :REM Timer handler
WHEN 273,78: REM Control event notifications
IF W%=2 IF F@%(2) THEN
P%=F@%(2):IF ?P%=&28 PROC(^P%)(M%,W%,L%) ELSE PROC(^P%) :REM trap ID_CANCEL in WINLIB2B mode. Destination set by PROC_trapcancel
ENDPROC :REM We have handled it with a special PROC for cancel button so exit.
ENDIF
IF W%=1 IF F@%(1) THEN
P%=F@%(1):IF ?P%=&28 PROC(^P%)(M%,W%,L%) ELSE PROC(^P%) :REM trap ID_OK, optional.
ENDPROC :REM We have handled it with a special PROC for OK button so exit.
ENDIF
P%=F@%(NOT W% AND &3FF) :REM get event handler using the control ID as the index into the handler address array.
IF P%=0 OR W%<0 THEN
IF s@ys% SYS @fn%(18),s@ys%,M%,W%,L% :@flags% OR= &20000000 :REM Unhandled controls or notifications passed back to a previous ON SYS if it exists.
ENDPROC REM Eliminates NM_CUSTOMDRAW and other Notifications &FXXX XXXX. e.g BCN_
ENDIF
IF ?P%=&28 PROC(^P%)(M%,W%>>16,L%) ELSE PROC(^P%) :REM Jump to PROC. Don't send the ID part of W% as it is hidden from the user.
OTHERWISE
REM The other *SYS 1 Events not handled elsewhere. IF PROC_initsweeper not called they get passed onto an earlier ON SYS if it exists.
P%=F@%(4) :IF P% PROC(^P%)(M%,W%,L%) ELSE IF s@ys% SYS @fn%(18),s@ys%,M%,W%,L% :@flags% OR= &20000000
ENDCASE
ENDWHILE
WAIT 0 :REM Short delay so we don't need one in main loop.
P%=F@%(3)
IF P% THEN
REM Look for keystrokes
K%=INKEY(0)
IF K%<>-1 PROC(^P%)(K%)
ENDIF
ENDPROC
INSTALL @lib$+"E2lib" :REM Event handling. OR add "library" code to the program
REM Set up menus
AM$ = "AppendMenu"
SYS "CreateMenu" TO H%
SYS "CreatePopupMenu" TO hpopfile%
SYS AM$, hpopfile%, 0, FN_regproc(PROCnew), "&New"
SYS AM$, hpopfile%, 0, FN_regproc(PROCopen), "&Open"
SYS AM$, hpopfile%, 0, FN_regproc(PROCsave), "&Save"
SYS AM$, hpopfile%, 0, FN_regproc(PROCsaveas), "Save &As"
SYS AM$, hpopfile%, &800, 0, 0
SYS AM$, hpopfile%, 0, FN_regproc(PROCprint), "&Print"+CHR$9+"Ctrl+P "
SYS AM$, hpopfile%, &800, 0, 0
SYS AM$, hpopfile%, 0, FN_regproc(PROCclose), "E&xit"
SYS AM$, H%, 16, hpopfile%, "&File "
SYS "SetMenu",@hwnd%,H%
SYS "DrawMenuBar",@hwnd%
REPEAT
REM All actions from Interrupts.
PROC_DoEvents :REM This does it all.
UNTIL FALSE
END
DEF PROCnew :PRINT "New"
DEF PROCopen :PRINT "Open"
DEF PROCsave :PRINT "Save me"
DEF PROCsaveas :PRINT "OK, you have the idea by now!"
DEF PROCprint :PRINT "Offline!"
DEF PROCclose : QUIT
ENDPROC
INSTALL @lib$+"WINLIB2"
INSTALL @lib$+"E2lib" :REM or copy the event lib code to this program.
Dlgt1% = FN_newdialog("Test Polling",125,40,153,61,8,400)
PROC_pushbutton(Dlgt1%,"Push",FN_regproc(PROCpush),22,12,40,14,0)
PROC_pushbutton(Dlgt1%,"OK",1,22,40,40,14,&20001)
PROC_pushbutton(Dlgt1%,"Cancel",2,89,40,42,14,&0)
PROC_showdialog(Dlgt1%)
PROC_trapok(PROCok)
PROC_trapcancel(PROCcancel)
REM Polling
REPEAT
PROC_DoEvents
UNTIL FALSE
PROC_closedialog(Dlgt1%)
END
DEF PROCpush
PRINT "Push pushed"
ENDPROC
DEF PROCok
PRINT "OK pushed"
ENDPROC
DEF PROCcancel
PRINT "Cancel pushed, we will close shortly."
WAIT 200
PROC_closedialog(Dlgt1%)
QUIT
ENDPROC