home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a114 / 2.img / TOOLKIT / TOOLKIT.ZIP / KERNEL.SC < prev    next >
Encoding:
Text File  |  1990-08-25  |  28.1 KB  |  625 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
  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 If Not Retval     ;Key wasn't accepted, or was
  164.                                Then Loop      ; reset to a new value
  165.                             Endif
  166.                     Endif
  167.             Endif
  168.             Retval = True
  169.             Switch
  170.                Case Search(TKKeyType,"XS") <> 0 : ;Processed next Switch stmnt
  171.                Case IsValid() :                   ;Good Depart
  172.                   If Search("D",TKAction[TKFieldNum]) <> 0
  173.                      Then TKChanged = [] <> TKFieldVal ;Changed? Set T/F
  174.                           CallProc(TKGoodDepart[TKFieldNum])
  175.                   Endif
  176.                Otherwise:                         ;Bad Depart
  177.                   If Search("F",TKAction[TKFieldNum]) <> 0
  178.                      Then CallProc(TKBadDepart[TKFieldNum])
  179.                   Endif
  180.             Endswitch
  181.             Switch
  182.                Case TKKeyType = "X" :   ;TKeyType set to "X" by Special key,
  183.                   CheckMessage()        ; Good Depart, or Bad Depart proc
  184.                   Echo Off              ;Exit immediately
  185.                   Return TKChar
  186.                Case Not Retval :        ;Good Depart or Bad Depart rejected
  187.                   Loop                  ; or reassigned TKChar.  Reprocess it.
  188.                Case TKKeyType = "S" :
  189.                   Keypress TKChar
  190.                Case IsValid() :         ;Field data is valid, pending key is
  191.                   ExecProc TKMvmntProc  ; a movement key ("S" or "M")
  192.                   If Search(TKKeyType,"EX") <> 0
  193.                      Then CheckMessage()  ;Movement-initiated proc or pending
  194.                           Echo Off        ; key requested exit from DoWait
  195.                           Return TKChar
  196.                   Endif
  197.                   If Not Retval         ;Movement-initiated proc rejected
  198.                      Then Loop          ; pending key
  199.                   Endif
  200.                Otherwise :     ;Data is still invalid, can't move out of it
  201.                  If (TKChar = -83 or TKChar = 21 or TKChar = 0) and
  202.                     TKKeyType <> "E"   ;If Del, Undo, or Cancel is an Exit key
  203.                     Then BadDelUndo()  ; reject it since data is invalid
  204.                          If Search(TKKeyType,"EX") <> 0
  205.                             Then CheckMessage()
  206.                                  Echo Off
  207.                                  Return TKChar
  208.                          Endif
  209.                          If not Retval
  210.                             Then Loop
  211.                          Endif
  212.                     Else If IsBlank(TKMessage)  ;Display standard Paradox
  213.                             Then Keypress -72   ; message unless specified
  214.                          Endif                  ; otherwise in user procedure
  215.                  Endif
  216.             Endswitch
  217.       Endswitch
  218.       CheckMessage()          ; Check for message to display
  219.       ExecProc TKKeyProc      ; Read next key
  220.       Echo Normal
  221.    Endwhile
  222. Endproc
  223.  
  224. ; This procedure is called by DoWait before a key is read from the keyboard.
  225. ; The procedure checks the variable TKMessage, and sends that message to the
  226. ; screen if it is non-blank.
  227. ;
  228. Proc CheckMessage()
  229.    If TKMessage <> ""    ;Has the user specified a message?
  230.       Then Echo Off
  231.            Message TKMessage
  232.            SyncCursor
  233.            TKMessage = ""       ;Re-initialize to show no pending message
  234.    Endif
  235.    TKAccept = True
  236. Endproc
  237.  
  238. ; This procedure examines the user-defined variable TKHoldCanvas, and turns
  239. ; echo to normal if the programmer hasn't prohibited it.  DoWait calls
  240. ; CheckHoldCanvas to update the current echo status.
  241. ;
  242. Proc CheckHoldCanvas()
  243.    If TKHoldCanvas
  244.       Then TKHoldCanvas = False ;Re-initialize to allow removal of PAL canvas
  245.       Else Echo Normal
  246.    Endif
  247. Endproc
  248.  
  249. ; This procedure calls a user-specified procedure, checks to see whether to
  250. ; turn echo back to normal upon return from the procedure, and determines
  251. ; whether the key that was pressed in order to invoke the procedure was
  252. ; accepted "as is" by that procedure.
  253. ;
  254. ; The procedure takes one argument, which is the name of the procedure to
  255. ; call. It returns False if the procedure does not accept the character which
  256. ; was passed to it (resets TKChar or sets TKAccept to False), or True
  257. ; otherwise.
  258. ;
  259. Proc CallProc(ProcName)
  260. ; Private ProcName               ;Name of procedure to be called
  261.    TKUserKey = TKChar            ;Remember the key that was passed to the proc
  262.    ExecProc ProcName
  263.    CheckHoldCanvas()             ;Turn echo back to normal if appropriate
  264.    If TKKeyType = "X"            ;Exit immediately from DoWait?
  265.       Then Return
  266.    Endif
  267.    If TKAccept                   ;Was TKChar accepted and unchanged?
  268.       Then If TKUserKey = TKChar
  269.               Then Return True
  270.            Endif
  271.       Else CheckMessage()        ;Get new character
  272.            ExecProc TKKeyProc
  273.            Echo Normal
  274.    Endif
  275.    Return False
  276. Endproc
  277.  
  278. ; This procedure keypresses a cursor movement key and then calls the
  279. ; ArriveMvmnt procedure to initialize any necessary table, record, or field
  280. ; level events.  DoWait calls RecMvmnt only after the appropriate good or bad
  281. ; depart procedure is executed.
  282. ;
  283. ; Note that since there is no way of knowing whether Undo will cause movement
  284. ; out of the current table, RecMvmnt will NOT call a Table Depart even if
  285. ; Undo does move the cursor to another table.  See also ArriveMvmnt below.
  286. ;
  287. ; In addition to this function, the RecMvmnt procedure checks to see
  288. ; whether the movement key that was pressed was [Zoom].  This is necessary
  289. ; because [Zoom] doesn't actually cause movement into a new field until after
  290. ; a value has been entered at the zoom prompt and [Enter] has been pressed.
  291. ; Thus we must pause and wait for this to occur before actually arriving into
  292. ; a new field.
  293. ;
  294. Proc RecMvmnt()
  295.  
  296.    If TKChar = 26                     ;Zoom key?
  297.       Then WaitZoom()                 ;Special Zoom handling procedure
  298.            If not Retval              ;User cancelled Zoom
  299.               Then Return False
  300.            Endif
  301.            TKRecMvmnt = True          ;Zoom always initiates rec-level depart
  302.       Else CheckRecMove()             ;Record departure key?
  303.    Endif
  304.    If TKRecMvmnt and TKRecDepart <> "" ;Call rec-level depart if necessary
  305.       Then CallProc(TKRecDepart)
  306.            If TKKeyType = "X"          ;Check for request to immediate exit
  307.               Then Return
  308.            Endif
  309.            If Not Retval               ;Key rejected or reassigned
  310.               Then Return False
  311.            Endif
  312.    Endif
  313.    Retval = True
  314.    If (TKChar = -61 or TKChar = -62) and TKTblDepart <> ""
  315.       Then CallProc(TKTblDepart)      ;Call table-level depart if necessary
  316.    Endif
  317.    If Search(TKKeyType,"EX") <> 0     ;Check for normal or immediate exit
  318.       Then Return
  319.    Endif
  320.    If Not Retval                      ;Key rejected or reassigned
  321.       Then Return False
  322.    Endif
  323.    ArriveMvmnt()             ;Initiate table->record->field arrival sequence
  324.    Return True
  325. Endproc
  326.  
  327. ; This procedure initiates the event arrival sequence for a movement key
  328. ; and the special invalid-field Undo, Del, Cancel case.  RecMvmnt calls this
  329. ; procedure to "press" a movement key.  ArriveMvmnt, in turn, will call the
  330. ; appropriate arrival procedures.
  331. ;
  332. ; If the Undo key causes movement to another table, ArriveMvmnt will properly
  333. ; call the table and record arrival events for the new table (your procedures
  334. ; consider this possibility).
  335. ;
  336. Proc ArriveMvmnt()
  337.  
  338.    Keypress TKChar
  339.    If ImageNo() <> TKImgNo        ;Did we move to a new table?
  340.       Then TKRecMvmnt = True      ;Will be arriving in a new record
  341.            SysTblArrive()         ;Call Table Arrive if assigned
  342.    Endif
  343.    If TKRecMvmnt                  ;Need to call record arrival procedure?
  344.       Then SysRecArrive()         ; (Did we just leave a record?)
  345.    Endif
  346.    SysArrive()                    ;Call field arrival procedure
  347.  
  348. Endproc
  349.  
  350. ; This procedure initiates a movement-arrival sequence for tables which
  351. ; do not have record-level events assigned to them.  See RecMvmnt above
  352. ; for more information.
  353. ;
  354. Proc StdMvmnt()
  355.  
  356.    If TKChar = 26                  ;Zoom key?
  357.       Then WaitZoom()              ;Call special Zoom handling procedure
  358.            If not Retval           ;Zoom not initiated
  359.               Then Return False
  360.            Endif
  361.            Enter                   ;Zoom!
  362.            SysArrive()             ;Arriving in new field, call field arrival
  363.            Return True             ; event
  364.    Endif
  365.    Retval = True
  366.    If (TKChar = -61 or TKChar = -62) and TKTblDepart <> ""
  367.       Then CallProc(TKTblDepart)   ;Call table depart, if assigned
  368.    Endif
  369.    If Search(TKKeyType,"EX") <> 0  ;Check for normal or immediate exit
  370.       Then Return
  371.    Endif
  372.    If Not Retval
  373.       Then Return False
  374.    Endif
  375.    Keypress TKChar
  376.    If TKChar = -61 or TKChar = -62  ;If key caused normal movement to another
  377.       Then SysTblArrive()           ; table, invoke table arrival procedure
  378.    Endif
  379.    SysArrive()                      ;Reset field-dependent variables--
  380.    Return True                         ; we are in a new field
  381. Endproc
  382.  
  383. ; This procedure determines whether a pending movement key should initiate a
  384. ; record-level event.  It requires key movement codes defined by SetUpDoWait
  385. ; and additional image-specific information.
  386. ;
  387. Proc CheckRecMove()
  388.  
  389.    If TKChar > 0           ;Determine type of key we are about to process
  390.       Then TKMvTyp = Substr(TKPosMv,TKChar,1)   ;These statements are
  391.       Else TKMvTyp = Substr(TKNegMv,1-TKChar,1) ; necessary because max
  392.    Endif                                         ; string length is 255
  393.  
  394.    TKRecMvmnt = False      ;Assume no record-level event will be generated
  395.  
  396.    If IsFormView()         ;Form view case
  397.       Then Switch
  398.               Case NPages() = 1 :  ; Only one page, PgUp/PgDn cause rec-event
  399.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  400.                     Then TKRecMvmnt = True
  401.                  Endif
  402.               Case PageNo() = 1 :  ; First page, PgUp causes rec-event
  403.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  404.                     Then TKRecMvmnt = True
  405.                  Endif
  406.               Case PageNo() = NPages() :   ; Last page, PgDn causes rec-event
  407.                  If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  408.                     Then TKRecMvmnt = True
  409.                  Endif
  410.            Endswitch
  411.       Else If Search(TKMvTyp,TKAction[TKFieldNum]+"") <> 0
  412.               Then TKRecMvmnt = True
  413.            Endif
  414.    Endif
  415.  
  416. Endproc
  417.  
  418. ; This procedure handles the special case in which a user invokes the Zoom
  419. ; command.  It only allows a user to exit from Zoom by pressing either [Enter]
  420. ; or [Esc] (same as [Cancel]).  Note that while a user is at the Zoom prompt,
  421. ; DoWait performs no special processing.  An attempt to initiate a Zoom will
  422. ; invoke a record-level event.
  423. ;
  424. Proc WaitZoom()
  425.  
  426.    Zoom                        ;Display Zoom prompt
  427.    While True
  428.       TKChar = GetChar()         ;Read key
  429.       Switch
  430.          Case TKChar = 13 :       ;Zoom should be acted upon
  431.             Return True
  432.          Case TKChar = 27 or TKChar = 0 :    ;Zoom not acted upon
  433.             Esc
  434.             ExecProc TKKeyProc     ;Process next key
  435.             Return False
  436.          Case TKChar > 31          ;Press only keys valid at Zoom prompt
  437.            or TKChar = 6 or TKChar = -108 or TKChar = 8
  438.            or (TKChar < -70 and TKChar > -84)
  439.            or (TKChar < -114 and TKChar > -120) :
  440.             Keypress TKChar
  441.          Otherwise :               ;Reject illegal keys
  442.             Beep
  443.       Endswitch
  444.    Endwhile
  445.  
  446. Endproc
  447.  
  448. ; This procedure reads a character from the keyboard buffer.  It
  449. ; facilitates the keyboard inactivity event and maintains the single-key
  450. ; type-ahead buffer. It is called by DoWait, CallProc, and WaitZoom when a
  451. ; new key is to be processed.
  452. ;
  453. ; A keyboard inactivity procedure, if assigned, is called once a second.  The
  454. ; variable TKSeconds, available to the procedure, specifies the number of
  455. ; seconds elapsed without a keypress (equal to the number of times the
  456. ; inactivity procedure has been called in a row).
  457. ;
  458. ; DoWait will act upon TKBuffer, if set equal to an ASCII or IBM Extended
  459. ; code, as if a user had actually pressed the key.  The keycode in TKBuffer
  460. ; take precedence over any keys already in the acutal keyboard buffer.
  461. ;
  462. Proc GetInactive()
  463.    TKSeconds = 0                 ;Reset TKSeconds after last keypress
  464.    While True
  465.       If IsBlank(TKBuffer)       ;Check for a key in TKBuffer
  466.          Then TKTime = Time()    ;Wait (a second) for a character
  467.               While Not CharWaiting() and TKTime = Time()
  468.               Endwhile
  469.               If CharWaiting()   ;Key pressed, read keycode
  470.                  Then TKChar = GetChar()
  471.                       Quitloop
  472.                  Else TKSeconds = TKSeconds + 1  ;No key pressed, call
  473.                       TKHoldCanvas = True        ; inactivity procedure
  474.                       ExecProc TKInactiveProc
  475.                       CheckHoldCanvas()          ;Check canvas status
  476.                       CheckMessage()             ;Check for message to display
  477.               Endif
  478.          Else TKChar = TKBuffer     ;TKBuffer has a keycode.  Process it ahead
  479.               TKBuffer = BlankNum() ; of the keycode in acutal buffer, and
  480.               Quitloop              ; reset TKBuffer
  481.       Endif
  482.    Endwhile
  483. Endproc
  484.  
  485. ; This procedure reads a character from the keyboard buffer.  It is called
  486. ; instead of GetInactive() if a keyboard inactivity procedure has not been
  487. ; defined.  GetKey() executes much faster than GetInactive().  Note that
  488. ; applications which do not use an inactivity procedure can still make use
  489. ; of TKBuffer.
  490. ;
  491. Proc GetKey()
  492.    If IsBlank(TKBuffer)
  493.       Then TKChar = GetChar()
  494.       Else TKChar = TKBuffer
  495.            TKBuffer = BlankNum()
  496.    Endif
  497. Endproc
  498.  
  499. ; This procedure is called by DoWait when Undo, Del, or Cancel (Ctrl-Break)
  500. ; is pressed and accepted while the information in the current field is
  501. ; invalid.  Special handling is needed in these cases, as we do not want to
  502. ; allow exit from the WAIT while information in a field is invalid.  At the
  503. ; same time, we recognize that pressing Undo, Del, or Cancel will
  504. ; automatically cause the field to be valid (by simply removing or changing
  505. ; the entire record).
  506. ;
  507. ; The problem that must be dealt with is that if Undo, Del, or Cancel is
  508. ; defined as an exit character, we must give control back to the program
  509. ; BEFORE either of these keys is pressed (acted upon).  Thus we do not know
  510. ; whether the key will be pressed at all.  This is not a problem if these
  511. ; keys are defined as move characters, as the keys will be pressed
  512. ; automatically (assuring the validity of the field).
  513. ;
  514. Proc BadDelUndo()
  515.  
  516.    TKMessage = ""        ;Any user-defined message was most likely put
  517.                          ; up in error, as field will now become valid
  518.    If TKRecMvmnt and TKRecDepart <> ""  ;Del, Undo, or Cancel will cause
  519.       Then CallProc(TKRecDepart)        ; a record-level event
  520.            If TKKeyType = "X"           ;Check for immediate exit request
  521.               Then Return
  522.            Endif
  523.            If Not Retval                ;Key rejected by rec-depart proc
  524.               Then Return False
  525.            Endif
  526.    Endif
  527.    ArriveMvmnt()        ;Initiate event arrival sequence
  528.    Return True
  529.  
  530. Endproc
  531.  
  532. ; NewField is called by DoWait whenever a new field is entered.  It is
  533. ; responsible for setting all field-dependent variables.  You may call this
  534. ; procedure instead of ArriveField if one of your procedures causes explicit
  535. ; movement into a new field and you wish to inhibit invocation of the arrival
  536. ; procedure for the new field.
  537. ;
  538. Proc NewField()
  539.    TKFieldVal = []                         ;Get field entry value and index
  540.    TKFieldNum = ColNo()                    ; into arrays for current field
  541. Endproc
  542.  
  543. ; ArriveField alerts DoWait that one of your procedures has just explicitly
  544. ; moved into a new field and that DoWait should call the arrival procedure
  545. ; for the new field.  Your procedures MUST call this procedure (or NewField)
  546. ; if they cause explicit movement into another field (using MOVETO or Right,
  547. ; for example).
  548. ;
  549. Proc ArriveField()
  550.    CheckHoldCanvas()            ;Update canvas status
  551.    SysArrive()                  ;Initiate field arrival
  552. Endproc
  553.  
  554. ; SysArrive initiates all actions associated with entering a field, including
  555. ; calling the appropriate arrival procedure if assigned.
  556. ;
  557. Proc SysArrive()
  558.    NewField()
  559.    If Search("A",TKAction[TKFieldNum]) <> 0 ;Is an arrival procedure assigned?
  560.       Then ExecProc TKArrive[TKFieldNum]
  561.            CheckHoldCanvas()
  562.    Endif
  563.    TKAccept = False  ;If a keystroke is pending (which could happen if this
  564. Endproc              ; proc were called from a user's proc), then ignore it
  565.  
  566. ; ArriveRecord initiates all actions associated with arriving into a new
  567. ; record.  Your procedures can call ArriveRecord to invoke a record-level
  568. ; arrival procedure for a table.
  569. ;
  570. Proc ArriveRecord()
  571.    CheckHoldCanvas()    ;Check canvas status
  572.    SysRecArrive()
  573. Endproc
  574.  
  575. ; SysRecArrive initializes field dependent variables and executes a record-
  576. ; level procedure for a table, if assigned.
  577. ;
  578. Proc SysRecArrive()
  579.    NewField()                   ;Initialize field variables
  580.    If TKRecArrive <> ""         ;Call record arrival proc if assigned
  581.       Then ExecProc TKRecArrive
  582.            CheckHoldCanvas()
  583.    Endif
  584.    TKAccept = False  ;If a key is pending (which could happen if this
  585. Endproc              ; proc were called from a user's proc), ignore it
  586.  
  587. ; This procedure initializes the DoWait procedure assignment variables
  588. ; when entering a new table image, but does not call a table arrival
  589. ; procedure if one is assigned.
  590. ;
  591. Proc NewTable()
  592.    ExecProc TKDPASet[ImageNo()]+Form()
  593.    TKKeyProc = "GetInactive"
  594.    If IsBlank(TKInactiveProc)     ;Select which keyboard procedure to use
  595.       Then TKKeyProc = "GetKey"
  596.    Endif
  597.    TKRecMvmnt = True
  598.    If TKMvmntProc = "StdMvmnt"    ;Select which movement procedure to use
  599.       Then TKRecMvmnt = False
  600.    Endif
  601.    TKImgNo = ImageNo()            ;Determine current image number
  602.    NewField()                     ;Initialize field dependent variables
  603. Endproc
  604.  
  605. ; This procedure is called upon entry into a new table image by NewImage, and
  606. ; subsequently calls a table arrival procedure for the new table if one is
  607. ; assigned.
  608. ;
  609. Proc ArriveTable()
  610.    CheckHoldCanvas()         ;Update canvas status
  611.    SysTblArrive()
  612. Endproc
  613.  
  614. ; This procedure initializes DoWait procedure assignment information and
  615. ; calls a table arrival procedure for the new table if assigned.
  616.  
  617. Proc SysTblArrive()
  618.    NewTable()        ;Define DPA set variables
  619.    If TKTblArrive <> ""
  620.       Then ExecProc TKTblArrive
  621.            CheckHoldCanvas()
  622.    Endif
  623.    TKAccept = False  ;If a keystroke is pending (which could happen if this
  624. Endproc              ; proc were called from a user's proc), then ignore it
  625.