by Jon Ripley and Richard Russell, April 2007

The functions GET and GET$, and the statement INPUT, can adversely affect the handling of events (e.g. ON CLOSE, ON MOUSE etc.) by your program. This is because whilst they are waiting for user input no events will be processed.

The following program demonstrates this issue. Run this program in the IDE and you will notice that clicking on the close icon has no effect until you press a key:

      ON CLOSE QUIT
      PRINT GET
In the case of GET and GET$ the problem can be solved by using the functions FNget and FNget$ listed below, which are equivalent to GET and GET$ but do not interfere with event handling:

      DEF FNget:LOCALK%
      REPEAT WAIT 0:K%=INKEY(0):UNTILK%>0
      =K%
 
      DEF FNget$:LOCALK$
      REPEAT WAIT 0:K$=INKEY$(0):UNTILK$>""
      =K$
The following code demonstrates how to call these functions:

      N = FNget
      N$ = FNget$
Solving the problem with INPUT is more difficult, because of the many facilities provided by that statement (input editing, pasting from the clipboard, copy key etc.). To reproduce the full functionality of INPUT in BBC BASIC code would be challenging, but often your program will not require all its facilities.

The function FNinput below provides a replacement for INPUT with simple line-editing facilities which may often be sufficient:

      DEF FNinput
      LOCAL a$,c%,k%,x%,y%
      x% = POS : y% = VPOS
      REPEAT
        OFF
        PRINT TAB(x%,y%) a$;" " TAB(x%,y%) LEFT$(a$,c%);
        ON
        REPEAT WAIT 0 : k% = INKEY(0) : UNTIL k%>0
        CASE k% OF
          WHEN 8,127: IF c% THEN a$ = LEFT$(a$,c%-1) + MID$(a$,c%+1):c% -= 1
          WHEN 135: IF c%<LEN(a$) THEN a$ = LEFT$(a$,c%) + MID$(a$,c%+2)
          WHEN 13:
          WHEN 136: IF c% THEN c% -= 1
          WHEN 137: IF c%<LEN(a$) THEN c% += 1
          OTHERWISE: a$ = LEFT$(a$,c%) + CHR$k% + MID$(a$,c%+1):c% += 1
        ENDCASE
      UNTIL k% = 13
      PRINT
      =a$
If you need the ability to paste from the clipboard, you can do that by adding the following line to the CASE statement:

          WHEN 22: PROCpaste(a$,c%)
and adding the procedure PROCpaste as follows:

      DEF PROCpaste(RETURN a$,RETURN c%)
      LOCAL r%,h%,t%
      SYS "IsClipboardFormatAvailable",1 TO r%
      IF r%=0 THEN ENDPROC
      SYS "OpenClipboard", @hwnd%
      SYS "GetClipboardData",1 TO h%
      SYS "GlobalLock",h% TO t%
      WHILE ?t% >= 32
        a$ = LEFT$(a$,c%) + CHR$?t% + MID$(a$,c%+1)
        c% += 1
        t% += 1
      ENDWHILE
      SYS "GlobalUnlock",h%
      SYS "CloseClipboard"
      ENDPROC
The following code demonstrates how to call FNinput from your program:

      PRINT "Prompt: ";
      reply$ = FNinput
A more comprehensive version of FNinput, supporting features such as toggling between insert and overtype modes, can be found in the NOWAIT library.