home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
database
/
kbrows.zip
/
KEVBROWS.PRG
< prev
next >
Wrap
Text File
|
1993-05-30
|
50KB
|
1,428 lines
******************************************************************************
* KBROWSE - Kevin's Rapid Access File Browser
*
* m_list = Kbrowse(<tlr>,<tlc>,<brr>,<brc>,<array>,<retexp>,;
* <headsep>,<colsep>,@<marked>,<frozen>)
*
* <tlr> = top left row coordinate; default = 0
* <tlc> = top left column coordinate; default = 0
* <brr> = bottom right row coordinate; default = 24
* <brc> = bottom right column coordinate; default = 79
* <array> = multi-dimensional array of display information:
* <array>[x][1] = column title
* <array>[x][2] = code block to return column contents
* Optional array elements:
* <array>[x][3] = index order if active searching
* <array>[x][4] = search string picture clause
* <array>[x][5] = upper key value if limiting the browse
* <array>[x][6] = lower key value if limiting the browse
* <retexp> = code block to return an expression to the caller
* <headsep> = string of header separators
* <colsep> = string of column separators
* @<marked> = array to hold marked RECNO()'s, null for no marking
* <frozen> = number of columns to freeze from left to right
*
* Source Code Example:
*
* m_tlr = 04
* m_tlc = 01
* m_brr = 20
* m_brc = 78
* m_headsep = "═╤═"
* m_colsep = " │ "
* m_freeze = 0
* m_marked = {}
* m_retexp = { || A->lastname}
* m_array = {;
* { "Last Name" , { || A->lastname}, 1, "@!" },; && use index 1, uppercase the search string
* { "First Name" , { || A->firstname} },;
* { "I" , { || A->initial} },;
* { "Marked" , { || IIF(ASCAN(m_marked,RECNO()) = 0," ","√") } }; && a marked record display function
* }
* m_retval = Kbrowse(m_tlr,m_tlc,m_brr,m_brc,m_array,m_retexp,;
* m_headsep,m_colsep,@m_marked,m_freeze)
******************************************************************************
FUNCTION Kbrowse(nParTlr,nParTlc,nParBrr,nParBrc,aColInfo,cRetExp,;
cHeadSep,cColSep,aMarked,nFreeze)
* memvar declarations
LOCAL cSaveColor && stores current color setting
LOCAL nSaveCursor && stores current cursor setting
LOCAL nTlr && top left screen row coordinate
LOCAL nTlc && top left screen column coordinate
LOCAL nBrr && bottom right screen row coordinate
LOCAL nBrc && bottom right screen column coordinate
LOCAL nPtr1 && general purpose counter
LOCAL nPtr2 && general purpose counter
LOCAL aFldArray && used to load the structure of a database file
LOCAL aCtrlArray && array of parsed column information
LOCAL nCtrlTop && pointer to leftmost displayed column
LOCAL nCtrlPtr && pointer to current displayed column
LOCAL nCtrlBot && pointer to rightmost displayed column
LOCAL nRowTop && top screen row for database info
LOCAL nRowPtr && current screen row for database info
LOCAL nRowBot && bottom screen row for database info
LOCAL nColTop && left screen column for database info
LOCAL nColBot && right screen row for database info
LOCAL nRecordTop && number of top displayed record
LOCAL nRecordPtr && number of current displayed record
LOCAL nRecordBot && number of bottom displayed record
LOCAL nRecRowBot && last used lower screen row
LOCAL nHeadRow && screen row for header information
LOCAL nKeyPress && holds operator keystroke
LOCAL cSeekVar && holds current seek string
LOCAL nOldRecno && pointer to previous record prior to seek
LOCAL nNtxOrder && holds the current index order
LOCAL nNewOrder && used to test for index order change
LOCAL nPickPtr && used during ASCAN of marked record array
LOCAL cDataType && used to parse the type of column expression
LOCAL nDataLen && used to parse the maximum length of the column
LOCAL cNtxPicture && used to parse the search column picture clause
LOCAL cNtxTopKey && used to parse the search column top key value
LOCAL cNtxBotKey && used to parse the search column bottom key value
LOCAL lHeaders && indicates the need to draw headers or not
* assign screen coordinates
nTlr = IIF(nParTlr = NIL, 0, nParTlr)
nTlc = IIF(nParTlc = NIL, 0, nParTlc)
nBrr = IIF(nParBrr = NIL, 24, nParBrr)
nBrc = IIF(nParBrc = NIL, 79, nParBrc)
* load the control array
aCtrlArray = {}
IF aColInfo <> NIL
* load the control array from the passed array
FOR nPtr1 = 1 TO LEN(aColInfo)
IF VALTYPE(aColInfo[nPtr1]) <> "A"
LOOP
ENDIF
IF LEN(aColInfo[nPtr1]) >= 2
cDataType = VALTYPE(EVAL(aColInfo[nPtr1][2]))
nDataLen = 0
nNtxOrder = 0
cNtxPicture = ""
cNtxTopKey = ""
cNtxBotKey = ""
DO CASE
CASE cDataType = "C"
nDataLen = LEN(EVAL(aColInfo[nPtr1][2]))
CASE cDataType = "D"
nDataLen = LEN(DTOC(DATE()))
CASE cDataType = "N"
nDataLen = LEN(STR(EVAL(aColInfo[nPtr1][2])))
CASE cDataType = "L"
nDataLen = 1
ENDCASE
IF nDataLen > 0
IF LEN(aColInfo[nPtr1][1]) > nDataLen
nDataLen = LEN(aColInfo[nPtr1][1])
ENDIF
IF LEN(aColInfo[nPtr1]) >= 4
nNtxOrder = aColInfo[nPtr1][3]
cNtxPicture = aColInfo[nPtr1][4]
ENDIF
IF LEN(aColInfo[nPtr1]) >= 5
cNtxTopKey = aColInfo[nPtr1][5]
IF LEN(aColInfo[nPtr1]) >= 6
cNtxBotKey = aColInfo[nPtr1][6]
ELSE
cNtxBotKey = cNtxTopKey
ENDIF
ENDIF
ENDIF
AADD(aCtrlArray, { -1,; && display column number
nDataLen,; && width of the column
aColInfo[nPtr1][1],; && column title text
aColInfo[nPtr1][2],; && column item expression
nNtxOrder,; && search index order
cNtxPicture,; && search index picture
cNtxTopKey,; && upper key value
cNtxBotKey; && lower key value
} )
ENDIF
NEXT
ENDIF
IF LEN(aCtrlArray) = 0
* load the control array from database fields
aFldArray = DBSTRUCT()
FOR nPtr1 = 1 TO LEN(aFldArray)
IF aFldArray[nPtr1][2] $ "CDLN"
IF LEN(aFldArray[nPtr1][1]) > aFldArray[nPtr1][3]
AADD(aCtrlArray, { -1,;
LEN(aFldArray[nPtr1][1]),;
aFldArray[nPtr1][1],;
&("{|| " + aFldArray[nPtr1][1] + "}"),;
0,;
"",;
"",;
"";
} )
ELSE
AADD(aCtrlArray, { -1,;
aFldArray[nPtr1][3],;
aFldArray[nPtr1][1],;
&("{|| " + aFldArray[nPtr1][1] + "}"),;
0,;
"",;
"",;
"";
} )
ENDIF
ENDIF
NEXT
ENDIF
IF LEN(aCtrlArray) = 0
RETURN ""
ENDIF
* scan for column headers
lHeaders = .F.
FOR nPtr1 = 1 TO LEN(aCtrlArray)
IF LEN(aCtrlArray[nPtr1][3]) <> 0
lHeaders = .T.
EXIT
ENDIF
NEXT
* check the rest of the parameters
IF cRetExp = NIL
cRetExp = { || RECNO() }
ENDIF
IF cHeadSep = NIL
cHeadSep = "═╤═"
ENDIF
IF cColSep = NIL
cColSep = " │ "
ENDIF
IF aMarked = NIL
aMarked = ""
ENDIF
IF nFreeze = NIL
nFreeze = 0
ENDIF
* initialize working memvars
nCtrlTop = 1
nCtrlPtr = 1
nCtrlBot = 1
nRowTop = nTlr
nRowPtr = nTlr
nRowBot = nBrr
nColTop = nTlc
nColBot = nBrc
nHeadRow = nTlr
nRecordTop = RECNO()
nRecordPtr = RECNO()
nRecordBot = RECNO()
IF lHeaders
* adjust display to allow for headers
nRowTop += 2
nRowPtr = nRowTop
ENDIF
nRecRowBot = nRowTop
cSeekVar = ""
nNtxOrder = INDEXORD()
cNtxTopKey = ""
cNtxBotKey = ""
nNewOrder = nNtxOrder
cSaveColor = SETCOLOR()
nSaveCursor = SETCURSOR()
* check for an index key limit
IF nNtxOrder <> 0
FOR nPtr1 = 1 TO LEN(aCtrlArray)
IF aCtrlArray[nPtr1][5] = nNtxOrder
cNtxTopKey = aCtrlArray[nPtr1][7]
cNtxBotKey = aCtrlArray[nPtr1][8]
EXIT
ENDIF
NEXT
ENDIF
* see if re-positioning is needed
IF LEN(cNtxTopKey) <> 0
IF &(INDEXKEY(0)) < cNtxTopKey .OR. &(INDEXKEY(0)) > cNtxBotKey
SEEK cNtxTopKey
ENDIF
nRecordTop = RECNO()
nRecordPtr = RECNO()
nRecordBot = RECNO()
ENDIF
* initial screen setup
SETCURSOR(0)
DISPBEGIN()
* calculate the column screen positions
KbrowseScr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nColTop,@nColBot,@cColSep)
IF lHeaders
* draw the headers and column seperators
KbrowseHdr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nRowTop,@nColTop,@nRowBot,@nColBot,;
@nHeadRow,@cHeadSep,@cColSep)
ENDIF
* refresh the browse data
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
* main program loop
DO WHILE .T.
* check for an index order switch and process it
IF aCtrlArray[nCtrlPtr][5] <> 0
DISPBEGIN()
nNewOrder = aCtrlArray[nCtrlPtr][5]
IF nNewOrder <> nNtxOrder
cSeekVar = ""
nNtxOrder = nNewOrder
SET ORDER TO nNtxOrder
GO nRecordPtr
cNtxTopKey = ""
cNtxBotKey = ""
FOR nPtr1 = 1 TO LEN(aCtrlArray)
IF aCtrlArray[nPtr1][5] = nNtxOrder
cNtxTopKey = aCtrlArray[nPtr1][7]
cNtxBotKey = aCtrlArray[nPtr1][8]
EXIT
ENDIF
NEXT
IF LEN(cNtxTopKey) <> 0
IF &(INDEXKEY(0)) < cNtxTopKey .OR. &(INDEXKEY(0)) > cNtxBotKey
SEEK cNtxTopKey
ENDIF
ENDIF
FOR nPtr1 = nRowTop TO nRowPtr -1
SKIP - 1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
NEXT
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
ENDIF
nRecordTop = RECNO()
FOR nPtr1 = nRowTop TO nRowBot
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
IF nFreeze > 0
FOR nPtr2 = 1 TO nFreeze
@ nPtr1,aCtrlArray[nPtr2][1] SAY EVAL(aCtrlArray[nPtr2][4])
NEXT
ENDIF
FOR nPtr2 = nCtrlTop TO nCtrlBot
@ nPtr1,aCtrlArray[nPtr2][1] SAY EVAL(aCtrlArray[nPtr2][4])
NEXT
nRecordBot = RECNO()
nRecRowBot = nPtr1
SKIP
NEXT
FOR nPtr1 = nPtr1 TO nRowBot
IF nFreeze > 0
FOR nPtr2 = 1 TO nFreeze
@ nPtr1,aCtrlArray[nPtr2][1] SAY SPACE(aCtrlArray[nPtr2][2])
NEXT
ENDIF
FOR nPtr2 = nCtrlTop TO nCtrlBot
@ nPtr1,aCtrlArray[nPtr2][1] SAY SPACE(aCtrlArray[nPtr2][2])
NEXT
NEXT
GO nRecordTop
nRowPtr = nRowTop
DO WHILE RECNO() <> nRecordPtr .AND. .NOT. EOF()
nRowPtr++
SKIP
ENDDO
nRecordPtr = RECNO()
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
ENDIF
IF LEN(cSeekVar) <> 0
SETCOLOR("W+/N")
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY cSeekVar
SETCOLOR(cSaveColor)
ENDIF
DISPEND()
ENDIF
* wait for a keystroke
nKeyPress = 0
DO WHILE nKeyPress = 0
nKeyPress = INKEY()
IF nKeyPress <> 0
IF SETKEY(nKeyPress) <> NIL
EVAL(SETKEY(nKeyPress), PROCNAME(), PROCLINE(), "NKEYPRESS")
nKeyPress = 0
ENDIF
IF nKeyPress <> 0
EXIT
ENDIF
ENDIF
ENDDO
DO CASE
CASE nKeyPress = 5 && uparrow
cSeekVar = ""
KbrowseUp(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 24 && downarrow
cSeekVar = ""
KbrowseDn(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 18 && pgup
cSeekVar = ""
KbrowsePu(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 3 && pgdn
cSeekVar = ""
KbrowsePd(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 19 && leftarrow
cSeekVar = ""
KbrowseLf(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 4 && rightarrow
cSeekVar = ""
KbrowseRt(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 1 && home
cSeekVar = ""
KbrowseHom(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 6 && end
cSeekVar = ""
KbrowseEnd(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 26 && ctrl-left
cSeekVar = ""
IF nCtrlPtr > 1
KbrowseCLf(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
ENDIF
CASE nKeyPress = 2 && ctrl-right
cSeekVar = ""
IF nCtrlPtr < LEN(aCtrlArray)
KbrowseCRt(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
ENDIF
CASE nKeyPress = 31 && ctrl-pgup
cSeekVar = ""
KbrowseCPu(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 30 && ctrl-pgdn
cSeekVar = ""
KbrowseCPd(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
CASE nKeyPress = 13 && enter
SETCOLOR(cSaveColor)
SETCURSOR(nSaveCursor)
RETURN EVAL(cRetExp)
CASE nKeyPress = 27 && esc
SETCOLOR(cSaveColor)
SETCURSOR(nSaveCursor)
RETURN ""
CASE VALTYPE(aMarked) = "A" .AND. nKeyPress = 32
cSeekVar = ""
nPickPtr = ASCAN(aMarked,RECNO())
IF nPickPtr = 0
AADD(aMarked,RECNO())
ELSE
ADEL(aMarked,nPickPtr)
ASIZE(aMarked,LEN(aMarked)-1)
ENDIF
DISPBEGIN()
FOR nPtr1 = nCtrlTop TO nCtrlBot
@ nRowPtr,aCtrlArray[nPtr1][1] SAY EVAL(aCtrlArray[nPtr1][4])
NEXT
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
KbrowseBot(cNtxTopKey,cNtxBotKey)
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
ELSE
SKIP -1
KbrowseDn(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep)
ENDIF
CLEAR TYPEAHEAD
DISPEND()
CASE aCtrlArray[nCtrlPtr][5] <> 0 .AND. ((nKeyPress >= 32 .AND. nKeyPress <= 122) .OR. nKeyPress = 8)
IF LEN(cNtxTopKey) = 0
KbrowseSrc(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nColTop,@nColBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey,;
@nHeadrow,@cHeadSep,@cColSep,;
@nKeyPress,@cSeekVar,@cSaveColor)
ENDIF
ENDCASE
ENDDO
SETCOLOR(cSaveColor)
SETCURSOR(nSaveCursor)
RETURN ""
******************************************************************************
* KbrowseScr - calculates the displayable columns and screen column positions
******************************************************************************
FUNCTION KbrowseScr(aCtrlArray,nCtrlTop,nCtrlBot,nFreeze,;
nColTop,nColBot,cColSep)
LOCAL nScrnCol
LOCAL nFreezeWidth
LOCAL nWidth
LOCAL nPtr1
nScrnCol = nColTop
nFreezeWidth = 0
IF nFreeze > 0
nFreezeWidth = 1
nScrnCol++
FOR nPtr1 = 1 TO nFreeze
IF nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
aCtrlArray[nPtr1][1] = nScrnCol
nScrnCol = nScrnCol + aCtrlArray[nPtr1][2] + LEN(cColSep)
nFreezeWidth = nFreezeWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
NEXT
IF nCtrlTop <= nFreeze
nCtrlTop = nFreeze + 1
ENDIF
IF nCtrlBot <= nFreeze
nCtrlBot = nFreeze + 1
ENDIF
ENDIF
nWidth = 0
FOR nPtr1 = nCtrlTop TO LEN(aCtrlArray)
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
aCtrlArray[nPtr1][1] = nScrnCol
nScrnCol = nScrnCol + aCtrlArray[nPtr1][2] + LEN(cColSep)
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlBot = nPtr1
NEXT
nWidth = nWidth - LEN(cColSep)
nScrnCol = (nColBot-nColTop-nFreezeWidth+1) - nWidth
IF nScrnCol >= 2
nScrnCol = INT((nScrnCol)/2)
FOR nPtr1 = nCtrlTop TO nCtrlBot
aCtrlArray[nPtr1][1] = aCtrlArray[nPtr1][1] + nScrnCol
NEXT
ENDIF
RETURN NIL
******************************************************************************
* KbrowseHdr - clears screen, draws column headers and separators
******************************************************************************
FUNCTION KbrowseHdr(aCtrlArray,nCtrlTop,nCtrlBot,nFreeze,;
nRowTop,nColTop,nRowBot,nColBot,;
nHeadRow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nPtr2
@ nHeadRow,nColTop CLEAR TO nRowBot,nColBot
IF nFreeze > 0
FOR nPtr1 = 1 TO nFreeze
@ nHeadRow,aCtrlArray[nPtr1][1] SAY aCtrlArray[nPtr1][3]
NEXT
ENDIF
FOR nPtr1 = nCtrlTop TO nCtrlBot
@ nHeadRow,aCtrlArray[nPtr1][1] SAY aCtrlArray[nPtr1][3]
NEXT
@ nHeadRow+1,nColTop SAY REPLICATE(SUBSTR(cHeadSep,1,1),nColBot-nColTop+1)
IF nFreeze > 0
FOR nPtr1 = 1 TO nFreeze
@ nHeadRow+1,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cHeadSep
NEXT
ENDIF
FOR nPtr1 = nCtrlTop TO nCtrlBot-1
@ nHeadRow+1,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cHeadSep
NEXT
FOR nPtr1 = nRowTop TO nRowBot
IF nFreeze > 0
FOR nPtr2 = 1 TO nFreeze
@ nPtr1,aCtrlArray[nPtr2][1] + aCtrlArray[nPtr2][2] SAY cColSep
NEXT
ENDIF
FOR nPtr2 = nCtrlTop TO nCtrlBot-1
@ nPtr1,aCtrlArray[nPtr2][1] + aCtrlArray[nPtr2][2] SAY cColSep
NEXT
NEXT
RETURN NIL
******************************************************************************
* KbrowseDat - refreshes all displayed data, highlights item
******************************************************************************
FUNCTION KbrowseDat(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey)
LOCAL nPtr1
LOCAL nPtr2
LOCAL nPtr3
GO nRecordTop
nRecordPtr = -1
FOR nPtr1 = nRowTop TO nRowBot
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
IF nFreeze > 0
FOR nPtr2 = 1 TO nFreeze
@ nPtr1,aCtrlArray[nPtr2][1] SAY EVAL(aCtrlArray[nPtr2][4])
NEXT
ENDIF
FOR nPtr2 = nCtrlTop TO nCtrlBot
@ nPtr1,aCtrlArray[nPtr2][1] SAY EVAL(aCtrlArray[nPtr2][4])
NEXT
IF nPtr1 = nRowPtr
nRecordPtr = RECNO()
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
ENDIF
nRecordBot = RECNO()
nRecRowBot = nPtr1
SKIP
NEXT
IF nRecordPtr < 0
nRecordPtr = nRecordBot
nRowPtr = nRecRowBot
GO nRecordBot
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
ENDIF
FOR nPtr1 = nPtr1 TO nRowBot
IF nFreeze > 0
FOR nPtr2 = 1 TO nFreeze
@ nPtr1,aCtrlArray[nPtr2][1] SAY SPACE(aCtrlArray[nPtr2][2])
NEXT
ENDIF
FOR nPtr2 = nCtrlTop TO nCtrlBot
@ nPtr1,aCtrlArray[nPtr2][1] SAY SPACE(aCtrlArray[nPtr2][2])
NEXT
NEXT
RETURN NIL
******************************************************************************
* KbrowseSrc - incremental search routine
******************************************************************************
FUNCTION KbrowseSrc(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep,;
nKeyPress,cSeekVar,cSaveColor)
LOCAL cTestVar
DISPBEGIN()
BEGIN SEQUENCE
IF nKeyPress = 8 && backspace
IF LEN(cSeekVar) <> 0
cSeekVar = SUBSTR(cSeekVar,1,LEN(cSeekVar)-1)
IF LEN(cSeekVar) = 0
BREAK
ENDIF
SEEK cSeekVar
IF .NOT. FOUND()
GO nRecordPtr
BREAK
ENDIF
ENDIF
ELSE
cTestVar = TRANSFORM(cSeekVar + CHR(nKeyPress),aCtrlArray[nCtrlPtr][6])
IF cTestVar = &(INDEXKEY(0))
cSeekVar = cTestVar
BREAK
ENDIF
SEEK cTestVar
IF .NOT. FOUND()
GO nRecordPtr
BREAK
ENDIF
cSeekVar = cTestVar
ENDIF
IF RECNO() <> nRecordPtr
nRecordTop = RECNO()
nRecordPtr = RECNO()
nRowPtr = nRowTop
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
ENDIF
END SEQUENCE
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
IF LEN(cSeekVar) <> 0
SETCOLOR("W+/N")
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY cSeekVar
SETCOLOR(cSaveColor)
ENDIF
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseUp - up arrow handler
******************************************************************************
FUNCTION KbrowseUp(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
DO WHILE .T.
SKIP -1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
RETURN NIL
ENDIF
SKIP
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
SKIP -1
nRecordPtr = RECNO()
nRowPtr--
IF nRowPtr < nRowTop
nRowPtr = nRowTop
GO nRecordTop
SKIP -1
nRecordTop = RECNO()
IF nRecRowBot < nRowBot
nRecRowBot++
ELSE
GO nRecordBot
SKIP -1
nRecordBot = RECNO()
ENDIF
GO nRecordPtr
SCROLL(nRowTop,nColTop,nRowBot,nColBot,-1)
IF nFreeze > 0
FOR nPtr1 = 1 TO nFreeze
@ nRowPtr,aCtrlArray[nPtr1][1] SAY EVAL(aCtrlArray[nPtr1][4])
NEXT
FOR nPtr1 = 1 TO nFreeze
@ nRowPtr,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cColSep
NEXT
ENDIF
FOR nPtr1 = nCtrlTop TO nCtrlBot
@ nRowPtr,aCtrlArray[nPtr1][1] SAY EVAL(aCtrlArray[nPtr1][4])
NEXT
FOR nPtr1 = nCtrlTop TO nCtrlBot-1
@ nRowPtr,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cColSep
NEXT
ENDIF
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
IF NEXTKEY() <> 5
EXIT
ENDIF
INKEY()
ENDDO
RETURN NIL
******************************************************************************
* KbrowseDn - down arrow handler
******************************************************************************
FUNCTION KbrowseDn(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
DO WHILE .T.
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
KbrowseBot(cNtxTopKey,cNtxBotKey)
RETURN NIL
ENDIF
SKIP -1
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
SKIP
nRecordPtr = RECNO()
nRowPtr++
IF nRowPtr > nRowBot
nRowPtr = nRowBot
GO nRecordTop
SKIP
nRecordTop = RECNO()
GO nRecordBot
SKIP
nRecordBot = RECNO()
GO nRecordPtr
SCROLL(nRowTop,nColTop,nRowBot,nColBot,1)
IF nFreeze > 0
FOR nPtr1 = 1 TO nFreeze
@ nRowPtr,aCtrlArray[nPtr1][1] SAY EVAL(aCtrlArray[nPtr1][4])
NEXT
FOR nPtr1 = 1 TO nFreeze
@ nRowPtr,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cColSep
NEXT
ENDIF
FOR nPtr1 = nCtrlTop TO nCtrlBot
@ nRowPtr,aCtrlArray[nPtr1][1] SAY EVAL(aCtrlArray[nPtr1][4])
NEXT
FOR nPtr1 = nCtrlTop TO nCtrlBot-1
@ nRowPtr,aCtrlArray[nPtr1][1] + aCtrlArray[nPtr1][2] SAY cColSep
NEXT
ENDIF
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
IF NEXTKEY() <> 24
EXIT
ENDIF
INKEY()
ENDDO
RETURN NIL
******************************************************************************
* KbrowsePu - page up handler
******************************************************************************
FUNCTION KbrowsePu(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
GO nRecordTop
SKIP -1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
IF nRowPtr = nRowTop
RETURN NIL
ENDIF
DISPBEGIN()
GO nRecordPtr
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nRecordPtr = nRecordTop
nRowPtr = nRowTop
GO nRecordPtr
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
DISPBEGIN()
SKIP (nRowBot - nRowTop) * -1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
ENDIF
nRecordTop = RECNO()
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
CLEAR TYPEAHEAD
DISPEND()
RETURN NIL
******************************************************************************
* KbrowsePd - page down handler
******************************************************************************
FUNCTION KbrowsePd(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nPtr2
GO nRecordBot
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
KbrowseBot(cNtxTopKey,cNtxBotKey)
IF nRecordPtr = RECNO()
RETURN NIL
ENDIF
DISPBEGIN()
GO nRecordPtr
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
DO WHILE .T.
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
nRowPtr++
ENDDO
KbrowseBot(cNtxTopKey,cNtxBotKey)
nRecordPtr = RECNO()
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
DISPBEGIN()
nRecordTop = RECNO()
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
CLEAR TYPEAHEAD
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseLf - left arrow handler
******************************************************************************
FUNCTION KbrowseLf(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nWidth
LOCAL nFreezeWidth
LOCAL nTmpCtrlPtr := nCtrlPtr
LOCAL nTmpCtrlTop := nCtrlTop
LOCAL nTmpCtrlBot := nCtrlBot
DO CASE
CASE nTmpCtrlPtr = 1
RETURN NIL
CASE nTmpCtrlPtr > nTmpCtrlTop .OR. nTmpCtrlPtr <= nFreeze
nTmpCtrlPtr--
CASE nFreeze = 0 .AND. nTmpCtrlTop > 1
nTmpCtrlTop--
nTmpCtrlPtr = nTmpCtrlTop
nTmpCtrlBot = nTmpCtrlTop
CASE nFreeze > 0 .AND. nTmpCtrlPtr = nFreeze + 1
nTmpCtrlPtr = nFreeze
CASE nFreeze > 0 .AND. nTmpCtrlTop > nFreeze + 1
nTmpCtrlTop--
nTmpCtrlPtr = nTmpCtrlTop
nTmpCtrlBot = nTmpCtrlTop
OTHERWISE
RETURN NIL
ENDCASE
IF nTmpCtrlTop = nCtrlTop
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nCtrlPtr = nTmpCtrlPtr
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
IF nTmpCtrlTop <> nCtrlTop
nCtrlTop = nTmpCtrlTop
nCtrlPtr = nTmpCtrlPtr
nCtrlBot = nTmpCtrlBot
nWidth = 0
nFreezeWidth = 0
IF nFreeze > 0
nFreezeWidth = 1
FOR nPtr1 = 1 TO nFreeze
IF nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nFreezeWidth = nFreezeWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
NEXT
ENDIF
FOR nPtr1 = nCtrlTop TO LEN(aCtrlArray)
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlBot = nPtr1
NEXT
FOR nPtr1 = nCtrlTop-1 TO 1 + nFreeze STEP -1
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlTop = nPtr1
NEXT
DISPBEGIN()
KbrowseScr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nColTop,@nColBot,@cColSep)
KbrowseHdr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nRowTop,@nColTop,@nRowBot,@nColBot,;
@nHeadRow,@cHeadSep,@cColSep)
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
ENDIF
RETURN NIL
******************************************************************************
* KbrowseRt - right arrow handler
******************************************************************************
FUNCTION KbrowseRt(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nWidth
LOCAL nFreezeWidth
LOCAL nTmpCtrlPtr := nCtrlPtr
LOCAL nTmpCtrlTop := nCtrlTop
LOCAL nTmpCtrlBot := nCtrlBot
DO CASE
CASE nTmpCtrlPtr = LEN(aCtrlArray)
RETURN NIL
CASE nFreeze = 0 .AND. nTmpCtrlPtr < nTmpCtrlBot
nTmpCtrlPtr++
CASE nFreeze > 0 .AND. nTmpCtrlPtr < nFreeze
nTmpCtrlPtr++
CASE nFreeze > 0 .AND. nTmpCtrlPtr = nFreeze
nTmpCtrlPtr = nTmpCtrlTop
CASE nFreeze > 0 .AND. nTmpCtrlPtr < nTmpCtrlBot
nTmpCtrlPtr++
CASE nTmpCtrlBot < LEN(aCtrlArray)
nTmpCtrlTop = nTmpCtrlBot + 1
nTmpCtrlPtr = nTmpCtrlTop
nTmpCtrlBot = nTmpCtrlTop
OTHERWISE
RETURN NIL
ENDCASE
IF nTmpCtrlTop = nCtrlTop
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nCtrlPtr = nTmpCtrlPtr
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
IF nTmpCtrlTop <> nCtrlTop
nCtrlTop = nTmpCtrlTop
nCtrlPtr = nTmpCtrlPtr
nCtrlBot = nTmpCtrlBot
nWidth = 0
nFreezeWidth = 0
IF nFreeze > 0
nFreezeWidth = 1
FOR nPtr1 = 1 TO nFreeze
IF nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nFreezeWidth = nFreezeWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
NEXT
ENDIF
FOR nPtr1 = nCtrlBot TO 1 + nFreeze STEP - 1
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlTop = nPtr1
NEXT
FOR nPtr1 = nCtrlBot+1 TO LEN(aCtrlArray)
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlBot = nPtr1
NEXT
DISPBEGIN()
KbrowseScr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nColTop,@nColBot,@cColSep)
KbrowseHdr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nRowTop,@nColTop,@nRowBot,@nColBot,;
@nHeadRow,@cHeadSep,@cColSep)
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
ENDIF
RETURN NIL
******************************************************************************
* KbrowseHom - home handler
******************************************************************************
FUNCTION KbrowseHom(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
IF nCtrlPtr > nCtrlTop .OR. (nFreeze > 0 .AND. nCtrlPtr > 1)
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
IF nFreeze > 0
nCtrlPtr = 1
ELSE
nCtrlPtr = nCtrlTop
ENDIF
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
ENDIF
RETURN NIL
******************************************************************************
* KbrowseEnd - end handler
******************************************************************************
FUNCTION KbrowseEnd(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
IF nCtrlPtr < nCtrlBot
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nCtrlPtr = nCtrlBot
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
ENDIF
RETURN NIL
******************************************************************************
* KbrowseCLf - ctrl-left arrow handler
******************************************************************************
FUNCTION KbrowseCLf(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nWidth
LOCAL nFreezeWidth
IF nCtrlTop = 1 .OR. (nFreeze > 0 .AND. nCtrlTop = nFreeze + 1)
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nCtrlPtr = 1
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
nCtrlBot = nCtrlTop - 1
nCtrlPtr = nCtrlTop - 1
nCtrlTop = nCtrlTop - 1
nFreezeWidth = 0
IF nFreeze > 0
nFreezeWidth = 1
FOR nPtr1 = 1 TO nFreeze
IF nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nFreezeWidth = nFreezeWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
NEXT
ENDIF
nWidth = 0
FOR nPtr1 = nCtrlBot TO 1 + nFreeze STEP - 1
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlTop = nPtr1
nCtrlPtr = nPtr1
NEXT
FOR nPtr1 = nCtrlBot+1 TO LEN(aCtrlArray)
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlBot = nPtr1
NEXT
DISPBEGIN()
KbrowseScr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nColTop,@nColBot,@cColSep)
KbrowseHdr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nRowTop,@nColTop,@nRowBot,@nColBot,;
@nHeadRow,@cHeadSep,@cColSep)
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseCRt - ctrl-right arrow handler
******************************************************************************
FUNCTION KbrowseCRt(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
LOCAL nWidth
LOCAL nFreezeWidth
IF nCtrlBot = LEN(aCtrlArray)
DISPBEGIN()
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nCtrlPtr = nCtrlBot
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
nCtrlTop = nCtrlBot + 1
nCtrlPtr = nCtrlBot + 1
nFreezeWidth = 0
IF nFreeze > 0
nFreezeWidth = 1
FOR nPtr1 = 1 TO nFreeze
IF nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nFreezeWidth = nFreezeWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
NEXT
ENDIF
nWidth = 0
FOR nPtr1 = nCtrlTop TO LEN(aCtrlArray)
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlBot = nPtr1
NEXT
FOR nPtr1 = nCtrlTop-1 TO 1 + nFreeze STEP - 1
IF nWidth + nFreezeWidth + aCtrlArray[nPtr1][2] > nColBot-nColTop
EXIT
ENDIF
nWidth = nWidth + aCtrlArray[nPtr1][2] + LEN(cColSep)
nCtrlTop = nPtr1
NEXT
DISPBEGIN()
KbrowseScr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nColTop,@nColBot,@cColSep)
KbrowseHdr(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nFreeze,;
@nRowTop,@nColTop,@nRowBot,@nColBot,;
@nHeadRow,@cHeadSep,@cColSep)
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseCPu - ctrl-page up handler
******************************************************************************
FUNCTION KbrowseCPu(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
GO nRecordTop
SKIP -1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
IF nRowPtr = nRowTop
RETURN NIL
ENDIF
DISPBEGIN()
GO nRecordPtr
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
nRecordPtr = nRecordTop
nRowPtr = nRowTop
GO nRecordPtr
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
KbrowseTop(cNtxTopKey,cNtxBotKey)
DISPBEGIN()
nRecordTop = RECNO()
nRowPtr = nRowTop
nRecordPtr = RECNO()
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseCPd - ctrl-page down handler
******************************************************************************
FUNCTION KbrowseCPd(aCtrlArray,nCtrlTop,nCtrlBot,nCtrlPtr,nFreeze,;
nRowTop,nRowBot,nColTop,nColBot,nRowPtr,;
nRecordTop,nRecordBot,nRecordPtr,nRecRowBot,;
cNtxTopKey,cNtxBotKey,;
nHeadrow,cHeadSep,cColSep)
LOCAL nPtr1
GO nRecordBot
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
KbrowseBot(cNtxTopKey,cNtxBotKey)
IF nRecordPtr = RECNO()
RETURN NIL
ENDIF
DISPBEGIN()
GO nRecordPtr
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
DO WHILE .T.
SKIP
IF KbrowseEof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
nRowPtr++
ENDDO
KbrowseBot(cNtxTopKey,cNtxBotKey)
nRecordPtr = RECNO()
COLORSELECT(1)
@ nRowPtr,aCtrlArray[nCtrlPtr][1] SAY EVAL(aCtrlArray[nCtrlPtr][4])
COLORSELECT(0)
DISPEND()
RETURN NIL
ENDIF
DISPBEGIN()
nRowPtr = nRowBot
KbrowseBot(cNtxTopKey,cNtxBotKey)
nRecordPtr = RECNO()
FOR nPtr1 = nRowTop TO nRowBot -1
SKIP - 1
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
EXIT
ENDIF
NEXT
IF KbrowseBof(cNtxTopKey,cNtxBotKey)
KbrowseTop(cNtxTopKey,cNtxBotKey)
ENDIF
nRecordTop = RECNO()
KbrowseDat(@aCtrlArray,@nCtrlTop,@nCtrlBot,@nCtrlPtr,@nFreeze,;
@nRowTop,@nRowBot,@nRowPtr,;
@nRecordTop,@nRecordBot,@nRecordPtr,@nRecRowBot,;
@cNtxTopKey,@cNtxBotKey)
GO nRecordPtr
DISPEND()
RETURN NIL
******************************************************************************
* KbrowseEof - test for EOF()
******************************************************************************
FUNCTION KbrowseEof(cNtxTopKey,cNtxBotKey)
IF EOF()
RETURN .T.
ENDIF
IF LEN(cNtxTopKey) <> 0
IF &(INDEXKEY(0)) < cNtxTopKey
RETURN .T.
ENDIF
ENDIF
IF LEN(cNtxBotKey) <> 0
IF &(INDEXKEY(0)) > cNtxBotKey
RETURN .T.
ENDIF
ENDIF
RETURN .F.
******************************************************************************
* KbrowseBof - test for BOF()
******************************************************************************
FUNCTION KbrowseBof(cNtxTopKey,cNtxBotKey)
IF BOF()
RETURN .T.
ENDIF
IF LEN(cNtxTopKey) <> 0
IF &(INDEXKEY(0)) < cNtxTopKey
RETURN .T.
ENDIF
ENDIF
IF LEN(cNtxBotKey) <> 0
IF &(INDEXKEY(0)) > cNtxBotKey
RETURN .T.
ENDIF
ENDIF
RETURN .F.
******************************************************************************
* KbrowseTop - GO TOP processor
******************************************************************************
FUNCTION KbrowseTop(cNtxTopKey,cNtxBotKey)
IF LEN(cNtxTopKey) = 0
GO TOP
RETURN NIL
ENDIF
IF LEN(cNtxTopKey) <> 0
SEEK cNtxTopKey
ENDIF
RETURN NIL
******************************************************************************
* KbrowseBot - GO BOTTOM processor
******************************************************************************
FUNCTION KbrowseBot(cNtxTopKey,cNtxBotKey)
LOCAL cSeekType
LOCAL cSeekVar
IF LEN(cNtxTopKey) = 0
GO BOTTOM
RETURN NIL
ENDIF
cSeekVar = cNtxBotKey
cSeekType := VALTYPE(cSeekVar)
DO CASE
CASE cSeekType == "C"
cSeekVar := STUFF(cSeekVar,LEN(cSeekVar),1,CHR(ASC(RIGHT(cSeekVar,1))+1))
CASE cSeekType == "N"
cSeekVar++
CASE cSeekType == "D"
cSeekVar++
ENDCASE
SET SOFTSEEK ON
SEEK cSeekVar
SET SOFTSEEK OFF
IF .NOT. EOF()
SKIP -1
ENDIF
RETURN NIL