home *** CD-ROM | disk | FTP | other *** search
- /***
- * Getex04.prg
- *
- * Get reader calling code block after each keystroke
- *
- * The example "on key block" uses a TBrowse object to display just the
- * records matching the entered key.
- *
- * N.B. - The TBrowse routines used in here are included in the
- * TBrowse paper's library and documented therein
- */
-
- #include "Getexit.ch"
- #include "Setcurs.ch"
-
- #command @ <row>, <col> GET <var> ;
- [<clauses,...>] ;
- ON KEY <b> ;
- [<moreClauses,...>] ;
- ;
- => @ <row>, <col> GET <var> ;
- [<clauses>] ;
- SEND reader := {|oGet| OnKeyReader(oGet, <{b}> ) } ;
- [<moreClauses>]
-
- #define INC_LAST(c) Substr(c, 1, Len(c) - 1) + ;
- Chr(Asc(Substr(c, 1, Len(c))) + 1)
-
- #define K_PLUS 43
- #define K_MINUS 45
-
- #define WIN_TOP 12
- #define WIN_LEFT 30
- #define WIN_BOTTOM 23
- #define WIN_RIGHT 79
-
- // Default column separator
- #define DEF_CSEP " " + chr(179) + " "
-
- // Default heading separator
- #define DEF_HSEP chr(205) + chr(209) + chr(205)
-
- // Default footing separator
- #define DEF_FSEP chr(205) + chr(207) + chr(205)
-
-
- MEMVAR GetList
-
- FUNCTION Getex04
-
- FIELD Lname, Fname, Addr1, AcBal IN Tbdbf1
-
- LOCAL cSearcher := ""
- LOCAL cLname
- LOCAL bFirst := {|| DbSeek(cSearcher) }
- LOCAL bLast := {|| iif(Empty(cSearcher), ;
- DbGoBottom(), ;
- (DbSeek(INC_LAST(cSearcher), .T.), ;
- DbSkip(-1))) }
-
- LOCAL bWhile := {|| Upper(Lname) = cSearcher }
- LOCAL bFor := {|| .T. }
- LOCAL oTbr := TBForWhile(bFirst, bLast, bFor, bWhile)
- LOCAL oTbc
- LOCAL cSaveScr := SaveScreen(WIN_TOP, WIN_LEFT, ;
- WIN_BOTTOM, WIN_RIGHT)
-
- oTbc := TBColumnNew("Last Name", {|| Lname })
- oTbc:width := 15
- oTbr:addColumn(oTbc)
-
- oTbc := TBColumnNew("First Name", {|| Fname })
- oTbc:width := 10
- oTbr:addColumn(oTbc)
-
- oTbc := TBColumnNew("Address", {|| Addr1 })
- oTbc:width := 15
- oTbr:addColumn(oTbc)
-
- oTbc := TBColumnNew("Balance", {|| AcBal })
- oTbc:width := 15
- oTbr:addColumn(oTbc)
-
- USE TbDbf1
- IF !File("Tbdbf1.ntx")
- INDEX ON Upper(Lname + Fname) TO Tbdbf1
- ELSE
- SET INDEX TO Tbdbf1
- ENDIF
-
- CLEAR SCREEN
- cSaveScr := SaveScreen(WIN_TOP, WIN_LEFT, ;
- WIN_BOTTOM, WIN_RIGHT)
- @ WIN_TOP, WIN_LEFT CLEAR TO WIN_BOTTOM, WIN_RIGHT
- @ WIN_TOP, WIN_LEFT TO WIN_BOTTOM, WIN_RIGHT
- oTbr:nTop := WIN_TOP + 1
- oTbr:nLeft := WIN_LEFT + 1
- oTbr:nBottom := WIN_BOTTOM - 1
- oTbr:nRight := WIN_RIGHT - 1
- oTbr:autoLite := .F.
-
- // Kick-start the TBrowse window
- TBDisplay(oTbr)
-
- cLname := Space(Len(Lname))
- @ 10, 10 SAY "Enter Lname" GET cLname ;
- ON KEY {|o| cSearcher := Upper(Trim(o:buffer)), ;
- TBDisplay(oTbr) }
- READ
-
- RestScreen(WIN_TOP, WIN_LEFT, WIN_BOTTOM, WIN_RIGHT, cSaveScr)
-
- RETURN NIL
-
-
- proc OnKeyReader( Get, b )
-
- LOCAL nKey
-
- // read the GET if the WHEN condition is satisfied
- IF ( GetPreValidate(get) )
- // activate the GET for reading
- get:SetFocus()
-
- DO WHILE ( get:exitState == GE_NOEXIT )
- // check for initial typeout (no editable positions)
- IF ( get:typeOut )
- get:exitState := GE_ENTER
- ENDIF
-
- // apply keystrokes until exit
- DO WHILE ( get:exitState == GE_NOEXIT )
- nKey := InKey(0)
- GetApplyKey(get, nKey)
- Eval(b, Get)
- ENDDO
-
- // disallow exit if the VALID condition is not satisfied
- IF ( !GetPostValidate(get) )
- get:exitState := GE_NOEXIT
- ENDIF
- ENDDO
-
- // de-activate the GET
- get:KillFocus()
- ENDIF
-
- RETURN
-
-
- FUNCTION TBDisplay(oTbr)
-
- LOCAL nSaveRow, nSaveCol
- LOCAL nSaveCurs
-
- nSaveRow := Row()
- nSaveCol := Col()
-
- nSaveCurs := SetCursor(SC_NONE)
-
- oTbr:goTop()
- oTbr:refreshAll()
- FullStabilize(oTbr)
-
- SetCursor(nSaveCurs)
- @ nSaveRow, nSaveCol SAY ""
-
- RETURN NIL
-
-
- FUNCTION TBForWhile(bFirst, bLast, bFor, bWhile)
-
- LOCAL oTbr := TBrowseNew()
-
- oTbr:goTopBlock := {|| TBFwFirst(bFirst, bWhile, bFor) }
- oTbr:goBottomBlock := {|| TBFwLast(bLast, bWhile, bFor) }
- oTbr:skipBlock := {|n| TBFwSkip(n, bWhile, bFor) }
-
- oTbr:headSep := DEF_HSEP
- oTbr:footSep := DEF_FSEP
- oTbr:colSep := DEF_CSEP
-
- RETURN oTbr
-
-
- FUNCTION TBFwFirst(bGoFirst, bWhile, bFor)
-
- eval(bGoFirst)
- DO WHILE !eof() .AND. eval(bWhile) .AND. !eval(bFor)
- SKIP
- ENDDO
-
- IF !eval(bWhile)
- // no records match filter - could also be at eof already here
- GOTO 0
- ENDIF
-
- RETURN NIL
-
-
- FUNCTION TBFwLast(bGoLast, bWhile, bFor)
-
- eval(bGoLast)
- DO WHILE !bof() .AND. eval(bWhile) .AND. !eval(bFor)
- SKIP -1
- ENDDO
-
- IF bof() .OR. !eval(bWhile)
- // No records match scope
- GOTO 0
- ENDIF
-
- RETURN NIL
-
-
- FUNCTION TBFwSkip(nToSkip, bWhile, bFor)
-
- LOCAL nSkipped := 0, ;
- nLastValidRecNum := Recno()
-
- IF nToSkip = 0
- SKIP 0
- RETURN 0
- ENDIF
-
- IF nToSkip > 0
- DO WHILE nSkipped < nToSkip .AND. !eof() .AND. eval(bWhile)
- SKIP
- // Note the last clause here makes a big speed difference
- DO WHILE !eval(bFor) .AND. !eof() .AND. eval(bWhile)
- SKIP
- ENDDO
- IF Eval(bWhile) .AND. !eof()
- // Found a new record matching the scope
- nSkipped++
- nLastValidRecNum := Recno()
- ENDIF
- ENDDO
-
- IF eof() .OR. !eval(bWhile)
- GOTO nLastValidRecNum
- ENDIF
- ELSE
- DO WHILE nSkipped > nToSkip .AND. !bof() .AND. eval(bWhile)
- SKIP -1
- // Note the last clause here makes a big speed difference
- DO WHILE !eval(bFor) .AND. !bof() .AND. eval(bWhile)
- SKIP -1
- ENDDO
- IF Eval(bWhile) .AND. !bof()
- nSkipped--
- nLastValidRecNum := Recno()
- ENDIF
- ENDDO
- IF !eval(bWhile) .OR. bof()
- GOTO nLastValidRecNum
- ENDIF
- ENDIF
-
- RETURN nSkipped
-
-
- FUNCTION FullStabilize(oTbr)
-
- DO WHILE !oTbr:stabilize()
- ENDDO
-
- RETURN NIL