home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 99.img / PDOX3-09.ZIP / TOOLKIT2 / KERNEL.SC < prev    next >
Text File  |  1989-09-15  |  29KB  |  634 lines

  1. ; Copyright (c) 1987-1989 Borland International.  All Rights Reserved.
  2. ;
  3. ; General permission to re-distribute all or part of this script is granted,
  4. ; provided that this statement, including the above copyright notice, is not
  5. ; removed.  You may add your own copyright notice to secure copyright
  6. ; protection for new matter that you add to this script, but Borland
  7. ; International will not support, nor assume any legal responsibility for,
  8. ; material added or changes made to this script.
  9. ;
  10. ; Revs.:  MJP 3/8/88, DCY 12/15/88, DCY 5/24/89
  11. ; ****************************************************************************
  12. ;
  13. ; InitWait initializes variables needed by DoWait and loads all of its
  14. ; required supplemental procedures.  You must call it before invoking DoWait.
  15. ;
  16. ; You MUST call InitWait to load DoWait and its supplemental procedures.
  17. ; The Toolkit, like the rest of Paradox, is subject to upgrade.  When such
  18. ; upgrades occur, it is possible that the Toolkit may require more procedures,
  19. ; or that undocumented procedure names may change.  Calling InitWait rather
  20. ; that loading all of the necessary procedures manually will assure
  21. ; compatibility between Toolkit versions.
  22. ;
  23. ; InitWait examines the variable TKLibName.  If TKLibName is defined,
  24. ; then its value is used as the name of the library that contains the Toolkit
  25. ; procedures.  TKLibName can, of course, contain a full directory name.  If
  26. ; you do not assign TKLibName a value, it will default to "Toolkit".
  27. ;
  28. ; Note that InitWait does not load DPA procs for tables you use with DoWait.
  29. ; It is YOUR repsonsibility to load them (you do not need to execute them).
  30. ;
  31. Proc InitWait(MaxImgNo,ImgNumLst,TblNamLst)
  32.    Private;MaxImgNo,       ;Max. image number of table(s) to use with DoWait
  33.           ;ImgNumLst,      ;Comma separated list of table image numbers
  34.           ;TblNamLst,      ;Comma separated list of table names (corresponds
  35.                            ; to ImgNumLst)
  36.            ImgNo,          ;Parsed image number
  37.            TNam            ;Parsed table name
  38. ;  Global  TKDPASet        ;Array of workspace table image configuration
  39.  
  40.    If Not IsAssigned(TKLibName)         ;Set DoWait procedure library name to
  41.       Then TKLibName = SDir()+"Toolkit" ; default if not specified otherwise
  42.    Endif
  43.    If IsFile(TKLibName+".LIB")
  44.       Then Readlib TKLibName DoWait,CheckHoldCanvas,CheckMessage,CallProc,
  45.                              RecMvmnt,ArriveMvmnt,StdMvmnt,CheckRecMove,
  46.                              WaitZoom,GetInactive,GetKey,BadDelUndo,NewField,
  47.                              ArriveField,SysArrive,ArriveRecord,
  48.                              SysRecArrive,NewTable,ArriveTable,SysTblArrive
  49.            If Version() < 3
  50.               Then Quit "Release 3.0 of the Data Entry Toolkit requires Paradox version 3.0 or higher."
  51.            Endif
  52.            Array TKDPASet[MaxImgNo]
  53.            ImgNumLst = ImgNumLst + ","
  54.            TblNamLst = TblNamLst + ","
  55.            While Match(ImgNumLst,"..,..",ImgNo,ImgNumLst) and
  56.                  Match(TblNamLst,"..,..",TNam,TblNamLst)
  57.               TKDPASet[Numval(ImgNo)] = "TK"+TNam+"_"
  58.            Endwhile
  59.       Else Quit "DoWait procedures not loaded: Could not find " + TKLibName +
  60.                 " library."
  61.    Endif
  62. Endproc
  63.  
  64. ; Here is the heart and soul of the toolkit: DoWait, an event-driven wait.
  65. ;
  66. ; Like the PAL WAIT TABLE command, DoWait allows a user to move around a
  67. ; table image (and make changes if in edit mode) until the user presses any
  68. ; one of a set of pre-designated "exit" keys, upon which control is returned
  69. ; back to the calling program.
  70. ;
  71. ; DoWait differs from a WAIT command in that after you invoke DoWait, you
  72. ; do not lose control over what a user can do while editing.  Instead, DoWait
  73. ; calls procedures which you've previously specified (using TKMenu's
  74. ; SetUpDoWait subsystem) DURING the wait condition upon the occurence of
  75. ; certain keystroke, field, record, and table-level events.  By creating
  76. ; appropriate procedures for DoWait to call upon specific events, you can
  77. ; have nearly total control over what a user does and can do during an editing
  78. ; session.
  79. ;
  80. ; Specifically, DoWait examines variables (defined in DPA procedures created
  81. ; by SetUpDoWait) to know both the names of procedures to call and the events
  82. ; upon which to activate them.  These variables also instruct DoWait on how
  83. ; to treat each key a user presses.
  84. ;
  85. Proc DoWait(TKMessage)
  86.    Private;TKMessage,     ;Message to be displayed (provided by user)
  87.            TKAccept,      ;Specifies whether last key hit will be accepted
  88.            TKHoldCanvas,  ;Specifies whether PAL canvas will be removed
  89.            TKFieldNum,    ;Column position (in table view) of current field
  90.            TKFieldVal,    ;Value of current field upon entry into it
  91.            TKChanged,     ;Indicates field value has changed since arrival
  92.            TKRecMvmnt,    ;Specifies whether last key will cause rec movement
  93.            TKMvmntProc,   ;Procedure which initiates movement key events
  94.            TKChar,        ;ASCII value of last key pressed
  95.            TKKeyType,     ;Type of key (R, I, E, M, S, D)
  96.            TKKeyProc,     ;Procedure which monitors keyboard (in)activity
  97.            TKUserKey,     ;Value of key before user's procedure was executed
  98.            TKSeconds,     ;Number of seconds elapsed without a keypress
  99.            TKBuffer,      ;ASCII value of key in keyboard buffer
  100.            TKTime,        ;Time of last keypress
  101.            TKImgNo,       ;Image number of active table image
  102.            TKPosKey,      ;ASCII (positive) key class assignments
  103.            TKNegKey,      ;IBM extended key class assignments
  104.            TKAction,      ;Array of field level procedure assignments
  105.            TKArrive,      ;Array of field arrival procedures
  106.            TKGoodDepart,  ;Array of field good departure procedures
  107.            TKBadDepart,   ;Array of field bad departure procedures
  108.            TKKeystroke,   ;Array of field keystroke procedures
  109.            TKSpclProc,    ;Special key procedure
  110.            TKInactiveProc,;Keyboard inactivity procedure
  111.            TKTblArrive,   ;Table arrival procedure
  112.            TKTblDepart,   ;Table departure procedure
  113.            TKRecArrive,   ;Record arrival procedure
  114.            TKRecDepart,   ;Record departure procedure
  115.            TKNegMv,       ;Record departure (ASCII) key assignments
  116.            TKPosMv        ;Record departure (IBM Extended) key assignments
  117.  
  118.    TKChar = BlankNum()    ;Initialize keystroke character
  119.    TKBuffer = BlankNum()  ;Initialize single-key type-ahead buffer
  120.    TKHoldCanvas = False   ;Unless specified otherwise in an arrival-level
  121.                           ; procedure, remove PAL canvas just before
  122.                           ; acceptance of first user keystroke
  123.    SysTblArrive()         ;Inform DoWait we've entered a new table--
  124.                           ; Initialize DPA set and call table arrival proc
  125.    SysRecArrive()         ;Inform DoWait we've arrived at a new record--
  126.                           ; Call record arrival procedure if assigned
  127.    SysArrive()            ;Inform DoWait we've arrived in a new field--
  128.                           ; Initialize field-dependent variables and call
  129.                           ; field arrival procedure if assigned
  130.    CheckHoldCanvas()      ;Unless specified otherwise in an arrival procedure,
  131.                           ; set echo to normal on entry
  132.    CheckMessage()         ; Check for a message to display
  133.    ExecProc TKKeyProc     ;Read a key from the keyboard
  134.    Echo Normal
  135.  
  136.    While True
  137.       If TKChar > 0         ;Determine class of key we are about to process
  138.          Then TKKeyType = Substr(TKPosKey,TKChar,1)   ;These statements are
  139.          Else TKKeyType = Substr(TKNegKey,1-TKChar,1) ; necessary because max
  140.       Endif                                           ; string length is 255
  141.       Switch
  142.          Case HelpMode() <> "None" or IsFieldView(): ;Do nothing special while
  143.             Keypress TKChar                          ; in field view or help
  144.          Case TKKeyType = "R":                       ;"Regular" key
  145.             If Search("K",TKAction[TKFieldNum]) <> 0 ;Call keystroke proc if
  146.                Then CallProc(TKKeystroke[TKFieldNum]); assigned
  147.                     If TKKeyType = "X"               ;Check for request to
  148.                        Then CheckMessage()           ; immediately exit DoWait
  149.                             Echo Off
  150.                             Return TKChar
  151.                     Endif
  152.                     If Not Retval
  153.                        Then Loop                    ;Key wasn't accepted or
  154.                     Endif                           ; was reset to a new
  155.             Endif                                   ; value--reprocess it.
  156.             Keypress TKChar
  157.          Case TKKeyType = "I":                      ;"Illegal" key
  158.             Beep                                    ;Beep and ignore key
  159.          Otherwise:  ;Key must be of type "S","D","E", or "M"
  160.             If Search(TKKeyType,"SD") <> 0    ;"Special" or "DepartSpecial"
  161.                Then CallProc(TKSpclProc)      ;Call appropriate procedure
  162.                     If TKKeyType = "X"
  163.                        Then CheckMessage()
  164.                             Echo Off
  165.                             Return TKChar
  166.                     Endif
  167.                     If not Retval     ;Key wasn't accepted, or was
  168.                        Then Loop      ; reset to a new value
  169.                     Endif
  170.                     If TKKeyType = "S"
  171.                        Then Keypress TKChar
  172.                             CheckMessage()
  173.                             ExecProc TKKeyProc
  174.                             Echo Normal 
  175.                             Loop
  176.                     Endif
  177.             Endif
  178.             If IsValid()
  179.                Then If Search("D",TKAction[TKFieldNum]) <> 0 ;Good Depart
  180.                        Then TKChanged = [] <> TKFieldVal ;Changed? Set T/F
  181.                             CallProc(TKGoodDepart[TKFieldNum])
  182.                             If TKKeyType = "X" ;Immediate Exit
  183.                                Then CheckMessage()
  184.                                     Echo Off      
  185.                                     Return TKChar
  186.                             Endif
  187.                             If not Retval ;Good Depart or Bad Depart rejected
  188.                                Then Loop  ; or reassigned TKChar.  Reprocess.
  189.                             Endif
  190.                     Endif
  191.                Else If Search("F",TKAction[TKFieldNum]) <> 0 ;Bad Depart
  192.                        Then CallProc(TKBadDepart[TKFieldNum])
  193.                             If TKKeyType = "X"
  194.                                Then CheckMessage()
  195.                                     Echo Off
  196.                                     Return TKChar
  197.                             Endif
  198.                             If not Retval ;Good Depart or Bad Depart rejected
  199.                                Then Loop  ; or reassigned TKChar.  Reprocess.
  200.                             Endif
  201.                     Endif
  202.             Endif
  203.             If IsValid()                  ;Field data is valid, pending key is
  204.                Then ExecProc TKMvmntProc  ; a movement key ("D" or "M")
  205.                     If Search(TKKeyType,"EX") <> 0
  206.                        Then CheckMessage() ;Movement-initiated proc or pending
  207.                             Echo Off       ; key requested exit from DoWait
  208.                             Return TKChar
  209.                     Endif
  210.                     If Not Retval         ;Movement-initiated proc rejected
  211.                        Then Loop          ; pending key
  212.                     Endif
  213.                Else ;Data is still invalid, can't move out of it
  214.                     If (TKChar = -83 or TKChar = 21 or TKChar = 0) and
  215.                        TKKeyType <> "E"   ;If Del, Undo, or Cancel is an Exit
  216.                        Then BadDelUndo()  ; key, reject it -- data is invalid
  217.                             If Search(TKKeyType,"EX") <> 0
  218.                                Then CheckMessage()
  219.                                     Echo Off
  220.                                     Return TKChar
  221.                             Endif
  222.                             If not Retval
  223.                                Then Loop
  224.                             Endif
  225.                        Else If IsBlank(TKMessage) ;Display standard Paradox
  226.                                Then Keypress -72  ; message unless specified
  227.                             Endif                ; otherwise in user procedure
  228.                     Endif
  229.             Endif
  230.       Endswitch
  231.       CheckMessage()          ; Check for message to display
  232.       ExecProc TKKeyProc      ; Read next key
  233.       Echo Normal
  234.    Endwhile
  235. Endproc
  236.  
  237. ; This procedure is called by DoWait before a key is read from the keyboard.
  238. ; The procedure checks the variable TKMessage, and sends that message to the
  239. ; screen if it is non-blank.
  240. ;
  241. Proc CheckMessage()
  242.    If TKMessage <> ""    ;Has the user specified a message?
  243.       Then Echo Off
  244.            Message TKMessage
  245.            SyncCursor
  246.            TKMessage = ""       ;Re-initialize to show no pending message
  247.    Endif
  248.    TKAccept = True
  249. Endproc
  250.  
  251. ; This procedure examines the user-defined variable TKHoldCanvas, and turns
  252. ; echo to normal if the programmer hasn't prohibited it.  DoWait calls
  253. ; CheckHoldCanvas to update the current echo status.
  254. ;
  255. Proc CheckHoldCanvas()
  256.    If TKHoldCanvas
  257.       Then TKHoldCanvas = False ;Re-initialize to allow removal of PAL canvas
  258.       Else Echo   Normal
  259.    Endif
  260. Endproc
  261.  
  262. ; This procedure calls a user-specified procedure, checks to see whether to
  263. ; turn echo back to normal upon return from the procedure, and determines
  264. ; whether the key that was pressed in order to invoke the procedure was
  265. ; accepted "as is" by that procedure.
  266. ;
  267. ; The procedure takes one argument, which is the name of the procedure to
  268. ; call. It returns False if the procedure does not accept the character which
  269. ; was passed to it (resets TKChar or sets TKAccept to False), or True
  270. ; otherwise.
  271. ;
  272. Proc CallProc(ProcName)
  273. ; Private ProcName               ;Name of procedure to be called
  274.    TKUserKey = TKChar            ;Remember the key that was passed to the proc
  275.    ExecProc ProcName
  276.    If TKKeyType = "X"            ;Exit immediately from DoWait?
  277.       Then Return
  278.    Endif
  279.    CheckHoldCanvas()             ;Turn echo back to normal if appropriate
  280.    If TKAccept                   ;Was TKChar accepted and unchanged?
  281.       Then If TKUserKey = TKChar
  282.               Then Return True
  283.            Endif
  284.       Else CheckMessage()        ;Get new character
  285.            ExecProc TKKeyProc
  286.            Echo Normal
  287.    Endif
  288.    Return False
  289. Endproc
  290.  
  291. ; This procedure keypresses a cursor movement key and then calls the
  292. ; ArriveMvmnt procedure to initialize any necessary table, record, or field
  293. ; level events.  DoWait calls RecMvmnt only after the appropriate good or bad
  294. ; depart procedure is executed.
  295. ;
  296. ; Note that since there is no way of knowing whether Undo will cause movement
  297. ; out of the current table, RecMvmnt will NOT call a Table Depart even if
  298. ; Undo does move the cursor to another table.  See also ArriveMvmnt below.
  299. ;
  300. ; In addition to this function, the RecMvmnt procedure checks to see
  301. ; whether the movement key that was pressed was [Zoom].  This is necessary
  302. ; because [Zoom] doesn't actually cause movement into a new field until after
  303. ; a value has been entered at the zoom prompt and [Enter] has been pressed.
  304. ; Thus we must pause and wait for this to occur before actually arriving into
  305. ; a new field.
  306. ;
  307. Proc RecMvmnt()
  308.  
  309.    If TKChar = 26                     ;Zoom key?
  310.       Then WaitZoom()                 ;Special Zoom handling procedure
  311.            If not Retval              ;User cancelled Zoom
  312.               Then Return False
  313.            Endif
  314.            TKRecMvmnt = True          ;Zoom always initiates rec-level depart
  315.       Else CheckRecMove()             ;Record departure key?
  316.    Endif
  317.    If TKRecMvmnt and TKRecDepart <> "" ;Call rec-level depart if necessary
  318.       Then CallProc(TKRecDepart)
  319.            If TKKeyType = "X"          ;Check for request to immediate exit
  320.               Then Return
  321.            Endif
  322.            If Not Retval               ;Key rejected or reassigned
  323.               Then Return False
  324.            Endif
  325.    Endif
  326.    If (TKChar = -61 or TKChar = -62) and TKTblDepart <> ""
  327.       Then CallProc(TKTblDepart)      ;Call table-level depart if necessary
  328.            If Not Retval                      ;Key rejected or reassigned
  329.               Then Return False
  330.            Endif
  331.    Endif
  332.    If Search(TKKeyType,"EX") <> 0  ;Check for normal or immediate exit
  333.       Then Return
  334.    Endif
  335.    ArriveMvmnt()             ;Initiate table->record->field arrival sequence
  336.    Return True
  337. Endproc
  338.  
  339. ; This procedure initiates the event arrival sequence for a movement key
  340. ; and the special invalid-field Undo, Del, Cancel case.  RecMvmnt calls this
  341. ; procedure to "press" a movement key.  ArriveMvmnt, in turn, will call the
  342. ; appropriate arrival procedures.
  343. ;
  344. ; If the Undo key causes movement to another table, ArriveMvmnt will properly
  345. ; call the table and record arrival events for the new table (your procedures
  346. ; consider this possibility).
  347. ;
  348. Proc ArriveMvmnt()
  349.  
  350.    Keypress TKChar
  351.    If ImageNo() <> TKImgNo        ;Did we move to a new table?
  352.       Then TKRecMvmnt = True      ;Will be arriving in a new record
  353.            SysTblArrive()         ;Call Table Arrive if assigned
  354.    Endif
  355.    If TKRecMvmnt                  ;Need to call record arrival procedure?
  356.       Then SysRecArrive()         ; (Did we just leave a record?)
  357.    Endif
  358.    SysArrive()                    ;Call field arrival procedure
  359.  
  360. Endproc
  361.  
  362. ; This procedure initiates a movement-arrival sequence for tables which
  363. ; do not have record-level events assigned to them.  See RecMvmnt above
  364. ; for more information.
  365. ;
  366. Proc StdMvmnt()
  367.  
  368.    If TKChar = 26                  ;Zoom key?
  369.       Then WaitZoom()              ;Call special Zoom handling procedure
  370.            If not Retval           ;Zoom not initiated
  371.               Then Return False
  372.            Endif
  373.            Enter                   ;Zoom!
  374.       Else If (TKChar = -61 or TKChar = -62) and TKTblDepart <> ""
  375.               Then CallProc(TKTblDepart)   ;Call table depart, if assigned
  376.                    If Not Retval
  377.                       Then Return False
  378.                    Endif
  379.            Endif
  380.            If Search(TKKeyType,"EX") <> 0  ;Check for normal or
  381.               Then Return                  ; immediate exit
  382.            Endif
  383.            Keypress TKChar
  384.            If TKChar = -61 or TKChar = -62  ;If key caused normal movement to
  385.               Then SysTblArrive()           ; another table, invoke table 
  386.            Endif                            ; arrival procedure
  387.    Endif
  388.    SysArrive()             ;Arriving in new field, call field arrival
  389.    Return True             ; event
  390. Endproc
  391.  
  392. ; This procedure determines whether a pending movement key should initiate a
  393. ; record-level event.  It requires key movement codes defined by SetUpDoWait
  394. ; and additional image-specific information.
  395. ;
  396. Proc CheckRecMove()
  397.  
  398.    If TKChar > 0           ;Determine type of key we are about to process
  399.       Then TKMvTyp = Substr(TKPosMv,TKChar,1)   ;These statements are
  400.       Else TKMvTyp = Substr(TKNegMv,1-TKChar,1) ; necessary because max
  401.    Endif                                         ; string length is 255
  402.  
  403.    TKRecMvmnt = False      ;Assume no record-level event will be generated
  404.  
  405.    If IsFormView()         ;Form view case
  406.       Then Switch
  407.               Case NPages() = 1 :  ; Only one page, PgUp/PgDn cause rec-event
  408.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  409.                     Then TKRecMvmnt = True
  410.                  Endif
  411.               Case PageNo() = 1 :  ; First page, PgUp causes rec-event
  412.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  413.                     Then TKRecMvmnt = True
  414.                  Endif
  415.               Case PageNo() = NPages() :   ; Last page, PgDn causes rec-event
  416.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  417.                     Then TKRecMvmnt = True
  418.                  Endif
  419.            Endswitch
  420.       Else If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  421.               Then TKRecMvmnt = True
  422.            Endif
  423.    Endif
  424.  
  425. Endproc
  426.  
  427. ; This procedure handles the special case in which a user invokes the Zoom
  428. ; command.  It only allows a user to exit from Zoom by pressing either [Enter]
  429. ; or [Esc] (same as [Cancel]).  Note that while a user is at the Zoom prompt,
  430. ; DoWait performs no special processing.  An attempt to initiate a Zoom will
  431. ; invoke a record-level event.
  432. ;
  433. Proc WaitZoom()
  434.  
  435.    Zoom                        ;Display Zoom prompt
  436.    While True
  437.       TKChar = GetChar()         ;Read key
  438.       Switch
  439.          Case TKChar = 13 :       ;Zoom should be acted upon
  440.             Return True
  441.          Case TKChar = 27 or TKChar = 0 :    ;Zoom not acted upon
  442.             Esc
  443.             ExecProc TKKeyProc     ;Process next key
  444.             Return False
  445.          Case TKChar > 31          ;Press only keys valid at Zoom prompt
  446.            or TKChar = 6 or TKChar = -108 or TKChar = 8
  447.            or (TKChar < -70 and TKChar > -84)
  448.            or (TKChar < -114 and TKChar > -120) :
  449.             Keypress TKChar
  450.          Otherwise :               ;Reject illegal keys
  451.             Beep
  452.       Endswitch
  453.    Endwhile
  454.  
  455. Endproc
  456.  
  457. ; This procedure reads a character from the keyboard buffer.  It
  458. ; facilitates the keyboard inactivity event and maintains the single-key
  459. ; type-ahead buffer. It is called by DoWait, CallProc, and WaitZoom when a
  460. ; new key is to be processed.
  461. ;
  462. ; A keyboard inactivity procedure, if assigned, is called once a second.  The
  463. ; variable TKSeconds, available to the procedure, specifies the number of
  464. ; seconds elapsed without a keypress (equal to the number of times the
  465. ; inactivity procedure has been called in a row).
  466. ;
  467. ; DoWait will act upon TKBuffer, if set equal to an ASCII or IBM Extended
  468. ; code, as if a user had actually pressed the key.  The keycode in TKBuffer
  469. ; take precedence over any keys already in the acutal keyboard buffer.
  470. ;
  471. Proc GetInactive()
  472.    TKSeconds = 0                 ;Reset TKSeconds after last keypress
  473.    While True
  474.       If IsBlank(TKBuffer)       ;Check for a key in TKBuffer
  475.          Then TKTime = Time()    ;Wait (a second) for a character
  476.               While Not CharWaiting() and TKTime = Time()
  477.               Endwhile
  478.               If CharWaiting()   ;Key pressed, read keycode
  479.                  Then TKChar = GetChar()
  480.                       Quitloop
  481.                  Else TKSeconds = TKSeconds + 1  ;No key pressed, call
  482.                       TKHoldCanvas = True        ; inactivity procedure
  483.                       ExecProc TKInactiveProc
  484.                       CheckHoldCanvas()          ;Check canvas status
  485.                       CheckMessage()             ;Check for message to display
  486.               Endif
  487.          Else TKChar = TKBuffer     ;TKBuffer has a keycode.  Process it ahead
  488.               TKBuffer = BlankNum() ; of the keycode in acutal buffer, and
  489.               Quitloop              ; reset TKBuffer
  490.       Endif
  491.    Endwhile
  492. Endproc
  493.  
  494. ; This procedure reads a character from the keyboard buffer.  It is called
  495. ; instead of GetInactive() if a keyboard inactivity procedure has not been
  496. ; defined.  GetKey() executes much faster than GetInactive().  Note that
  497. ; applications which do not use an inactivity procedure can still make use
  498. ; of TKBuffer.
  499. ;
  500. Proc GetKey()
  501.    If IsBlank(TKBuffer)
  502.       Then TKChar = GetChar()
  503.       Else TKChar = TKBuffer
  504.            TKBuffer = BlankNum()
  505.    Endif
  506. Endproc
  507.  
  508. ; This procedure is called by DoWait when Undo, Del, or Cancel (Ctrl-Break)
  509. ; is pressed and accepted while the information in the current field is
  510. ; invalid.  Special handling is needed in these cases, as we do not want to
  511. ; allow exit from the WAIT while information in a field is invalid.  At the
  512. ; same time, we recognize that pressing Undo, Del, or Cancel will
  513. ; automatically cause the field to be valid (by simply removing or changing
  514. ; the entire record).
  515. ;
  516. ; The problem that must be dealt with is that if Undo, Del, or Cancel is
  517. ; defined as an exit character, we must give control back to the program
  518. ; BEFORE either of these keys is pressed (acted upon).  Thus we do not know
  519. ; whether the key will be pressed at all.  This is not a problem if these
  520. ; keys are defined as move characters, as the keys will be pressed
  521. ; automatically (assuring the validity of the field).
  522. ;
  523. Proc BadDelUndo()
  524.  
  525.    TKMessage = ""        ;Any user-defined message was most likely put
  526.                          ; up in error, as field will now become valid
  527.    If TKRecMvmnt and TKRecDepart <> ""  ;Del, Undo, or Cancel will cause
  528.       Then CallProc(TKRecDepart)        ; a record-level event
  529.            If TKKeyType = "X"           ;Check for immediate exit request
  530.               Then Return
  531.            Endif
  532.            If Not Retval                ;Key rejected by rec-depart proc
  533.               Then Return False
  534.            Endif
  535.    Endif
  536.    ArriveMvmnt()        ;Initiate event arrival sequence
  537.    Return True
  538.  
  539. Endproc
  540.  
  541. ; NewField is called by DoWait whenever a new field is entered.  It is
  542. ; responsible for setting all field-dependent variables.  You may call this
  543. ; procedure instead of ArriveField if one of your procedures causes explicit
  544. ; movement into a new field and you wish to inhibit invocation of the arrival
  545. ; procedure for the new field.
  546. ;
  547. Proc NewField()
  548.    TKFieldVal = []                         ;Get field entry value and index
  549.    TKFieldNum = ColNo()                    ; into arrays for current field
  550. Endproc
  551.  
  552. ; ArriveField alerts DoWait that one of your procedures has just explicitly
  553. ; moved into a new field and that DoWait should call the arrival procedure
  554. ; for the new field.  Your procedures MUST call this procedure (or NewField)
  555. ; if they cause explicit movement into another field (using MOVETO or Right,
  556. ; for example).
  557. ;
  558. Proc ArriveField()
  559.    CheckHoldCanvas()            ;Update canvas status
  560.    SysArrive()                  ;Initiate field arrival
  561. Endproc
  562.  
  563. ; SysArrive initiates all actions associated with entering a field, including
  564. ; calling the appropriate arrival procedure if assigned.
  565. ;
  566. Proc SysArrive()
  567.    NewField()
  568.    If Search("A",TKAction[TKFieldNum]) <> 0 ;Is an arrival procedure assigned?
  569.       Then ExecProc TKArrive[TKFieldNum]
  570.            CheckHoldCanvas()
  571.    Endif
  572.    TKAccept = False  ;If a keystroke is pending (which could happen if this
  573. Endproc              ; proc were called from a user's proc), then ignore it
  574.  
  575. ; ArriveRecord initiates all actions associated with arriving into a new
  576. ; record.  Your procedures can call ArriveRecord to invoke a record-level
  577. ; arrival procedure for a table.
  578. ;
  579. Proc ArriveRecord()
  580.    CheckHoldCanvas()    ;Check canvas status
  581.    SysRecArrive()
  582. Endproc
  583.  
  584. ; SysRecArrive initializes field dependent variables and executes a record-
  585. ; level procedure for a table, if assigned.
  586. ;
  587. Proc SysRecArrive()
  588.    NewField()                   ;Initialize field variables
  589.    If TKRecArrive <> ""         ;Call record arrival proc if assigned
  590.       Then ExecProc TKRecArrive
  591.            CheckHoldCanvas()
  592.    Endif
  593.    TKAccept = False  ;If a key is pending (which could happen if this
  594. Endproc              ; proc were called from a user's proc), ignore it
  595.  
  596. ; This procedure initializes the DoWait procedure assignment variables
  597. ; when entering a new table image, but does not call a table arrival
  598. ; procedure if one is assigned.
  599. ;
  600. Proc NewTable()
  601.    ExecProc TKDPASet[ImageNo()]+Form()
  602.    TKKeyProc = "GetInactive"
  603.    If IsBlank(TKInactiveProc)     ;Select which keyboard procedure to use
  604.       Then TKKeyProc = "GetKey"
  605.    Endif
  606.    TKRecMvmnt = True
  607.    If TKMvmntProc = "StdMvmnt"    ;Select which movement procedure to use
  608.       Then TKRecMvmnt = False
  609.    Endif
  610.    TKImgNo = ImageNo()            ;Determine current image number
  611.    NewField()                     ;Initialize field dependent variables
  612. Endproc
  613.  
  614. ; This procedure is called upon entry into a new table image by NewImage, and
  615. ; subsequently calls a table arrival procedure for the new table if one is
  616. ; assigned.
  617. ;
  618. Proc ArriveTable()
  619.    CheckHoldCanvas()         ;Update canvas status
  620.    SysTblArrive()
  621. Endproc
  622.  
  623. ; This procedure initializes DoWait procedure assignment information and
  624. ; calls a table arrival procedure for the new table if assigned.
  625.  
  626. Proc SysTblArrive()
  627.    NewTable()        ;Define DPA set variables
  628.    If TKTblArrive <> ""
  629.       Then ExecProc TKTblArrive
  630.            CheckHoldCanvas()
  631.    Endif
  632.    TKAccept = False  ;If a keystroke is pending (which could happen if this
  633. Endproc              ; proc were called from a user's proc), then ignore it
  634.