21. EVENTS MENU() In an accessory you have to check if it has been selected by the user. This is done with MENU(1). It is not necessary to check again with MENU(5) (and certainly not with MENU(4) as stated incorrectly in my Dutch GFA- manual): DO ! endless accessory-loop ~EVNT_MESAG(0) ! check if there is a message IF MENU(1)=40 ! yes, this accessory was selected IF MENU(5)=me_id& ! check accessory-number (*) @main ! do accessory-stuff there ENDIF ! (*) ENDIF LOOP The accessory-number (0-5: not more than six accessories are possible) can be checked with MENU(5), but we already know that this number is correct because the accessory is activated. The two (*)-lines can be left out. There is no easy way to test in a program if an accessory has been selected by the user. MENU(1) looks promising, but the value 40 (select accessory) or 41 (close accessory) is only sent to the accessory and not to your program! It would have been nice to be able to determine if an accessory has been closed, because GEM will clear the accessory-window and will fill the space with the desktop-pattern. No easy solution for this one, sorry. The best idea probably is to test frequently if a redraw is necessary, e.g.: ON MENU MESSAGE GOSUB message REPEAT ON MENU (...) UNTIL ready! (...) ' PROCEDURE message SELECT MENU(1) CASE 20 (...) ! redraw screen ENDSELECT RETURN This method only works if you have opened a window. If you're on the desktop (not in a window) you could ask GEM to restore the desktop: ~WIND_SET(14,0,0,0,0) ON MENU BUTTON The syntax for ON MENU BUTTON is: ON MENU BUTTON clicks,button,event GOSUB button_procedure For both 'button' and 'event' you can use the numbers 0-3. The variable 'button' determines which mouse-button you're monitoring (0=none, 1=left, 2=right, 3=both). The variable 'event' determines which button-presses should be intercepted (resulting in calling Procedure Button_procedure), so this variable usually is the same as 'button'. The variable 'clicks' stands for the maximal number of clicks you want to register. If you choose '2', the Procedure will be called if the user clicks once or twice: ON MENU BUTTON 2,1,1 GOSUB proc ! left click or left double-click It's not possible to wait for a double-click, unless the progam is really waiting, and not doing anything else: SELECT EVNT_BUTTON(2,1,1) CASE 1 ' clicked once CASE 2 ' clicked twice ENDSELECT But you can't combine this with an ON MENU loop. If you use the described method: ON MENU BUTTON 2,1,1 GOSUB proc you could use MENU(15) in the called Procedure to check if the user clicked twice. The same Procedure would be called after a single click, but you could ignore that. Fasten your seatbelts now. If you run such a program the first time, a double click is not registered in MENU(15). If you suspect a bug and run the program again, MENU(15) works all right. Nasty. Another GFA-bug (I think) after: ON MENU BUTTON 1,2,2 GOSUB proc The Procedure is called immediately, whether the right mouse-button was pressed or not. Use one dummy-call (to an empty Procedure) and all is well: ON MENU BUTTON 0,0,0 GOSUB dummy ON MENU ! dummy-call ON MENU BUTTON 1,2,2 GOSUB proc ! works fine now If you want to switch ON MENU BUTTON temporarily off, let it call an empty dummy-Procedure (also possible with other ON MENU commands): ON MENU BUTTON clicks,button,event GOSUB dummy ON MENU IBOX You can define two independent rectangles with ON MENU IBOX and/or ON MENU OBOX, either: - one IBOX and one OBOX - two IBOXes - two OBOXes Here is an example how you can use IBOX/OBOX to invert a rectangle if the mouse happens to enter the rectangle: BOX x1,y1,x2,y2 ! the rectangle w=x2-x1+1 ! rectangle-width h=y2-y1+1 ! rectangle-height ON MENU IBOX 1,x1,y1,w,h GOSUB invert ! if mouse enters rectangle REPEAT ON MENU ! watch the mouse UNTIL exit! ! never happens here ' PROCEDURE invert ! mouse entered rectangle GET x1,y1,x2,y2,b$ PUT x1,y1,b$,10 ! invert rectangle ON MENU OBOX 1,x1,y1,w,h GOSUB normal ! if mouse leaves rectangle RETURN ' PROCEDURE normal ! mouse left rectangle GET x1,y1,x2,y2,b$ PUT x1,y1,b$,10 ! restore rectangle ON MENU IBOX 1,x1,y1,w,h GOSUB invert ! if mouse enters rectangle RETURN ON MENU KEY If you are using keyboard-alternatives for submenu-options, you'll need ON MENU KEY: ON MENU KEY GOSUB key DO ON MENU LOOP In the Procedure Key you examine the key that has been pressed by the user and take an appropriate action: PROCEDURE key status|=MENU(13) key&=MENU(14) asci|=BYTE(key&) scan|=BYTE{V:key&} ' Examine variables status|, asci| and scan| (...) RETURN The three byte-variables can be used as described in the paragraph 'KEYGET' in chapter 8 (page 8-5). The advantage of the above method is that the mouse can be monitored at the same time: REPEAT REPEAT ON MENU MOUSE mx&,my&,mk& UNTIL mk& OR exit! IF mk& ' Mouse-button pressed, do something (...) ENDIF UNTIL exit! You can also use ON MENU to monitor both mouse and keyboard: ON MENU BUTTON 1,1,1 GOSUB left_click ON MENU KEY GOSUB key REPEAT ON MENU UNTIL exit! But if a mouse-Procedure is called (Left_click in this case) you can't determine the mouse-position with MENU(10) and MENU(11). You'll have to use MOUSEX and MOUSEY.