lTrimmer is a logical value denoting whether leading or
trailing spaces should be included in the comparison. If .T., then ignores spaces in comparison, defaults to .T., .F. includes spaces.
lCaseSens is a logical value denoting case sensitivity.
If .T., then comparison is sensitive to case, defaults to .T., .F. ignores case.
Returns
An array of the union of aList1 and aList2.
Description
This function will add the elements unique of aList2 with aList1. It returns a new array including all the elements of aList1 plus the unique elements of aList2.
Examples
LOCAL aList1 := { "apple", "orange", "pear" }
LOCAL aList2 := { "apple ", "banana", "PEAR" }
// ignores spaces, sensitive to case
? hb_ValToExp( ft_AAddition( aList1, aList2 ) )
// --> { "apple", "orange", "pear", "banana", "PEAR" }
// ignores spaces, not sensitive to case
? hb_ValToExp( ft_AAddition( aList1, aList2, , .F. ) )
// --> { "apple", "orange", "pear", "banana" }
// sensitive to spaces, not sensitive to case
? hb_ValToExp( ft_AAddition( aList1, aList2, .F. , .F. ) )
// --> { "apple", "orange", "pear", "apple ", "banana" }
LOCAL aSubTotals := { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
? ft_AAvg( aSubTotals ) // Get Average of Entire Array
? ft_AAvg( aSubTotals, 5 ) // Get Average of 5th Element On
? ft_AAvg( aSubTotals, , 10 ) // Get Average of 1st 10 Elements
? ft_AAvg( aSubTotals, 5, 10 ) // Get Average of Elements 5-10
aArray is the array containing the elements to be measured.
nDimension is the array dimension to be measured,
defaults to first dimension.
nStart is the starting array element to include,
defaults to first array element.
nCount is the number of array elements to process from
from nStart, defaults to remaining elements in array.
Returns
The length of the longest size element of an array.
Description
This function will measure each element of an array dimension and return the longest element.
Examples
// FIXME
? ft_AEMaxLen( aArray ) // Measure the 1st dimension of an Array
? ft_AEMaxLen( aArray, 2 ) // Measure the 2nd dimension of an Array
? ft_AEMaxLen( aArray, 2, , 9 ) // Measure Elements 1-9 of the 2nd dimension or subarray
? ft_AEMaxLen( aArray, 3, 5, 9 ) // Measure Elements 5-9 of the 3rd dimension or subarray
? ft_AEMaxLen( aArray, 3, 5 ) // Measure Elements 5 to last in the 3rd dimension or subarray
aArray is the array containing the elements to be measured.
nDimension is the array dimension to be measured,
defaults to first dimension.
nStart is the starting array element to include,
defaults to first array element.
nCount is the number of array elements to process from
from nStart, defaults to remaining elements in array.
Returns
The length of the shortest size element of an array.
Description
This function will measure each element of an array dimension and return the shortest element.
Examples
// FIXME
? ft_AEMinLen( aArray ) // Measure the 1st dimension of an Array
? ft_AEMinLen( aArray, 2 ) // Measure the 2nd dimension of an Array
? ft_AEMinLen( aArray, 2, , 9 ) // Measure Elements 1-9 of 2nd dimension
? ft_AEMinLen( aArray, 3, 5, 9 ) // Measure Elements 5-9 of 3rd dimension
? ft_AEMinLen( aArray, 3, 5 ) // Measure Elements 5 to end of 3rd dimension
aArray is the array containing the elements to be averaged.
nStart is the first array element to include, defaults to first element.
nEnd is the last array element to include, defaults to last element.
Returns
The median average of the array elements
Description
This function sorts the elements of a numeric array and then returns the value in the middle element of the sorted array. If there is no exact middle value, then it returns the average of the two middle values. Half of the elements are > median and half are < median. A median average may more reflect a more useful average when there are extreme values in the set.
Examples
LOCAL aArray := { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
? ft_AMedian( aArray ) // Return Median for entire array
? ft_AMedian( aArray, 2 ) // Return Median for elements from 2 to end
? ft_AMedian( aArray, , 9 ) // Return Median for 1st 9 elements
? ft_AMedian( aArray, 8, 40 ) // Return Median for elements 8 to 40
bCompareBlock is a code block containing the expression for the array elements to be tested with. Each element is passed as a parameter to the block. If the block returns .T., the number of matches will be incremented by one.
nStartIndex is the first array item to include in the search, defaults to first element.
nEndIndex is the last array element to include in the search, defaults to all elements.
Returns
The number of elements that cause the code block to return .T.
Description
This function returns the number of array elements that, when passed to the supplied code block, cause that code block to return a .T. value.
Examples
// FIXME
// Search the Entire Array
? ft_ANoMatches( aTries, {| x | x <= 100 } )
// Search from the 5th Element On
? ft_ANoMatches( aCodes, {| x | Upper( x ) == cCurrentCode }, 5 )
// Search the 1st 10 Elements
? ft_ANoMatches( aDates, {| x | IS_BETWEEN( Date() - 7, x, Date() + 7 ) }, 10 )
// Search Elements 5-10
? ft_ANoMatches( aNames, {| x | x <= cLastGoodName }, 5, 10 )
nTop, nLeft, nBottom, nRight are coordinates for TBrowse
Array Name is name of 2 dimensional to array edit
nElem is pointer for element in array
aHeadings is array of column headings
aBlocks is array of blocks describing each array element
[ bGetFunc ] is get editing function for handling individual elements
Returns
Value of element positioned on when exit ft_ArEdit() The type of this value depends on what is displayed.
Description
This function allows you to position yourself in an array, add and delete rows with the F7 and F8 keys, and pass a UDF with information to edit the individual gets.
Examples
LOCAL i, ar[ 3 ][ 26 ], aBlocks[ 3 ], aHeadings[ 3 ]
LOCAL nElem := 1, bGetFunc
// This example will allow you to browse a 2 dimensional array
// But you cannot edit it since there is no GetBlock UDF
// It allows the user to hit <Enter> to select an element or <Esc>
// to return 0
ft_ArEdit( 3, 5, 18, 75, ar, @nElem, aHeadings, aBlocks )
// This second example shows how to edit a 2 dimensional array
// as might be done to edit an invoice
// Set up two dimensional array "ar"
FOR i := 1 TO 26
ar[ 1 ][ i ] := i // 1 -> 26 Numeric
ar[ 2 ][ i ] := Chr( Asc( "A" ) + i - 1 ) // "A" -> "Z" Character
ar[ 3 ][ i ] := Chr( Asc( "Z" ) - i + 1 ) // "Z" -> "A" Character
NEXT
// set up aHeadings Array for column headings
aHeadings := { "Numbers", "Letters", "Reverse" }
// Need to set up individual array blocks for each TBrowse column
aBlocks[ 1 ] := {|| Str( ar[ 1 ][ nElem ], 2 ) } // prevent default 10 spaces
aBlocks[ 2 ] := {|| ar[ 2 ][ nElem ] }
aBlocks[ 3 ] := {|| ar[ 3 ][ nElem ] }
// set up TestGet() as the passed Get Function so ft_ArEdit() knows how
// to edit the individual gets.
bGetFunc := {| b, ar, nDim, nElem | TestGet( b, ar, nDim, nElem ) }
SetColor( "N/W, W/N, , , W/N" )
CLS
ft_ArEdit( 3, 5, 18, 75, ar, @nElem, aHeadings, aBlocks, bGetFunc )
STATIC FUNCTION TestGet( ... )
RETURN .T.
aArray is the array containing the elements to be summed.
nStartIndex is the first array item to include, defaults to first element.
nEndIndex is the last array element to include, defaults to all elements.
Returns
The sum of the elements of the array or the lengths of the elements.
Description
This function is to sum the elements of a numeric array or to sum the lengths of a character array.
Examples
LOCAL aSubTotals := { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
? ft_ASum( aSubTotals ) // Sum the Entire Array
? ft_ASum( aSubTotals, 5 ) // Sum from the 5th Element On
? ft_ASum( aSubTotals, , 10 ) // Sum the 1st 10 Elements
? ft_ASum( aSubTotals, 5, 10 ) // Sum Elements 5-10
ft_RestArr() restores an array which was saved to a disc file using ft_SaveArr().
[1992-10-01 Librarian note:
This function does not appear to work with multi-dimensional arrays. If you'd care to modify it to support this feature, please do and send it to Glenn Scott 71620,1521.]
aArray is any Clipper array except those containing compiled code blocks.
cFileName is a DOS file name.
nErrorCode will return any DOS file error.
All arguments are required.
Returns
.F. if there was a DOS file error or the array contained code blocks, otherwise returns .T.
Description
ft_SaveArr() saves any Clipper array, except those containing compiled code blocks, to a disc file. The array can be restored from the disc file using ft_RestArr().
[1992-10-01 Librarian note:
This function does not appear to work with multi-dimensional arrays. If you'd care to modify it to support this feature, please do and send it to Glenn Scott 71620,1521.]
9-character string, consisting of 1's and 0's, representing bits 0 through 7 of parameter byte, with space between bits 3 and 4. Returns NIL if parameters are faulty.
Description
Can be used to show results of bit manipulation, both before and after. Binary representation follows right-to-left convention of bit position numbering, 0 through 7. Space between high and low nibbles for clarity and easy comparison to hexadecimal notation.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// These three code lines perform a bitwise AND on bytes with values of
// hb_BChar( 20 ) and hb_BChar( 36 ), and deliver the result as a string
// in binary (bit) format.
? ft_Byt2Bit( hb_BChar( 20 ) ) // --> "00010100"
? ft_Byt2Bit( hb_BChar( 36 ) ) // --> "00100100"
? ft_Byt2Bit( ft_ByteAnd( hb_BChar( 20 ), hb_BChar( 36 ) ) ) // --> "00000100"
Convert byte to hexadecimal version of its binary value
Syntax
ft_Byt2Hex( cByte ) β cHexValue
Arguments
cByte is the byte to convert.
Returns
Three-character string, consisting of two digits of hexadecimal notation and letter h to signify hex. Returns NIL if parameters are faulty.
Description
Can be used to show results of bit manipulation, both before and after.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// These three code lines perform a bitwise AND on bytes with values of
// hb_BChar( 20 ) and hb_BChar( 36 ), and deliver the result as a string
// in hexadecimal format, using 'h' to signify hexadecimal.
? ft_Byt2Hex( hb_BChar( 20 ) ) // --> "14h"
? ft_Byt2Hex( hb_BChar( 36 ) ) // --> "24h"
? ft_Byt2Hex( ft_ByteAnd( hb_BChar( 20 ), hb_BChar( 36 ) ) ) // --> "04h"
cASCII is the ASCII representation of the printer control codes in Lotus 123 format (e.g. "\027E" for hb_BChar( 27 ) + "E")
"\nnn" will be converted to hb_BChar( nnn )"\\" will be converted to "\"
Returns
The binary version of an ASCII coded printer setup string.
Description
This function is useful for allowing the user to enter printer control codes in Lotus-style ASCII format, and then having this function convert that code to the format that the printer needs to receive.
Examples
// FIXME
LOCAL cSetup := "\015" // default = Epson compressed print
UserInput( @cSetup ) // Let user modify setup code
SET DEVICE TO PRINTER // get ready to print
?? ft_EscCode( cSetup ) // Output the converted code
ft_NToW() is intended to be used with integers only. Since I don't know what your application will be, I cannot assume the type of fraction you want returned (ninety nine cents, 99/100, .99, etc). If you want the fraction in words, just pass it as an integer.
Do not pass a negative number! Handle negative numbers any way you need to in your code. (i.e.: CR, DB, Negative, Minus, etc.)
Also, numeric 0 is returned as a null string. You will need to make a decision how to output it (zero dollars, no dollars, etc).
Examples
LOCAL x, cents, string
? ft_NToW( 999 ) // --> "Nine Hundred Ninety Nine"
? ft_NToW( 1000 ) // --> "One Thousand"
? ft_NToW( 23 ) + " Dollars and " + ft_NToW( 99 ) + " Cents"
// --> Twenty Three Dollars and Ninety Nine Cents
? ft_NToW( 23 ) + " Dollars and " + "99/100"
// --> Twenty Three Dollars and 99/100
x := -23.99
cents := Str( ( x - Int( x ) ) * 100, 2, 0 ) + "/100"
x := Int( x )
string := iif( x < 0, "Credit of ", "Debit of " )
? string + ft_NToW( Abs( x ) ) + " Dollars and " + "99/100"
// --> Credit of Twenty Three Dollars and 99/100
nValue - The numeric value to be compressed nSize - Optional size of numeric field, defaults to 10 nDecimals - Optional number of decimal places, defaults to 0
Returns
cCompressed - Compressed string, 50% the size of nSize
Description
The ft_Sqzn() function allows a numeric value to be compressed when stored in the database. The compression is 50% the storage space of the original number. The companion function, ft_Unsqzn() returns the original number from the compressed string.
cDateStr is a Clipper string in the format "CCYYMMDD".
Returns
A Clipper date type.
Description
This function allows the programmer to hard code a date into the program without knowing what the current date type is. This function is the converse of the Clipper DToS() function.
cCompressed - Compressed string, obtained from ft_Sqzn()
nSize - Size of numeric field
nDecimals - Optional number of decimal places
Returns
nValue - Uncompressed numeric value
Description
The ft_Unsqzn() function returns the numeric value from the compressed string. The compression is 50% the storage space of the original number. The original number must have been compressed using the ft_Sqzn() function.
This function, along with ft_Sqzn() can be used to reduce disk storage requirements for numeric fields in a database file.
cTypeToConvertTo is the type of value to convert to ("C","D","L","N","A" or "B").
lWantYesNo is a logical to signal if 'Y' or 'N' is to be returned if Converting a logical, otherwise '.T.' or '.F.' will be returned for logicals.
Returns
The original value converted to the new type.
Description
This function converts a value of character, date, numeric, logical, array or code block type to any of the other type. While it is guaranteed to return a value of the correct type, that value may not be meaningful (i.e., converting from a code block returns an Empty() value of the desired type).
dGivenDate is any valid date in any valid format. Defaults to Date() if not supplied.
lIsEnd is a logical variable. .F. = adjust for beginning of period mode, .T. = adjust for end of period mode. Defaults to beginning of period mode.
Returns
An adjusted date dependent upon mode and work week start day.
Description
Called by other ft_Acct*() functions. The algorithm is:
Beginning of period mode:
IF dGivenDate is in last 3 days of work week
Return next week's start date
ELSE
Return this week's start date
ENDIF
End of period mode:
IF dGivenDate is in last 4 days of work week
Return this week's end date
ELSE
Return prior week's end date
ENDIF
Examples
LOCAL dDate
// Beginning of period mode (lIsEnd == .F.)
dDate := 0d19910131 // In last 3 days of work week
? ft_AcctAdj( dDate ) // --> 1991-02-03 (next week's start)
dDate := 0d19910331 // Not in last 3 days of work week
? ft_AcctAdj( dDate ) // --> 1991-03-31 (this week's start)
// End of period mode (lIsEnd == .T.)
dDate := 0d19910131 // In last 4 days of work week
? ft_AcctAdj( dDate, .T. ) // --> 1991-02-02 (this week's end)
dDate := 0d19910331 // Not in last 4 days of work week
? ft_AcctAdj( dDate, .T. ) // --> 1991-03-30 (prior week's end)
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nMonthNum is a number from 1 to 12 signifying a month. Defaults to current month if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and month as a character string "YYYYMM"
aDateInfo[ 2 ] - The beginning date of the accounting month
aDateInfo[ 3 ] - The ending date of the accounting month
Description
ft_AcctMonth() creates an array containing data about the accounting month containing the given date.
An accounting period has the following characteristics:
If the first week of the period contains 4 or more 'work' days, it is included in the period; otherwise, the first week was included in the prior period.
If the last week of the period contains 4 or more 'work' days it is included in the period; otherwise, the last week is included in the next period. This results in 13 week 'quarters' and 4 or 5 week 'months'. Every 5 or 6 years, a 'quarter' will contain 14 weeks and the year will contain 53 weeks.
Examples
LOCAL aDateInfo
// get info about accounting month containing 1990-09-15
aDateInfo := ft_AcctMonth( 0d19900915 )
? aDateInfo[ 1 ] // --> 199009 (9th month)
? aDateInfo[ 2 ] // --> 1990-09-02 beginning of month 9
? aDateInfo[ 3 ] // --> 1990-09-29 end of month 9
// get info about accounting month 5 in year containing 1990-09-15
aDateInfo := ft_AcctMonth( 0d19900915, 5 )
? aDateInfo[ 1 ] // --> 199005
? aDateInfo[ 2 ] // --> 1990-04-29 beginning of month 5
? aDateInfo[ 3 ] // --> 1990-06-02 end of month 5
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nQtrNum is a number from 1 to 4 signifying a quarter. Defaults to current quarter if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and qtr. as a character string "YYYYQQ"
aDateInfo[ 2 ] - The beginning date of the accounting quarter
aDateInfo[ 3 ] - The ending date of the accounting quarter
Description
ft_AcctQtr() creates an array containing data about the accounting quarter containing the given date.
An accounting period has the following characteristics:
If the first week of the period contains 4 or more 'work' days, it is included in the period; otherwise, the first week was included in the prior period.
If the last week of the period contains 4 or more 'work' days it is included in the period; otherwise, the last week is included in the next period. This results in 13 week 'quarters' and 4 or 5 week 'months'. Every 5 or 6 years, a 'quarter' will contain 14 weeks and the year will contain 53 weeks.
Examples
LOCAL aDateInfo
// get info about accounting month containing 1990-09-15
aDateInfo := ft_AcctQtr( 0d19900915 )
? aDateInfo[ 1 ] // --> 199003 (3rd quarter)
? aDateInfo[ 2 ] // --> 1990-07-01 beginning of quarter 3
? aDateInfo[ 3 ] // --> 1990-09-29 end of quarter 3
// get info about accounting qtr. 2 in year containing 1990-09-15
aDateInfo := ft_AcctQtr( 0d19900915, 2 )
? aDateInfo[ 1 ] // --> 199002
? aDateInfo[ 2 ] // --> 1989-04-01 beginning of quarter 2
? aDateInfo[ 3 ] // --> 1990-06-30 end of quarter 2
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nWeekNum is a number from 1 to 52 signifying a week. Defaults to current week if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and week as a character string "YYYYWW"
aDateInfo[ 2 ] - The beginning date of the accounting week
aDateInfo[ 3 ] - The ending date of the accounting week
Description
ft_AcctWeek() returns an array containing data about the accounting week containing the given date.
An accounting period has the following characteristics:
If the first week of the period contains 4 or more 'work' days, it is included in the period; otherwise, the first week was included in the prior period.
If the last week of the period contains 4 or more 'work' days it is included in the period; otherwise, the last week is included in the next period. This results in 13 week 'quarters' and 4 or 5 week 'months'. Every 5 or 6 years, a 'quarter' will contain 14 weeks and the year will contain 53 weeks.
Examples
LOCAL aDateInfo
// get info about accounting week containing 1990-09-15
aDateInfo := ft_AcctWeek( 0d19900915 )
? aDateInfo[ 1 ] // --> 199037 (37th week)
? aDateInfo[ 2 ] // --> 1990-09-09 beginning of week 37
? aDateInfo[ 3 ] // --> 1990-09-15 end of week 37
// get info about accounting week 25 in year containing 1990-09-15
aDateInfo := ft_AcctWeek( 0d19900915, 25 )
? aDateInfo[ 1 ] // --> 199025
? aDateInfo[ 2 ] // --> 1989-06-17 beginning of week 25
? aDateInfo[ 3 ] // --> 1990-06-23 end of week 25
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year as a character string "YYYY"
aDateInfo[ 2 ] - The beginning date of the accounting year
aDateInfo[ 3 ] - The ending date of the accounting year
Description
ft_AcctYear() creates an array containing data about the accounting year containing the given date.
An accounting period has the following characteristics:
If the first week of the period contains 4 or more 'work' days, it is included in the period; otherwise, the first week was included in the prior period.
If the last week of the period contains 4 or more 'work' days it is included in the period; otherwise, the last week is included in the next period. This results in 13 week 'quarters' and 4 or 5 week 'months'. Every 5 or 6 years, a 'quarter' will contain 14 weeks and the year will contain 53 weeks.
Examples
LOCAL aDateInfo
// get info about accounting year containing 1990-09-15
aDateInfo := ft_AcctYear( 0d19900915 )
? aDateInfo[ 1 ] // --> 1990
? aDateInfo[ 2 ] // --> 1989-12-31 beginning of year
? aDateInfo[ 3 ] // --> 1990-12-29 end of year
Return true number of days to add given number of workdays
Syntax
ft_AddWkDy( <dStart>, <nWorkDays> ) β nTrueDays
Arguments
dStart = date to start adding from nWorkDays = number of workdays to add
Returns
nTrueDays = Number of actual days to add to dStart in
order to add the required nWorkDays
Description
Let's say you are given the problem:
"All invoices are due 10 working days from the date they are printed. Please display the due date on the invoice."
When is the due date? Assuming you are printing the invoices today, your answer is:
dDueDate := Date() + ft_addWkDay( Date(), 10 )
A work day is defined as Monday through Friday. Unfortunately this routine does not account for holidays.
This documentation was written by Glenn Scott so if it's wrong, blame him.
Examples
LOCAL dPost := 0d19910101
// Postdate 5 working days from the first of January
dPost += ft_AddWkDy( dPost, 5 ) // returns 7 true days
? dPost // --> 1991-01-08
nRow is an optional screen row for calendar display,
default row 1.
nCol is an optional screen col for calendar display,
default col 63.
cColor is an optional color string for displayed messages,
default is bright white text over green background.
lShadow is an optional logical variable. If true (.T.),
it uses ft_Shadow() to add a transparent shadow to the display, default (.F.).
lShowHelp is an optional logical variable. If true, uses
ft_XBox() to display a four line help message if the F1 key is pressed, default (.F.).
Returns
aRetVal is an 8 element array containing date, month, day, year,
month (in character format), day of the week, Julian day and current time.
Description
ft_Calendar() simply displays today's date, time and Julian day in a two line display with an optional box shadow. Cursor keys may be used to page through the calendar by day, week, month or year increments. Returns an 8 element array of calendar data:
cFYStart is a character date string in the user's system date format, i.e., the same as the user would enter for CToD(). If this argument is NIL, the current value is unchanged.
Note: The year portion of the date string must be present and be a valid year; however, it has no real meaning.
nDow is a number from 1 to 7 (1 = Sunday) indicating the desired start of a work week. If this argument is NIL, the current value is unchanged.
Returns
A 2-element array containing the following information:
aDateInfo[ 1 ] - an ANSI date string indicating the beginning
date of the year. Only the month and day are meaningful.
aDateInfo[ 2 ] - the number of the first day of the week
(1 = Sunday)
Description
ft_DateCnfg() is called internally by many of the date functions in the library to determine the beginning of year date and beginning of week day.
The default beginning of the year is January 1st and the default beginning of the week is Sunday (day 1). Either or both of these settings may be changed by calling ft_DateCnfg() with the proper arguments. They will retain their values for the duration of the program or until they are changed again by a subsequent call to ft_DateCnfg().
It is not necessary to call ft_DateCnfg() unless you need to change the defaults.
ft_DateCnfg() affects the following library functions:
Set( _SET_DATEFORMAT, "yyyy-mm-dd" )
// Configure library date functions to begin year on July 1st.
ft_DateCnfg( "1980-07-01" ) // year is insignificant
SET DATE TO AMERICAN // System date format: American
? hb_ValToExp( ft_DateCnfg() ) // --> { "1980.01.01", 1 } (Sun)
? hb_ValToExp( ft_DateCnfg( "07/01/80" ) ) // --> { "1980.07.01", 1 } (Sun)
? hb_ValToExp( ft_DateCnfg( "07/01/80", 2 ) ) // --> { "1980.07.01", 2 } (Mon)
? hb_ValToExp( ft_DateCnfg( , 2 ) ) // --> { "1980.01.01", 2 } (Mon)
SET DATE TO BRITISH // System date format: British
? hb_ValToExp( ft_DateCnfg( "01/07/80", 2 ) ) // --> { "1980.07.01", 2 } (Mon)
dGivenDate is any valid date in any valid format. Defaults to current system date if not supplied.
nDayNum is a number from 1 to 371, signifying a day of a year. Defaults to current day if not supplied.
lIsAcct is a logical which specifies the type of year to base the return value on: .F. = calendar or fiscal year, .T. = accounting year.
Returns
A three element array containing the following data:
If nDayNum is specified:
aDateInfo[ 1 ] - The date of the specified day number aDateInfo[ 2 ] - The beginning date of the year aDateInfo[ 3 ] - The ending date of the year
If nDayNum is not specified:
aDateInfo[ 1 ] - The year and day as a character string "YYYYDDD" aDateInfo[ 2 ] - The beginning date of the year aDateInfo[ 3 ] - The ending date of the year
Description
ft_DayOfYr() returns an array containing data about a day in the calendar or fiscal year containing the given date.
The beginning of year date defaults to January 1st but may be changed with ft_DateCnfg().
Examples
LOCAL aDateInfo
aDateInfo := ft_DayOfYr( 0d19910331 )
? aDateInfo[ 1 ] // --> 1991090 (90th day of year 1991)
? aDateInfo[ 2 ] // --> 1991-01-01
? aDateInfo[ 3 ] // --> 1991-12-31
aDateInfo := ft_DayOfYr( , 90 ) // assume current date is 3/31/91
? aDateInfo[ 1 ] // --> 1991-03-31 (90th day of year)
? aDateInfo[ 2 ] // --> 1991-01-01
? aDateInfo[ 3 ] // --> 1991-12-31
aDateInfo := ft_DayOfYr( , 90, .T. )
? aDateInfo[ 1 ] // --> 1991-03-29 (90th day of accounting year)
? aDateInfo[ 2 ] // --> 1990-12-30 (1st day of accounting year)
? aDateInfo[ 3 ] // --> 1991-12-28 (last day of accounting year)
Calculate no. of days between date and beginning of week
Syntax
ft_DayToBoW( [ <dGivenDate> ] ) β nDays
Arguments
dGivenDate is any valid date in any valid date format. Defaults to current date if not supplied.
Returns
A positive number of days to beginning of week, range 0 to 6.
Description
ft_DayToBoW() returns the number of days to the beginning of the week. Normally this will be one less than the value that would be returned by the Clipper function DoW(), unless the day for the beginning of the week has been changed with ft_DateCnfg().
dDate is a date in the form "mm/dd/yy" or "mm/dd/yyyy"
Returns
Return numeric position of day within the year. Return NIL if parameter does not conform.
Description
Finds the day number, considering 01/01 as day 1 Handles dates with CENTURY ON|OFF, to allow for 21st century. Date validation must be external to this function.
Examples
LOCAL dDate, GetList := {}
// These code fragments find the day number, given a date.
// literal character date
? ft_DoY( 0d19910101 ) // --> 1
// presume OS date to be 1991-01-06
? ft_DoY( Date() ) // --> 6
// date input
dDate := 0d0
@ 4, 10 GET cDate // input 1991-07-04
READ
? ft_DoY( dDate ) // --> 185
// last day of year
? ft_DoY( 0d19911231 ) // --> 365
xYear can be a character, date or numeric describing the year for which you wish to receive the date of Easter.
Returns
The actual date that Easter occurs.
Description
Returns the date of Easter for any year after 1582 up to Clipper's limit which the manual states is 9999, but the Guide agrees with the actual imposed limit of 2999.
This function can be useful in calendar type programs that indicate when holidays occur.
dDateToChk is a date within a month for which you want to find the first date of that month. If not passed or is an incorrect type, defaults to current system date.
Returns
A Clipper date value representing the first date of the month.
Description
This function will return the first day of the month of the date passed, or the first day of the current month if no argument is supplied.
dDateToChk is a date within a month for which you want to find the last date of that month. If not passed or is an incorrect type, defaults to current system date.
Returns
A Clipper date value representing the last date of the month.
Description
This function will return the last day of the month of the date passed, or the last day of the current month if no argument is supplied.
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nAddMonths is the number of months to be added or subtracted. Defaults to 0 if not supplied.
lMakeEOM is a logical variable indicating whether or not to force the returned date to the last date of the month. It only affects the returned date if dGivenDate is an end-of-month date.
Returns
A date.
Description
ft_MAdd() adds or subtracts months to/from a given date.
If lMakeEOM is passed and dGivenDate is the last day of a month, it will return the EOM of calculated month. Otherwise it will return the same day as the day of the passed date.
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nMonthNum is a number from 1 to 12 signifying a month. Defaults to current month if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and month as a character string "YYYYMM" aDateInfo[ 2 ] - The beginning date of the month aDateInfo[ 3 ] - The ending date of the month
Description
ft_Month() returns an array containing data about the month containing the given date.
Normally the return data will be based on a year beginning on January 1st with weeks beginning on Sunday.
The beginning of year date and/or beginning of week day can be changed by using ft_DateCnfg(), which will affect all subsequent calls to ft_Month() until another call to ft_DateCnfg().
The beginning of year date and beginning of week day may be reset to January 1 and Sunday by calling ft_DateCnfg() with no parameters.
Examples
LOCAL aDateInfo
// get info about month containing 1990-09-15
aDateInfo := ft_Month( 0d19900915 )
? aDateInfo[ 1 ] // --> 199009 (9th month)
? aDateInfo[ 2 ] // --> 1990-09-01 beginning of month 9
? aDateInfo[ 3 ] // --> 1990-09-30 end of week month 9
// get info about month 5 in year containing 1990-09-15
aDateInfo := ft_Month( 0d19900915, 5 )
? aDateInfo[ 1 ] // --> 199005
? aDateInfo[ 2 ] // --> 1990-05-01 beginning of month 5
? aDateInfo[ 3 ] // --> 1990-05-31 end of month 5
// get info about month 5 in current year (1991)
aDateInfo := ft_Month( , 5 )
? aDateInfo[ 1 ] // --> 199105
? aDateInfo[ 2 ] // --> 1991-05-01 beginning of month 5
? aDateInfo[ 3 ] // --> 1991-05-31 end of month 5
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nQtrNum is a number from 1 to 4 signifying a quarter. Defaults to current quarter if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and quarter as a character string "YYYYQQ"
aDateInfo[ 2 ] - The beginning date of the quarter
aDateInfo[ 3 ] - The ending date of the quarter
Description
ft_Qtr() returns an array containing data about the quarter containing the given date.
Normally the return data will be based on a year beginning on January 1st with weeks beginning on Sunday.
The beginning of year date and/or beginning of week day can be changed by using ft_DateCnfg(), which will affect all subsequent calls to ft_Qtr() until another call to ft_DateCnfg().
The beginning of year date and beginning of week day may be reset to January 1 and Sunday by calling ft_DateCnfg() with no parameters.
Examples
LOCAL aDateInfo
// get info about quarter containing 1990-09-15
aDateInfo := ft_Qtr( 0d19900915 )
? aDateInfo[ 1 ] // --> 199003 (3rd quarter)
? aDateInfo[ 2 ] // --> 1990-07-01 beginning of quarter 3
? aDateInfo[ 3 ] // --> 1990-09-30 end of week quarter 3
// get info about quarter 2 in year containing 1990-09-15
aDateInfo := ft_Qtr( 0d19900915, 2 )
? aDateInfo[ 1 ] // --> 199002
? aDateInfo[ 2 ] // --> 1990-04-01 beginning of quarter 2
? aDateInfo[ 3 ] // --> 1990-06-30 end of quarter 2
// get info about quarter 2 in current year (1991)
aDateInfo := ft_Qtr( , 2 )
? aDateInfo[ 1 ] // --> 199102
? aDateInfo[ 2 ] // --> 1991-04-01 beginning of quarter 2
? aDateInfo[ 3 ] // --> 1991-06-30 end of quarter 2
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
nWeekNum is a number from 1 to 53 signifying a week. Defaults to current week if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year and week as a character string "YYYYWW" aDateInfo[ 2 ] - The beginning date of the week aDateInfo[ 3 ] - The ending date of the week
Description
ft_Week() returns an array containing data about the week containing the given date.
Normally the return data will be based on a year beginning on January 1st with weeks beginning on Sunday.
The beginning of year date and/or beginning of week day can be changed by using ft_DateCnfg(), which will affect all subsequent calls to ft_Week() until another call to ft_DateCnfg().
The beginning of year date and beginning of week day may be reset to January 1 and Sunday by calling ft_DateCnfg() with no parameters.
Examples
LOCAL aDateInfo
// get info about week containing 1990-09-15
aDateInfo := ft_Week( 0d19900915 )
? aDateInfo[ 1 ] // --> 199037 (37th week)
? aDateInfo[ 2 ] // --> 1990-09-09 beginning of week 37
? aDateInfo[ 3 ] // --> 1990-09-15 end of week 37
// get info about week 25 in year containing 1990-09-15
aDateInfo := ft_Week( 0d19900915, 25 )
? aDateInfo[ 1 ] // --> 199025
? aDateInfo[ 2 ] // --> 1990-06-17 beginning of week 25
? aDateInfo[ 3 ] // --> 1990-06-23 end of week 25
// get info about week 25 in current Year( 1991 )
aDateInfo := ft_Week( , 25 )
? aDateInfo[ 1 ] // --> 199025
? aDateInfo[ 2 ] // --> 1991-06-16 beginning of week 25
? aDateInfo[ 3 ] // --> 1991-06-22 end of week 25
The number of work days (Monday through Friday) between two dates.
Description
ft_Workdays() returns a number indicating the number of work days between two dates. Work days are considered Monday through Friday. (The five day work week none of us Clipper programmers have.)
dDate is a date in the form "mm/dd/yy" or "mm/dd/yyyy"
Returns
Return numeric position of week within the year or NIL if parameter does not conform.
Description
Considers a full week as starting on Sunday, ending on Saturday. First week of year (week 1) may start on any day, and thus
contain any number of days.
Final week of year (week 53) may contain any number of days. Handles dates with CENTURY ON|OFF, to allow for 21st century. Date validation must be external to this function.
Examples
LOCAL dDate, GetList := {}
// These code fragments find the week number, given a date.
// literal character date
? ft_WoY( 0d19910101 ) // --> 1
// presume OS date to be 1991-01-06
? ft_WoY( Date() ) // --> 2
// date input
dDate := 0d0
@ 4, 10 GET cDate // input 1991-07-04
READ
? ft_WoY( dDate ) // --> 27
// last day of year
? ft_WoY( 0d19911231 ) // --> 53
dGivenDate is any valid date in any date format. Defaults to current system date if not supplied.
Returns
A three element array containing the following data:
aDateInfo[ 1 ] - The year as a character string "YYYY"
aDateInfo[ 2 ] - The beginning date of the year
aDateInfo[ 3 ] - The ending date of the year
Description
ft_Year() returns an array containing data about the year containing the given date.
Normally the return data will be based on a year beginning on January 1st.
The beginning of year date can be changed by using ft_DateCnfg(), which will affect all subsequent calls to ft_Year() until another call to ft_DateCnfg().
The beginning of year date may be reset to January 1 by calling ft_DateCnfg() with no parameters.
Examples
LOCAL aDateInfo
// Get info about year containing 1990-09-15, assuming default
// beginning of year is January 1st.
aDateInfo := ft_Year( 0d19900915 )
? aDateInfo[ 1 ] // --> 1990
? aDateInfo[ 2 ] // --> 1990-01-01 beginning of year
? aDateInfo[ 3 ] // --> 1990-12-31 end of year
// get info about current year (1991).
aDateInfo := ft_Year()
? aDateInfo[ 1 ] // --> 1991
? aDateInfo[ 2 ] // --> 1991-01-01 beginning of year
? aDateInfo[ 3 ] // --> 1991-12-31 end of year
Retrieve and optionally change the current default drive
Syntax
ft_Default( [ <cDrive> ] ) β cDrive
Arguments
cDrive is optional, and if specified is the new default drive.
Returns
The current default drive. If a change of default drive is requested, the return value is the drive after the change is made. This allows you to make sure you specified a valid drive (i.e. if you attempt to change the default drive, and the function returns a different drive letter than the one you specified, then the drive does not exist).
Description
Useful any time you need to know or change the default drive.
Examples
LOCAL cDrive := ft_Default() // Get the current drive
ft_Default( "C" ) // Switch to drive C:
IF ! ft_Default( "E" ) == "E"
? "Drive E: does not exist!"
ENDIF
Return the current DOS major and minor version as a string
Syntax
ft_DosVer() β cVersion
Arguments
None
Returns
A character string with the major version number first, a period ("."), then the minor version number (e.g., "3.30")
Description
ft_DosVer() invokes DOS interrupt 21h, service 30 in order to return the current DOS version. It does this by setting up an array corresponding to machine registers and then calling the toolkit function ft_int86().
It returns a character string corresponding to the DOS version, as follows: The major version, a period ("."), then the minor version.
nDrive is the diskette drive number, 0 = A:, 1 = B:
Returns
-1 - Wrong Parameters
0 - Drive Loaded and ready to read or write 1 - Drive Door Open or Diskette inserted upside down 2 - Diskette is unformatted 3 - Write protected 4 - Undetermined
Description
ft_FlopTst() is designed as a full replacement for ISDRIVE(). Where ISDRIVE() returns just .T. or .F. depending if the diskette drive is ready or not, ft_FlopTst() returns a numeric code designating the diskette drive's status.
ft_FlopTst() is particularly useful in backup and restore programs that need to test the floppy drive before writing/reading from a floppy disk.
No testing has been performed on systems with more than 2 floppy drives. If the third drive is "C" and the fourth "D" then there should be no problems.
Examples
LOCAL iStatus := ft_FlopTst( "A:" )
DO CASE
CASE iStatus == 1
? "The door to drive A is open."
CASE iStatus == 2
? "The diskette in drive A is not formatted."
CASE iStatus == 3
? "The diskette in drive A is write-protected."
CASE iStatus == 4
? "Something is wrong with drive A, but I don't know what."
ENDCASE
aRegisterValues is an array that contains values to be loaded into the various CPU registers. The correspondence between registers and array elements is as follows:
.T. if all parameters valid and the function was able
to execute the desired interrupt.
.F. if invalid parameters passed. If you call this function in
protected mode, .F. may also be returned if an allocation of low DOS memory fails.
In addition, the array elements will contain whatever values were in the CPU registers immediately after the interrupt was executed. If either of the string parameters were altered by the interrupt, these changes will be reflected as well.
Description
It is occasionally useful to be able to call interrupts directly from Clipper, without having to write a separate routine in C or ASM. This function allows you that capability.
Given Clipper's high-level orientation, this function is necessarily somewhat messy to use. First, declare an array of ten elements to hold the eight values for the CPU registers and two string parameters. Then initialize the array elements with the values that you want the CPU registers to contain when the interrupt is executed. You need not initialize all the elements. For example, if the interrupt requires you to specify values for AX, DX, and DS, you would only need to initialize elements 1, 4, and 8.
Once you have done the required register setup, call ft_int86(), passing the interrupt number and the register array as parameters. The function will load the CPU with your specified values, execute the interrupt, and then store the contents of the CPU registers back into your array. This will allow you to evaluate the results of the interrupt.
Some interrupt services require you to pass the address of a string in a pair of registers. This function is capable of handling these sorts of situations, but it will take a little work on your part. If you need to pass a string that uses the DS register, store the string in element 8; if you need to pass a string that uses the ES register, store the string in element 9. ft_int86() will detect that you've supplied a string instead of a numeric value and will behave accordingly.
That takes care of obtaining the segment portion of the pointer. To specify which register is to contain the offset, use the values REG_DS and REG_ES which are defined in the ftint86.ch file. When one of these values is found in an array element, it alerts ft_int86() to use the offset portion of a pointer instead of a numeric value. REG_DS tells ft_int86() to use the offset of the string in element 8, while REG_ES tells ft_int86() to use the offset of the string in element 9.
All the CPU registers are sixteen bits in size. Some, however, are also split into two 8-bit registers. This function is only capable of receiving and returning registers that are 16 bits in size. To split a 16-bit register into two 8-bit values, you can use the pseudo-functions HighByte() and LowByte(), contained in the .ch file.
To alter an 8-bit number so it will appear in the high-order byte of a register when passed to the ft_int86() function, use the MakeHI() pseudo-function contained in the .ch file.
When run in real mode, this function is a shell for __ftint86(), which is written in assembler and does the actual work of executing the interrupt. __ftint86() is callable from C, so feel free to incorporate it into any C routines for which it might be useful. The source for __ftint86() can be found in the file AINT86.ASM.
When run in protected mode, this function is a shell for cpmiInt86(), which is written in assembler and makes a DPMI call to drop into real mode and execute the interrupt. cpmiInt86() is also callable from C, so feel free to incorporate it into any C routines for which it might be useful. cpmiInt86() is part of the CPMI API. See the CPMI documentation for more information.
Examples
// FIXME
// This example shows how to call the DOS "create file" service. Take
// special note of how to set up string parameters.
#include "ftint86.ch"
LOCAL aRegs[ 10 ] // Declare the register array
aRegs[ AX ] := makehi( 60 ) // DOS service, create file
aRegs[ CX ] := 0 // Specify file attribute
// Pay attention here, this is crucial. Note how to set up the string
// so it appears in DS:DX.
aRegs[ DS ] := "my_file.ext"
aRegs[ DX ] := REG_DS
ft_int86( 33, aRegs ) // Make the call to the DOS interrupt
// This example shows how to call the DOS "get current directory"
// service. This one also uses a string parameter, but note that it
// uses a different offset register.
#include "ftint86.ch"
LOCAL aRegs[ 10 ]
aRegs[ AX ] := makehi( 71 )
aRegs[ DX ] := 0 // Choose default drive
// This service requires a 64-byte buffer whose address is in DS:SI. DOS
// will fill the buffer with the current directory.
aRegs[ DS ] := Space( 64 )
aRegs[ SI ] := REG_DS
ft_int86( 33, aRegs )
? aRegs[ DS ] // Display the directory name
// For the sake of completeness, here's an example that doesn't use a
// string. This one changes the video mode.
#include "ftint86.ch"
LOCAL aRegs[ 10 ]
aRegs[ AX ] := 16 // Choose hi-res graphics
ft_int86( 16, aRegs )
Inform the operating system that the application is idle.
Syntax
ft_IAmIdle() β lSuccess
Arguments
None
Returns
.T. if supported, .F. otherwise.
Description
Some multitasking operating environments (e.g. Windows or OS/2) can function more efficiently when applications release the CPU during idle states. This function allows you "announce" to the operating system that your application is idle.
Note that if you use this function in conjunction with ft_OnIdle(), you can cause Clipper to automatically release the CPU whenever Clipper itself detects an idle state.
Examples
#include "inkey.ch"
DO WHILE Inkey() != K_ESC
ft_IAmIdle() // Wait for ESC and announce idleness
ENDDO
// Here's another way to do it:
ft_OnIdle( {|| ft_IAmIdle() } )
Inkey( 0 ) // Automatically reports idleness until key is pressed!
cDevice is optional and is the device to test (LPT2, COM1, etc.). If omitted, the function will default to the PRN device.
Returns
.T. if device is ready for output. .F. if one of the following conditions occurs:
1) The device is not ready. 2) The device does not exist. 3) DOS couldn't open the device for some reason
(such as no file handles available).
Description
The Clipper IsPrinter() function is somewhat limited because it only works with LPT1. Furthermore, it talks directly to the hardware, so if you have redirected LPT1 via the DOS MODE command, the IsPrinter() function will return erroneous results.
This function offers a better alternative. Instead of talking to the hardware, it issues a DOS call that checks to see if the device is ready or not. That gives DOS an opportunity to deal with any redirections, and since you pass the device name as a parameter, you can test any device, not just LPT1 (note that the function defaults to PRN if you fail to pass a valid parameter).
The function also temporarily traps the DOS critical error handler so you don't get any nasty error messages if the device isn't ready. It restores the old critical error handler before exiting.
Note that although this function is mainly designed for testing printers, you can also check to see if a drive is ready. Since DOS thinks the NUL device exists on every drive, you can pass a drive letter followed by NUL as a parameter. If DOS is able to open the NUL device, then the drive is ready, otherwise the door is open or something else is wrong.
Examples
IF ! ft_IsPrint()
? "PRN is not ready!"
ENDIF
IF ! ft_IsPrint( "COM2" )
? "Check the device on COM2. Something is wrong."
ENDIF
IF ! ft_IsPrint( "/dev/lp0" )
? "Oops, not available."
ENDIF
nSegment is the segment of the desired memory address.
nOffset is the offset of the desired memory address.
Returns
nValue will be a value from 0 to 255 if all parameters were valid and
the function was able to retrieve the desired byte.
nValue will be -1 if invalid parameters were passed.
Description
Use this function if you have a need to examine a specific memory location. The function will return the byte at the specified address as a numeric value. If you need this value as a character, use the hb_BChar() function to convert it.
Examples
? ft_Peek( 0, 0x449 ) // Get the current video mode (MS-DOS)
nSegment is the segment of the desired memory address.
nOffset is the offset of the desired memory address.
nValue is the value to write to the desired memory address.
Returns
lResult will be .T. if all parameters were valid and the function was
able to write the desired byte.
lResult will be .F. if invalid parameters were passed.
Description
Use this function if you have a need to change the value at a specific memory location. The function will write the specified byte to the specified address. The value must be passed as a numeric; if the byte you wish to use is stored as a character, use the hb_BCode() function to convert it.
dDate is a Clipper date variable that you want to set the current OS system date to.
It is up to you to send in a valid date. The year must be within the range 1980 through 2099. If the OS thinks the date is not valid, it won't change the date.
Returns
lResult is simply the result of ft_int86(), passed back to your program.
Description
ft_SetDate() uses NANFOR.LIB's ft_int86() function to invoke the DOS Set Date service (Interrupt 33, service 43).
Examples
// The following program takes a date from the command-line and sets
// the OS system date:
LOCAL dDate := Date() + 1
? "Setting date to:", dDate
ft_SetDate( dDate )
? "Today is now:", Date()
cTime is a string in the form hh:mm:ss that you want to set the current DOS system time to.
Use 24-hour time. It is up to you to send in a valid time. If DOS doesn't think it is valid, it won't reset the time anyway.
Returns
lResult is simply the result of ft_int86(), passed back to your program.
Description
ft_SetTime() uses NANFOR.LIB's ft_int86() function to invoke the DOS Set Time service (Interrupt 33, service 45).
Examples
// The following program takes a time string from the command-line and sets
// the DOS system time:
LOCAL cTime := Time()
? "Setting time to:", cTime + "... "
ft_SetTime( cTime )
? "Time is now:", Time()
cPath is the directory where you want to create the temporary file. If you omit this argument, the root of the current drive is assumed.
If lHide is .T., then the file will be created with the hidden attribute set. The default is .F.
Returns
cFileSpec should be your path, including the name of the newly created unique file. You are safe to create a new file with this filename.
If a DOS error occurred when trying to create the file, a null string will be returned.
Description
This function uses DOS Interrupt 21, service 5Ah (Create temporary file) to create a unique filename in a directory you specify. There will be no extension. After the file is created, you may do any I/O you need (see the test driver in the source code).
// Create a unique file in the root of the current drive:
? ft_TempFil()
// Create a unique file in the current directory and hide it:
? ft_TempFil( ".", .T. )
// Create a unique file on another directory, but do not hide it:
? ft_TempFil( "mytempdir" )
xReceiveVar is the variable to receive the environment data.
xReceiveVar can be a character type variable, in which case the function will place all environment strings in the variable separated by carriage return/line feeds (Chr( 13 ) + Chr( 10 )).
xReceiveVar can be an array type, in which case the function will place each string in an array element. The array MUST be declared with the proper number of elements prior to passing it to the function. This can be done by calling ft_GetE() without parameters first to get the number of strings in the environment.
Note that the argument MUST be passed by reference. Since arrays are by nature passed by reference, the "@" symbol is optional when passing an array.
If no argument is passed, ft_GetE() merely returns the number of strings in the environment.
Returns
ft_GetE() returns the total number of strings found in the current program's environment.
Description
This function stores ALL of the current program's environment variables in either a block of text lines or in an array. It is useful for looking at the entire environment at once, or recording a snapshot of it to a file for later inspection, such as when a program error occurs. If the value of one specific variable is desired, use Clipper's built-in GetE() function.
Examples
// Get the environment in text form and browse it:
LOCAL cEnvBlock := ""
LOCAL nNumStrings := ft_GetE( @cEnvBlock )
LOCAL aEnvArray
@ 0, 0 TO MaxRow() - 1, MaxCol()
@ MaxRow(), 0 SAY 'Browse strings, press <Esc> to exit...'
hb_MemoWrit( cEnvBlock, 1, 1, MaxRow() - 2, MaxCol() - 1, .F. )
// Get the environment in text form and write it to a file:
cEnvBlock := ""
ft_GetE( @cEnvBlock )
hb_MemoWrit( "environ.txt", cEnvBlock )
// Get the environment in Array form:
aEnvArray := Array( ft_GetE() )
ft_GetE( aEnvArray )
? aEnvArray[ 1 ]
? aEnvArray[ 2 ]
cString is a character string containing one or more function
calls
Returns
.T. if all functions within the string are currently linked into the application, .F. if one or more aren't. See below for a definition of "function."
Description
This function would be used in data driven application to determine whether or not a macro compiled function was linked in.
Several functions can be passed, and nested, in cString.
Caveat: Some function calls are converted by the preprocessor into other function calls. You cannot have these types of functions in a macro compiled string as they never exist at runtime. ft_Linked() will correctly tell you that they are invalid.
For instance: there is no function called "SORT()" in any of the Nantucket Libraries, but it is a valid CLIPPER command because the preprocessor will convert it to other function calls.
Examples
LOCAL cString := "ft_GoodFunc( BadFunc( 3, 2 ) )"
IF ft_Linked( cString )
Eval( &( "{||" + cString + "}" ) )
ELSE
? "Error:", cString, "was not linked in. Called by ft_Linked()"
ENDIF
Report the drive, path and filename of the current program
Syntax
ft_Origin() β cString
Arguments
None
Returns
A string containing the full drive/directory/filename of the currently executing file.
Description
Often users will install multiple copies of application software, especially on networks and in situations where the user is trying to get around a copy protection scheme.
This function enables you to learn the name and source location of the currently executing file, so that you may take whatever action you need to.
Examples
IF ! hb_FNameNameExt( ft_Origin() ) == "myapp.exe"
? "Incorrect startup file. Please remove/rename and start again"
ENDIF
aOldSets is an array of SET settings created by ft_SaveSets()
Returns
NIL
Description
This function "restores" the SET Settings, i.e., it sets them to the values in the array aOldSets. The following SETs are not currently supported: FILTER, FORMAT, FUNCTION, INDEX, KEYS, MODE, ORDER, PROCEDURE, RELATION, TYPEAHEAD
An array containing the values of the supported SETs.
Description
This function saves the SET Settings, i.e., it copies them into an array, aOldSets. The following SETs are not currently supported: FILTER, FORMAT, FUNCTION, INDEX, KEYS, MODE, ORDER, PROCEDURE, RELATION, TYPEAHEAD
Examples
LOCAL aOldSets := ft_SaveSets()
? hb_ValToExp( aOldSets )
.F. - Toggle CENTURY off .T. - Toggle CENTURY on If not specified, leave CENTURY as is
Returns
The state of the CENTURY setting upon entry to the routine
Description
This function returns the state (ON/OFF, TRUE/FALSE) of the CENTURY and optionally sets it ON or OFF.
Examples
? ft_SetCentury() // Get current CENTURY Setting
? ft_SetCentury( .T. ) // Get the current CENTURY Setting
// and turn it on (set it to TRUE)
? ft_SetCentury( .F. ) // Get the current CENTURY Setting
// and turn it off (set it to FALSE)
Generate an idle event to allow incremental garbage collection.
Syntax
ft_Idle()
Arguments
None
Returns
NIL
Description
During memory-intensive operations that do not generate much in the way of idle states, the Clipper runtime may not get a chance to perform garbage collection of discarded memory. This can eventually lead to any of a variety of memory-related internal errors.
This function attempts to alleviate the problem by providing a mechanism by which an idle event can be artificially generated at will. The idle event will cause the CA-Cl*pper runtime to perform an incremental memory scavenge.
This function makes use of an undocumented internal routine. If this this fact makes you uncomfortable then don't use this function, you miserable jello-spined lump of human debris.
Examples
// FIXME
DO WHILE Whatever // Some batch process
Something() // Create 'n' discard a bunch of stuff
ft_Idle() // Take out the garbage
ENDDO
Evaluate a designated code block during idle states.
Syntax
ft_OnIdle( [<bCode>] )
Arguments
bCode is the code block to evaluate.
Returns
NIL
Description
This function allows you to evaluate code blocks in the background while the foreground is in an idle state.
To halt the evaluation of the code block during idle states, call ft_OnIdle() with no arguments.
This function makes heavy use of several undocumented internal routines. If this fact makes you uncomfortable then don't use this function, you putrid pile of chicken excrement.
Examples
ft_OnIdle( {|| QOut( "Hey, I'm not busy!" ) } )
Inkey( 0 ) // Let the fun begin
Evaluate a designated code block at a designated interval.
Syntax
ft_OnTick( bCode, nInterval )
Arguments
bCode is the code block to evaluate. nInterval is the number of clock ticks to wait between
evaluations of the code block.
Returns
NIL
Description
This function effectively allows you to run tasks in the background by transparently and periodically calling a designated routine.
To halt the execution of the background function, call ft_OnTick() with no arguments.
This function makes heavy use of several undocumented internal routines. If this fact makes you uncomfortable then don't use this function, you quivering sack of cowardly slime.
Examples
// Set up a self-updating on-screen clock
ft_OnTick( @Clock(), 9 )
STATIC PROCEDURE Clock()
LOCAL nRow := Row()
LOCAL nCol := Col()
@ 0, 0 SAY Time()
SetPos( nRow, nCol )
RETURN
cInFile - text file to display (full path and filename) nTop - upper row of window nLeft - left col of window nBottom - lower row of window nRight - right col of window nStart - line to place highlight at startup nCNormal - normal text color (numeric attribute) nCHighlight - text highlight color (numeric attribute) cExitKeys - terminating key list (each byte of string is a
key code)
lBrowse - act-like-a-browse-routine flag nColSkip - col increment for left/right arrows nRMargin - right margin - anything to right is truncated nBuffSize - size of the paging buffer
Note: make sure you allocate a buffer large enough to hold enough data for the number of lines that you have in the window. Use the following formula as a guideline:
buffer size = (# of line) + 1 * RMargin
This is the smallest you should make the buffer. For normal use, 4096 bytes is recommended
This routine displays a text file within a defined window using as little memory as possible. The text file to display has to be present or an error value of 0 is returned (as a character.)
Assumptions: The routine assumes that all lines are terminated
with a CR/LF sequence (0x0d and 0x0a).
Note: Make sure you allocate a buffer large enough to hold
enough data for the number of lines that you have in the window. Use the following formula as a guideline - buffer size = (# of line) + 1 * RMargin this is the smallest you should make the buffer and for normal use I recommend 4096 bytes.
Cursor Keys: Up, Down - moves the highlight line
Left, Right - moves the window over nColSkip col's Home - moves the window to the far left End - moves the window to the nRMargin column PgUp, PgDn - moves the highlight one page Ctrl+PgUp - moves the highlight to the file top Ctrl+PgDn - moves the highlight to the file bottom Ctrl+Right - moves the window 16 col's to the right Ctrl+Left - moves the window 16 col's to the left
Esc, Return - terminates the function
All other keys are ignored unless they are specified within cExitKeys parameter. This list will tell the routine what keys terminate the function. Special keys must be passed by a unique value and that value can be found by looking in the dhkey.h file.
Appends a line to the currently selected text file
Syntax
ft_FAppend( [ <nLines> ] ) β NIL
Arguments
nLines is the number of lines that should be appended to the end of the currently selected text file.
If nLines is omitted, one record is appended.
Returns
lSuccess. If FALSE, check ft_FError() for the error code.
Description
This function appends a line of text to the file in the currently selected text file workarea. Text lines are delimited with a CRLF/LF. The record pointer is moved to the last appended record.
Multiple lines may be appended with one call to ft_FAppend().
A text file "record" is a line of text terminated by a CRLF/LF. Each line appended with this function will be empty.
NOTE: Occasionally a text file may contain a non-CRLF/LF terminated line, at the end of the file ("stragglers"). This function assumes these stragglers to be the last line of the file, and begins appending the new lines after this line. In other words, if the last line in the text file is not terminated with a CRLF/LF prior to calling ft_FAppend(), the function will terminate that last line before appending any new lines.
Examples
// add a blank line of text to a file
ft_FUse( "test.txt" )
ft_FGoBot()
? ft_FRecNo()
ft_FAppend()
ft_FGoBot()
? ft_FRecNo()
Deletes a line from the currently selected text file
Syntax
ft_FDelete( [ <nLines> ] ) β lSuccess
Arguments
nLines is the number of lines to be eliminated, beginning with the current record position.
If nLines is omitted, the current record is deleted only.
Returns
TRUE if successful, otherwise check ft_FError() for error code.
Description
This function deletes one or several lines of text from the file in the currently selected text file workarea. Text lines are delimited with a CRLF/LF. The record pointer is not moved, unless the deleted lines occur at the end of the file, in which case ft_FRecNo() will equal ft_FLastRe() and ft_FEof() will be set to TRUE.
Examples
// delete the next 4 lines from a file
ft_FUse( "test.txt" )
? ft_FDelete( 4 )
Move record pointer to specific record in a text file
Syntax
ft_FGoto( nLine ) β NIL
Arguments
nLine is the record number to go to.
Returns
NIL
Description
This function moves the record pointer to a specific record in the file in the currently selected text file workarea. If the record number requested is greater than the number of records in the file, the record pointer will be positioned at the last record.
Internally, the function operates differently depending on how you invoke it. Passing a value for nLine results in what is effectively a skip operation, which is fairly quick. However if you pass 0 for nLine, e.g. ft_FGoto( 0 ), the function internally goes to the top of the file, then skips down the required number of records. Hence if your file is relatively large and the current record is a high number, you may see some delay as ft_FGoto( 0 ) skips through the file.
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
// read 5th line of text from file
ft_FUse( "test.txt" )
ft_FGoto( 5 )
? ft_FReadLn()
This function moves the record pointer to the first record in the currently selected text file workarea.
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
ft_FUse( "test.txt" ) // open text file
DO WHILE ! ft_FEof()
? ft_FReadLn() // read thru file
ft_FSkip()
ENDDO
ft_FGoTop() // go back to top
? ft_FRecNo() // 1
Get the no. of records in the currently selected text file
Syntax
ft_FLastRe() β nLastRecordNum
Arguments
None
Returns
An integer containing the number of records in the text file in the currently selected text file workarea, or zero if no file is currently open in the workarea.
Description
This function returns the number of the last record in a text file.
A text file "record" is a line of text terminated by a CRLF/LF.
A string containing the current record in a text file.
Description
This function returns a line of text read from the file in the currently selected text file workarea. Text lines are delimited with a CRLF/LF. The record pointer is not moved.
Currently the maximum record size is 4096 characters. You may increase the maximum record size by changing the value of #define BUFFSIZE in the C source and recompiling, however you should consider the performance implications if you do (all read and writes use this buffer size, including ft_FSkip()'s and ft_FGoto()'s).
If a read error occurs ft_FError() will contain the error code.
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
// display each record of a text file
ft_FUse( "test.txt" )
DO WHILE ! ft_FEof()
? ft_FReadLn()
ft_FSkip()
ENDDO
The current record number of a text file or 0 if no file is open.
Description
This function returns the current record number of the file open in the currently selected text file workarea.
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
ft_FUse( "test.txt" ) // open text file
DO WHILE ! ft_FEof()
? ft_FReadLn() // read thru file
ft_FSkip()
ENDDO
ft_FGoTop() // go back to top
? ft_FRecNo() // 1
This function selects a text file "workarea" from 1 to 10. A file may or may not be open in the selected area.
Passing 0 for nNewArea selects the next available workarea, similar to Clipper's SELECT 0 command. If no more workareas are available the current workarea is not changed.
Each file is opened in its own "workarea", similar to the concept used by dbf files. As provided, a maximum of 10 files (in 10 workareas) can be opened (assuming there are sufficient file handles available). That number may be increased by modifying the #define TEXT_WORKAREAS in the C source code and recompiling.
All the ft_F*() file functions operate on the file in the currently selected text file workarea.
Text file workareas are separate from and independent of Clipper's database workareas.
Examples
LOCAL nFile1, nFile2
ft_FSelect( 1 )
nFile1 := ft_FUse( "test.txt" )
? ft_FLastRe() // no. of lines in test.txt
ft_FSelect( 2 )
nFile2 := ft_FUse( "test.dbf" )
? ft_FLastRe() // no. of lines in test.dbf
Move the record pointer to a new position in a text file
Syntax
ft_FSkip( [ <nLines> ] ) β nLinesSkipped
Arguments
nLines is the number of lines to skip. Defaults to 1 if not specified.
Returns
The number of lines actually skipped. If the file's EOF or BOF was encountered before nLines could be skipped, the return value will be less than nLines.
Description
This function moves the text file record pointer, similar to the CLIPPER SKIP command.
Use the return value to determine how many records were actually skipped, for example to write a custom skipper function for TBrowse-ing text files.
If a read error occurs ft_FError() will contain the error code.
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
// display each record of a text file
ft_FUse( "test.txt" )
DO WHILE ! ft_FEof()
? ft_FReadLn()
ft_FSkip()
ENDDO
cFile is the text file you want to open. If not specified, the file currently open, if any, will be closed.
nMode is the open mode for the file. Please refer to the discussion of file open modes in fileio.ch for a list of allowable open modes. If not specified, the file will be opened with a mode of FO_READ + FO_SHARED.
Returns
If cFile is passed and the file is opened successfully, an integer containing the text file's workarea. If the file cannot be opened, 0 will be returned. In this case, check the return value of ft_FError() for the cause of the error.
If ft_FUse() is called without any arguments, it will close the text file in the current "text area" and return 0.
If a read error occurs ft_FError() will contain the error code.
Description
The ft_F*() file functions are for reading text files, that is, files where each line (record) is delimited by a CRLF/LF.
Each file is opened in its own "workarea", similar to the concept use by dbf files. As provided, a maximum of 10 files (in 10 workareas) can be opened (assuming there are sufficient file handles available). That number may be increased by modifying the #define TEXT_WORKAREAS in the C source code and recompiling.
Examples
#include "fileio.ch"
? ft_FUse( "test.txt" ) // Open a text file for reading
? ft_FUse( "test.txt", FO_READWRITE + FO_SHARED ) // Open a text file for reading and writing
? ft_FUse() // Close file
cData is a string of data to write to the file at the current
record position.
lInsert is a logical indicating whether the contents of the current record are to be preserved, that is, if lInsert evaluates to .T., the a new record is inserted at the current position. The current record then is pushed down to ft_FRecNo()+1.
If lInsert is .F. or omitted, the current record is replaced by cData.
Returns
TRUE if successful, otherwise check ft_FError() for error code.
Description
This function writes a line of text to the file in the currently selected text file workarea. Text lines are delimited with a CRLF/LF. The record pointer is not moved.
The contents of the current record are updated to reflect the new new line written, unless the Insert option is selected.
Writing a null string has the effect of clearing the current line if in overstrike mode, else inserting a new line (same as ft_FInsert()).
A text file "record" is a line of text terminated by a CRLF/LF.
Examples
// write a line of text to a file
ft_FUse( "test.txt" )
DO WHILE ! hb_LeftEqI( ft_FReadLn(), "===" ) .AND. ! ft_FEof()
ft_FSkip()
ENDDO
? ft_FWriteLn( "FILES=30", ft_FEof() )
It is occasionally useful to force LastKey() to return a known value. This is easily accomplishing by using the KEYBOARD command, but this has undesirable side effects (the keyboard buffer is cleared, and the keystroke is processed whether you needed it to be or not). This function accomplishes the same task but without the side effects. It does so by directly modifying the memory location where Clipper stores the LastKey() value.
Some highly unorthodox programming techniques, not to mention rather strange use of Clipper internals, was necessary to make this function work. If this makes you uncomfortable, then don't use this function, you worthless crybaby.
nTop, nLeftnBottomnRight are the four corners of the
screen region in row and column coordinates.
Returns
NIL
Description
This function tells the mouse driver to hide the cursor if it is in the given region. The driver hides the cursor by decrementing the cursor flag. A call to ft_MShowCrs() is required to turn the cursor back on. Calling ft_MShowCrs() also disables this function.
See ft_MShowCrs() for a discussion of the cursor display flag.
nClick is a numeric value. If it is zero ft_MDblClk() will not
check for the first press but rather will simply wait the specified period for a single press. This is useful if this routine is called from one which in turn responded to a button press. If it is not present or not equal to 0, then ft_MDblClk() will wait for two presses of the specified button.
nButton is the mouse button number
0 - Left Button 1 - Right Button 2 - Middle Button [if applicable]
nInterval is the interval to wait for the first click if requested
and the time to wait for the second. If not present then defaults to 0.5 second.
nRow is the row number for the mouse cursor location for a double click
to be valid. If not present then the current position is taken as the valid location.
nCol is the column number for the mouse cursor location for a double
click to be valid. If not present, then the current position is taken as the valid location.
nTime is an optional start time for the waiting period for the first
click (of either one or two requested). If not given then the time is set at entry into this routine. This is useful when this routine is called from another routine which was called in response to a mouse click but needs to know if a double click has occurred
Returns
.T. if a double click was detected.
Description
This is a mouse meta function that checks for the presence of a double click.
Examples
IF ft_MInRegion( 10, 10, 11, 20 ) .AND. ;
ft_MDblClk( 0, 1,, ft_MGetX(), ft_MGetY() ) // double click, right button
// at current location with
// default interval
// MnuItem1()
ENDIF
nCrsType is the cursor type. A value of 0 indicates the software cursor
(the default) and a value of 1 indicates the hardware cursor.
nScrMask is the screen mask for the software cursor or the first scan
line of the hardware cursor. See the description for more information.
nCrsMask is the cursor mask for the software cursor of the last scan
line of the hardware cursor. See the description for more information.
Returns
NIL
Description
In text mode the mouse cursor can either be a software generated or the actual hardware cursor. This routine allows one choose between them. The software cursor is the default and its effect on the character it covers is determined by the screen mask and the cursor mask. Both of these masks are 16-bit values (which in Clipper are passed as standard numerical values). The 16-bit masks are arranged in a manner identical to the way information is stored for each character cell on the screen. The low order 8 bits represent the actual character displayed while the high order bits represent the display attributes such as blinking, intensity and foreground and background colors. The mask is represented in the diagram below:
Blinking and high intensity are on when the bit is 1. The background and foreground indicate which colors are used for each. The software mouse cursor uses these two values by taking the mask from the screen cell it is on and performing a logical AND on each bit with the screen mask value. The result is then logically XOR'ed with the cursor mask value. Thus to keep the character the same but invert the foreground and background colors the following values would be used:
The hardware cursor is the text cursor provided by the video board. One specifies the range of scan lines which are on using nScrMask and nCrsMask. The range of values is dependent upon the type of monitor. The first scan line is 0.
nPage is the display page on which the mouse is currently being
displayed
Description
This function gets the display page for the mouse cursor. The valid values of nPage is dependent upon the display mode. See ft_SetVPg() for changing the current video page
Examples
? ft_MGetPage( ) // Gets the mouse cursor display page
nX is a variable that will receive the mouse X position in virtual screen coordinates. It must be passed by reference.
nY is a variable that will receive the mouse Y position in virtual screen coordinates. It must be passed by reference.
Returns
an integer representing button status
Β 0Β -Β noΒ buttonΒ pressed
Β 1Β -Β leftΒ pressed
Β 2Β -Β rightΒ pressed
Β 3Β -Β leftΒ andΒ rightΒ pressed
Β 4Β -Β middleΒ pressed
Β 5Β -Β leftΒ andΒ middleΒ pressed
Β 6Β -Β rightΒ andΒ middleΒ pressed
Β 7Β -Β allΒ threeΒ buttonsΒ pressed
Description
Loads cursor position into x and y coordinates passed by reference and returns the button status. The coordinate system in text mode has eight virtual coordinates per character cell. Thus x=16 means that you are in the Row 2. The values returned by this routine when in text mode and with mouse driver versions 6 and above are multiples of 8. We have experience with drivers prior to that version
Examples
LOCAL nX, nY
LOCAL nButton := ft_MGetPos( @nX, @nY )
? "Mouse Row :", nX
? "Mouse Column :", nY
? "Button Status:", nButton
nHoriz is the percentage of maximum horizontal sensitivity.
Passed by reference.
nVert is the percentage of maximum vertical sensitivity.
Passed by reference.
nDouble is the percentage of maximum sensitivity for doubling the
mouse cursor's speed on the screen. Passed by reference.
Returns
NIL
Description
This function returns the current values of the mouse movement sensitivity parameters. The first two arguments control the amount of movement necessary to move the cursor a given amount. The third argument determines the threshold above which the mouse moves at twice the normal speed. For further discussion of these values see ft_MSetSens()
nRowPos which is the row position of mouse in virtual screen
coordinates.
Description
Retrieves mouse's row position in virtual screen coordinates. The values returned are multiples of 8 when in text mode and with at least Microsoft drivers 6 and above.
nColPos Column position of mouse in virtual screen coordinates
Description
Retrieves mouse's column position in virtual screen coordinates. The values returned are multiples of 8 when in text mode and with at least Microsoft drivers 6 and above.
Decrement internal mouse cursor flag and hide mouse cursor
Syntax
ft_MHideCrs() β NIL
Arguments
NONE
Returns
NIL
Description
Hides the mouse cursor. Make sure to turn the mouse cursor off when redrawing screens. The mouse cursor dutifully saves the screen under it, so if you draw over the mouse cursor it will create a "hole" in your screen when you move the mouse cursor.
Note: A call to ft_MHideCrs() decrements a mouse driver variable which indicates whether the cursor is shown. The cursor is visible only when the variable = 0. Thus multiple calls to ft_MHideCrs() require an equal number of calls to ft_MShowCrs() before the cursor will again be visible. Once the variable is 0 calls to ft_MShowCrs() does not increment the variable above 0.
Initialize the mouse driver, vars and return status of mouse
Syntax
ft_MInit() β lMouseStatus
Arguments
NONE
Returns
An logical representing the mouse status (.F. == mouse not installed)
Description
Initializes the mouse drive, associated variables and returns mouse status. It checks to see if the mouse has been previously initialized and if so it does not reinitialize. The row and column limits of mouse movement is set to the maximum for the current video mode. Use ft_MShowCrs() to display the mouse cursor.
Examples
IF ! ft_MInit()
? "No mouse driver is installed"
ENDIF
An integer representing the mouse status (0 == mouse not installed)
Description
Resets the mouse driver and returns mouse status. Use ft_MShowCrs() to display the mouse cursor. The mouse is set to allow it to cover the complete screen (as defined by MaxCol() and MaxRow()). This is necessary because at least some versions of the mouse drivers do not operate according to the documentation when confronted with a 43 or 50 line screen.
Normally, ft_MInit() should be used to initialize the mouse since it will not reinitialize if already done.
Examples
IF ft_MReset() == 0
? "No mouse driver is installed"
ENDIF
This function sets the display page for the mouse cursor. The valid values of nPage is dependent upon the display mode. See ft_SetVPg() for changing the current video page
Examples
ft_MSetPage( 1 ) // Sets the mouse cursor to page 1
Position the mouse cursor using virtual screen coordinates
Syntax
ft_MSetPos( <nX>, <nY> ) β NIL
Arguments
nX is the desired mouse row.
nY is the desired mouse column.
Returns
NIL
Description
Positions mouse cursor on screen. The virtual coordinate system in text mode has eight virtual coordinates per character cell. Thus x=16 means that you are in the Row 2.
Examples
ft_MSetPos( 10, 20 ) // position mouse cursor at row 10, col 20
// in virtual screen coordinates
nHoriz is the sensitivity of the mouse on the horizontal axis. This
value is the integer percentage of highest sensitivity and thus has a range of 1 to 100. The default value is 50 and at this setting about 3.2 inches of mouse movement will move the mouse cursor across the screen. If NIL, the current value is used.
nVert is the relative sensitivity of the mouse on the vertical axis.
The value is an integer percentage of the highest sensitivity and thus has a range of 1 to 100. The default value is 50 and requires about 2 inches of mouse movement will move from top to bottom of the screen.IfNIL, the current value is used.
nDouble is the relative sensitivity of the mouse to doubling the ratio
of cursor movement to mouse movement. The default value is 50. If NIL, the current value is used.
Returns
NIL
Description
This function allows one to control the mouse movement sensitivity. The first two arguments control the amount of movement necessary to move the cursor a given amount. The values are the percentage of full sensitivity and the default values after installing the mouse driver is 50 which represents approximately 3.2 inches of horizontal and 2 inches of vertical mouse movement to cover the entire screen. A value of 100 requires about 0.9 inches of horizontal mouse movement to cover the screen from one side to the other.
The third argument changes the threshold above which the mouse moves at twice the normal speed. The value is a percentage of full sensitivity with the default (50) providing doubling at 64 mickeys per second.
NOTE: These values are NOT restored after resetting the mouse driver/ hardware. A well behaved application should reset them to the original value upon exiting.
NOTE: The above description is counter to all of the documentation I have available. However, it does not work the way it is documented with Microsoft drivers versions 6.16, 6.24, 7.04 and 8.20. The above movement values are documented to be the number of mickeys per 8 pixels and the double speed value as the number mickeys per second required to double the speed. Each of these values should range from 1 to 32000 but the driver forces a maximum of 100. Also the documentation states that resetting the mouse will reset these values. This is not the case.
Examples
ft_MSetSens( 75, 75, 50 ) // a little less mouse movement necessary.
Increment internal cursor flag and display mouse cursor
Syntax
ft_MShowCrs() β NIL
Arguments
NONE
Returns
NIL
Description
Displays the mouse cursor. Make sure to turn the mouse cursor off when redrawing screens. The mouse cursor dutifully saves the screen under it, so if you draw over the mouse cursor it will create a "hole" in your screen when you move the mouse cursor.
Note: A call to ft_MHideCrs() decrements a mouse driver variable which indicates whether the cursor is shown. The cursor is visible only when the variable = 0. Thus multiple calls to ft_MHideCrs() require an equal number of calls to ft_MShowCrs() before the cursor will again be visible. Once the variable is 0 calls to ft_MShowCrs() does not increment the variable above 0.
nMinor is the Minor version number. Passed by reference. nType is the Mouse type. Passed by reference.
1 = Bus Mouse 2 = Serial Mouse 3 = InPort Mouse 4 = PS/2 Mouse 5 = HP Mouse
nIRQ is the IRQ number used for the mouse. Passed by reference.
0 = PS/2 2,3,4,5 or 7 = IRQ number
Returns
nMajor which is the major version number of the mouse driver.
Description
This function returns the current values of the mouse driver version number and type. The major version would be 6 and the minor version would be 10 if the driver were version 6.10. The mouse type and IRQ numbers are also returned.
NOTE: It appears that the values reported when one starts the mouse driver actually have the minor version in hexadecimal! Thus on boot-up my screen showed 6.24 but this routine returned 30 for the minor version number!
Examples
LOCAL nMinor
LOCAL nMajor := ft_MVersion( @nMinor )
IF ( nMajor + nMinor / 100 ) < 7.2
? "Sorry mouse driver version too old"
ENDIF
? nMajor, nMinor
lNewSetting is optional and if supplied is the new setting for the CapLock key. Specify .T. to turn CapLock on, or .F. to turn it off.
Returns
lValue is .T. if NumLock is set, .F. if it isn't set. The value returned represents the setting in effect prior to any changes that might by made by lNewSetting.
Description
This function is useful if you need to know or set the status of the NumLock key for some reason.
Examples
#include "inkey.ch"
IF ft_NumLock()
? "NumLock is active"
ENDIF
// Another one, slightly strange, courtesy of Glenn Scott:
numBlink()
STATIC FUNCTION numBlink()
LOCAL lOldNum := ft_NumLock()
DO WHILE Inkey( 0.5 ) != K_ESC
ft_NumLock( ! ft_NumLock() )
ENDDO
RETURN ft_NumLock( lOldNum )
lSetStat set to .T. will enable the Print Screen key, .F. will disable it. If omitted, leaves status as is.
Returns
The current state: .T. if enabled, .F. if disabled.
Description
This function is valuable if you have a need to disable the PrintScreen key. It works by fooling the BIOS into thinking that a printscreen is already in progress. The BIOS will then refuse to invoke the printscreen handler.
Examples
ft_PrtScr( .F. ) // Disable the printscreen key
ft_PrtScr( .T. ) // Enable the printscreen key
? ft_PrtScr() // Get the current status
nKeyValue is the Inkey() value of the keystroke to be stuffed.
Returns
.T. if the keystroke was put into the keyboard buffer. .F. if nKeyValue was invalid or the buffer was full.
Description
This function is similar to the KEYBOARD command, with a few exceptions. First, this function does not clear the keyboard buffer before inserting the keystroke. In addition, since it uses the Inkey() value, you can stuff any key, including function keys, into the keyboard buffer. However, this also means that unlike the KEYBOARD command, you can only stuff one keystroke at a time.
You can easily create a User-Defined Command that makes this function even more like the KEYBOARD command. For example,
#xcommand KEYSTROKE <key> => ft_PutKey( <key> )
will create a command called KEYSTROKE that could be used as a companion command to KEYBOARD. The only difference is that it would insert a single keystroke instead of a string.
Be aware that this function makes use of Clipper's internal event handler. If you don't like using internals, then don't use this function, you sniveling coward.
Examples
ft_PutKey( -9 ) // Stuff the <F10> key
ft_PutKey( 276 ) // Stuff the <Alt+T> key
KEYBOARD 28 // Stuff the <F1> key using a User-Defined Command
A two-character string, corresponding to the keyboard scan code.
Description
ft_ScanCode() enables you to distinguish the different scan-codes of similar keys (such as Grey minus versus regular minus), thus increasing the number of keys your input routine can recognize.
It works like Inkey(), in that it waits for a key to be pressed. The scan code consists of two bytes, which are returned as a two-character string.
For example, calling ft_ScanCode() and pressing the Grey-minus key will return a two character string:
hb_BChar( 45 ) + hb_BChar( 74 )
LastKey() is not updated by ft_ScanCode(), so don't try to test LastKey() to see what was pressed during an ft_ScanCode() call. Simply assign the return value to a variable and test that (see the test driver below).
* This was adapted from a short C routine posted by John Kaster on
NANFORUM. It was written in Clipper to help demonstrate the ft_int86() function of the Nanforum Toolkit.
This routine is used to adjust the IBM PC/AT and PS/2 "typematic" repeat and delay feature. This is used to allow the users of your application to adjust these speeds to the most comfortable level.
Examples
ft_SetRate( 0, 0 ) // Set keyboard to fastest possible settings
ft_SetRate() // Set keyboard to AT defaults (10.9cps, 500ms delay)
ft_SetRate( 11, 1 ) // Set keyboard to PS/2 defaults (10cps, 500ms delay)
Replacement for Inkey() that tests for SET KEY procedures
Syntax
ft_SInkey( [ <nWaitTime> ] ) β nKey
Arguments
nWaitTime is the number of seconds to wait. If zero, ft_SInkey() will wait indefinitely for a key-press. If not passed, ft_SInkey() does not wait for a key-press. If NIL, it is treated the same as 0.
ft_SInkey() is similar to the function provided by Nantucket in keyboard.prg, with one significant difference: you can pass NIL to Inkey(), which will be treated as a zero (i.e., wait indefinitely for key-press). Therefore, it is necessary to differentiate between an explicit NIL and one that is a result of a formal parameter not being received.
ft_SInkey() differs from the standard Inkey() in that it will respond to any keys set with SET KEY TO or SetKey().
Examples
#include "inkey.ch"
SetKey( K_F1, {| n, l, r | HELP( n, l, r ) } )
? ft_SInkey( 0 ) // HELP() will be called if <F1> pressed
STATIC PROCEDURE HELP( n, l, r )
? n, l, r
RETURN
The greatest common divisor of the 2 numbers, or 0 if either is 0.
Description
This function calculates the greatest common divisor between 2 numbers, i.e., the largest number that will divide into both numbers evenly. It will return zero (0) if either number is zero.
nInitialInvestment is the amount of cash invested for purposes of generating the cash flows.
nInterestRate is the annual interest rate used to discount expected cash flows (10.5% = 10.5, not .105).
aCashFlow is an array of the expected cash receipts each year.
nNoOfCashFlows is the number of years cash flows are expected (optional, Len( aCashFlow ) ).
Returns
The difference between the initial investment and the discounted cash flow in dollars.
Description
This function calculates the net present value, the difference between the cost of an initial investment and the present value of the expected cash flow(s) from the investment. The present value of the expected cashflow(s) is calculated at the specified interest rate, which is often referred to as the "cost of capital".
This function can be used to evaluate alternative investments. The larger the NPV, the more profitable the investment. See also the FutureValue and PresentValue for further explanations. The formula to calculate the net present value is:
NetPresentValue := SUM( CashFlow[ i ] / ( ( 1 + InterestRate ) ^ i ) )
FOR i := 1 TO NoOfCashFlows
//
NEXT
NIL .... but optionally places Total of calculation in active
Get variable using oGet:varPut()
Description
ft_Adder() gives you an adding machine inside your Clipper 5.2 application. It has the basic functions add, subtract, multiply, and divide. You may move it from one side of the screen to the other. It even displays a scrollable tape, if you want it.
There are a few HOT Keys while using the Adder:
Decimals - change # of decimals Move - the Adder from right display to left Tape - turn the Tape Display On or Off Scroll - the tape display DEL
β 1st Clear entry
+β 2nd Clear adder
ESC - Quit F10 - return a total to the active get
A couple of notes about the adder:
1. It was designed to be used on an Enhanced keyboard with
separate DEL key. DEL is used to clear the adder. However, it will still work on a Standard keyboard.
2. You do not have to display the tape. You may turn it on
at any time by pressing T. You may scroll back through the tape once there are more than 16 entries in the adder, by pressing S.
3. To Quit the Adder just press ESC. To return your Total
to the application press F10. The adder will place the Total in the active GET variable using oGet:varPut(). The adder will only return a Total to a numerical GET!
4. There are many support functions that you might find
interesting. They are part of my personal library, but are necessary to the operation of the adder. You might want to pull these out to reduce the overall size of the adder. Many are worth at least a little time studying.
5. To make ft_Adder() a Hot key from inside your application
at the beginning of your application add the line:
SetKey( K_ALT_A, {|| ft_Adder() } )
This will make ALT+A a key "Hot" and permit you to Pop - Up the adder from anywhere in the application.
6. If you use ft_SInkey(), you can even have active hotkeys
bWhileCond is the limiting WHILE condition as a block.
Example 1: {|| Names->Last == "JONES" } Example 2: {|| Names->Last == "JONES" .AND. Names->First == "A" }
cKey is the key to find top condition of WHILE.
cLast := "JONES "
cFirst := "A"
Example 1: cKey := cLast Example 2: cKey := cLast + cFirst
nFreeze is number of fields to freeze in TBrowse(). Defaults to 0 if not passed.
lSaveScrn is a logical indicating whether or not you want to save the screen from the calling program. Defaults to .T. if not passed.
cColorList is a list of colors for the TBrowse() columns. The 1st color is used as SAY/TBrowse() Background and the 3rd and 4th colors are used as part of column:defColor := { 3, 4 }
Thus if you pass a cColorList, you must pass at least 4 colors. Defaults to N/W, N/BG, B/W, B/BG, B/W, B/BG, R/W, B/R if not passed.
cColorShad is the color of the TBrowse box shadow. Defaults to "N/N" if not passed.
nTop, nLeft, nBottom, nRight are the coordinates of the area to display the TBrowse() in. Defaults to 2, 2, MaxRow() - 2, MaxCol() - 2 with shadowed box, i.e. full screen.
Returns
nRecno is the number of the record selected by the Enter key. 0 is returned if there are either no records matching the WHILE condition or an Esc is pressed instead of an Enter
Description
This is a demonstration of TBrowse() with a WHILE condition for an indexed database.
Examples
// This example will only show those people with last name of "JONES"
// in the test.dbf which contains at least the fields:
// Last, First, City AND is indexed on Last + First.
LOCAL nRecSel := 0
LOCAL aFields := {}
LOCAL bWhile := {|| field->last = "JONES" }
LOCAL cKey := "JONES"
LOCAL nFreeze := 1
LOCAL lSaveScrn := .T.
LOCAL cColorList := "N/W, N/BG, B/W, B/BG, B/W, B/BG, R/W, B/R"
LOCAL cColorShad := "N/N"
USE test NEW // indexed on Last + First
INDEX ON field->last + field->first TO test
// Pass Heading as character and Field as Block including Alias
// To eliminate the need to use FieldWBlock() function in ft_BrwsWhl()
AAdd( aFields, { "Last Name" , {|| field->last } } )
AAdd( aFields, { "First Name", {|| field->first } } )
AAdd( aFields, { "City" , {|| field->city } } )
IF ft_BrwsWhl( aFields, bWhile, cKey, nFreeze, lSaveScrn, ;
cColorList, cColorShad, 3, 6, MaxRow() - 2, MaxCol() - 6 ) == 0
? "Sorry, No records were selected"
ELSE
? "You Selected:", field->last, field->first, field->city
ENDIF
T = Title Only 1 color element D = Desktop Background color and character M = Menu For ft_MenuTo() style menus W = Window Windows with radio buttons G = Get For use with @ SAY... B = Browse For TBrowse() and *dbEdit() A = AChoice Pick-lists etc...
W/G/B/A are functionally the same but will provide a more appropriate test display.
[ 4 ] cFillChar is the character (for desktop background only)
Default is "ββββββββββββββ"
cTestChr 2 Byte character string for color test display
Default is "β β "
Returns
An array identical to the one passed, with new selected colors
Description
This function allows users to select their own color combinations for all the different types of screen I/O in a typical application. This facilitates an easy implementation of Ted Means' replacement of the @..PROMPT/MENU TO found in the NanForum Toolkit. If you are not using ft_MenuTo(), you can specify "A" for setting type and have a normal color string returned.
Examples
LOCAL aClrs
LOCAL lColor := IsColor()
Set( _SET_SCOREBOARD, .F. )
SetBlink( .F. ) // Allow bright backgrounds
// .... a typical application might have the following different settings
// normally these would be stored in a .dbf/.dbv
aClrs := { ;
{ "Desktop", "N/BG", "D", "β" }, ;
{ "Title", "N/W", "T" }, ;
{ "Top Menu", "N/BG,N/W,W+/BG,W+/N,GR+/N", "M" }, ;
{ "Sub Menu", "W+/N*,GR+/N*,GR+/N*,W+/R,G+/R", "M" }, ;
{ "Standard Gets", "W/B, W+/N,,, W/N", "G" }, ;
{ "Nested Gets", "N/BG, W+/N,,, W/N", "G" }, ;
{ "Help", "N/G, W+/N,,, W/N", "W" }, ;
{ "Error Messages", "W+/R*,N/GR*,,,N/R*", "W" }, ;
{ "Database Query", "N/BG, N/GR*,,,N+/BG", "B" }, ;
{ "Pick List", "N/GR*,W+/B,,, BG/GR*", "A" } }
aClrs := ft_ClrSel( aClrs, lColor )
? hb_ValToExp( aClrs )
aMessageArray is a multidimensional array of messages to be displayed and the color attributes for each message.
The first dimension of the array contains one or more elements, each representing one line in the message box, up to the maximum number of rows on the screen.
Within each line of the message individual characters or groups of characters may be delimited with braces []. The braces will be stripped out and the character(s) inside those braces will be highlighted.
The second dimension of the array contains a color attribute for the corresponding element in dimension one, plus one additional element for the color of the box border. Dimension two will always contain one more element than dimension one. If an attribute is omitted, the last color selected will be used.
cKey2Check is a character string of one or more keys to check for. If omitted, the message is displayed and control is returned to the calling procedure. If one character is specified, ft_DispMsg() waits for one key-press, restores the screen and returns. If multiple characters are specified, ft_DispMsg() remains in a loop until one of the specified keys has been pressed, then restores the screen and returns.
nTopBoxRow is the upper row for the message box. If omitted, the box is centered vertically.
nLeftBoxColumn is the leftmost column for the box. If omitted, the box is centered horizontally.
cnBoxType is a string of characters or a variable for the box border. See the DispBox() function. If omitted, a double box is drawn.
lShadow is a logical variable. If true (.T.) or omitted, it uses ft_Shadow() to add a transparent shadow to the box. If false (.F.), the box is drawn without the shadow.
Returns
If cKey2Check is not specified, ft_DispMsg() will return false (.F.).
If cKey2Check is a one-character string, ft_DispMsg() will return true (.T.) if the user presses that key, or false (.F.) if any other key is pressed.
If cKey2Check consists of multiple characters, it will lock the user in a loop until one of those keys are pressed and return the Inkey() value of the key-press.
Description
ft_DispMsg() is a multi-purpose pop-up for user messages. Multiple lines may be displayed, each with a different attribute. The box will be automatically centered on the screen, or the row and/or column can be specified by the programmer. It also centers each line of the message within the box.
Examples
// The following example displays a simple two-line message
// and returns immediately to the calling routine.
ft_DispMsg( { { "Printing Report", ;
"Press <Esc> To Interrupt" }, ;
{ "W+/B*", "W/B", "GR+/B" } } )
// The next example displays a message and waits for a key press.
ft_DispMsg( { { "Press <D> To Confirm Deletion", ;
"Or Any Other Key To Abort" }, ;
{ "W+/B", "W+/B", "GR+/B" } }, ;
"D" )
// The next example displays a one-line message centered on row 5
// and returns to the calling procedure.
ft_DispMsg( { { "Please Do Not Interrupt" }, ;
{ "W+/B", "GR+/B" } }, ;
, 5, )
aSubArrayName is a sub-array of acOptions in ft_Menu1() denoting the group in which to include the selection β e.g., acOptions[ 1 ]
cMenuSelection is the character string that will appear on the menu.
bFunction is the code block to be executed when that menu option is selected. i.e. {|| MyFunction() } would execute the function called MyFunction(). {|| .F. } would exit the ft_Menu1() and return to the calling routine. {|| .T. } would do nothing.
lSelectable is a logical variable that determines whether the corresponding menu option is selectable or not.
Returns
NIL
Description
ft_Fill() is a function used to set up the menu options prior to calling ft_Menu1().
Examples
LOCAL aOptions := Array( 4 )
ft_Fill( aOptions[ 1 ], "A. Execute A Dummy Procedure" , {|| Alert( "hello" ) }, .T. )
// The above would be added to the sub-menu associated with the
// first menu bar item, would execute the function FUBAR() when
// that option was selected, and would be selectable.
ft_Fill( aOptions[ 3 ], "B. Enter Daily Charges" , {|| .T. }, .F. )
// The above would be added to the sub-menu associated with the
// third menu bar item, and would be unselectable.
ft_Fill( aOptions[ 2 ], "C. Enter Payments On Accounts", {|| .T. }, .T. )
// The above would be added to the sub-menu associated with the
// second menu bar item, and would be selectable, but would do
// nothing when selected.
ft_Fill( aOptions[ 4 ], "C. Exit" , {|| .F. }, .T. )
// The above would be added to the sub-menu associated with the
// fourth menu bar item, and would be selectable, and would exit
// ft_Menu1() when chosen.
acBarNames is a character array containing the names to appear on the menu bar.
acOptions is a multi-dimensional array with one element for each selection to appear on the pulldown menus.
acColors is an array containing the colors for the menu groups.
nTopRow is a numeric value that determines the row for the menu bar. If omitted, it defaults to 0.
lShadow is a logical variable. If true (.T.) or omitted, it uses ft_Shadow() to add a transparent shadow to the each pulldown menu. If false (.F.), the menu is drawn without the shadow.
All arguments except nTopRow and lShadow are required.
Returns
NIL
Description
ft_Menu1() is a function that displays a pulldown menu for each item on the menu bar and executes the corresponding function for the item selected. When a called function returns false, ft_Menu1() returns control to the calling program.
// Declare arrays
LOCAL aColors := {}
LOCAL aBar := { " ENTER/EDIT ", " REPORTS ", " DISPLAY " }
// Include the following two lines of code in your program, as is.
// The first creates aOptions with the same length as aBar. The
// second assigns a three-element array to each element of aOptions.
LOCAL aOptions := Array( Len( aBar ) )
AEval( aBar, {| x, i | aOptions[ i ] := { {}, {}, {} } } )
// fill color array
// Box Border, Menu Options, Menu Bar, Current Selection, Unselected
aColors := iif( IsColor(), ;
{ "W+/G", "N/G", "N/G", "N/W", "N+/G" }, ;
{ "W+/N", "W+/N", "W/N", "N/W", "W/N" } )
// array for first pulldown menu
ft_Fill( aOptions[ 1 ], "A. Execute A Dummy Procedure" , {|| Alert( "hello" ) }, .T. )
ft_Fill( aOptions[ 1 ], "B. Enter Daily Charges" , {|| .T. }, .F. )
ft_Fill( aOptions[ 1 ], "C. Enter Payments On Accounts", {|| .T. }, .T. )
// array for second pulldown menu
ft_Fill( aOptions[ 2 ], "A. Print Member List" , {|| .T. }, .T. )
ft_Fill( aOptions[ 2 ], "B. Print Active Auto Charges" , {|| .T. }, .T. )
// array for third pulldown menu
ft_Fill( aOptions[ 3 ], "A. Transaction Totals Display", {|| .T. }, .T. )
ft_Fill( aOptions[ 3 ], "B. Display Invoice Totals" , {|| .T. }, .T. )
ft_Fill( aOptions[ 3 ], "C. Exit To DOS" , {|| .F. }, .T. )
// Call ft_Fill() once for each item on each pulldown menu, passing it
// three parameters:
//
// ft_Fill( <cMenuSelection>, <bCodeBlock>, <lSelectable> )
// <cMenuSelection> is a character string which will be displayed on
// the pulldown menu.
// <bCodeBlock> should contain one of the following:
// A function name to execute, which in turn should return .T. or .F.
// ft_Menu1() WILL RETURN CONTROL TO THE CALLING PROGRAM IF .F. IS
// RETURNED OR CONTINUE IF .T. IS RETURNED.
// .F. WHICH WILL CAUSE ft_Menu1() TO RETURN CONTROL TO THE CALLING
// PROGRAM.
// .T. WHICH WILL DO NOTHING. THIS ALLOWS THE DEVELOPER TO DESIGN A
// SKELETON MENU STRUCTURE PRIOR TO COMPLETING ALL OF THE SUBROUTINES.
ft_Menu1( aBar, aOptions, aColors, 0 )
// NOTE: ft_Menu1() disables <Alt-C> and <Alt-D> in order to make them
// available for the menu bar. It enables <Alt-D> and resets
// <Alt-C> to its previous state prior to calling each function.
cColors is a string containing colors for the prompts, in the same format as that returned by Set( _SET_COLOR ). If not supplied, colors default to the current color setting.
Returns
NIL
Description
This function greatly simplifies the process of displaying light-bar menus. All prompts are padded out with spaces so they are the same length, a box is drawn around the prompts, the box is automatically centered on the screen, and the underlying screen is restored after a menu selection has been made.
Additionally, because you can tie action blocks to each menu option, you can save on a lot of DO CASE or IF..ELSEIF code in your main program. See the test code for a succinct demonstration.
Execute light bar menu using prompts created with @...PROMPT
Syntax
#include "ftmenuto.ch"
MENU TO <var> [COLD]
Arguments
var is the name of the variable to which the result of the menu selection should be assigned.
COLD is optional and if specified indicates that trigger characters should be treated as "cold," i.e. rather than causing the menu item to be selected it only causes the light bar to move to that selection.
Description
This enhanced version of MENU TO requires the inclusion of the header file ftmenuto.ch in any source file that uses it. It may be used in place of the standard Clipper MENU TO command. However, in the interests of functionality it is not 100% compatible (in particular, you should make sure that the target memvar exists before executing the menu β the Clipper version will create a PRIVATE memvar for you if it does not already exist, but this version does not). No whining! If compatibility is such a big deal then use the standard Clipper command.
Note that this command can also be called using function-style syntax. See the entry for ft_MenuTo() for further details.
Examples
// FIXME
#include "ftmenuto.ch"
// Simple command
MENU TO memvar
nRow is an optional screen row for message display, default row 24.
nCol is an optional screen col for message display, default col 0.
nWait is an optional wait (sec) between messages, default 5 sec.
cColor is an optional color string for displayed messages, default
is white text over red background.
Returns
NIL
Description
A good way to display information messages during the running of an application is to send them all to the same line on the screen where users are expected to look for them. In order to give users a chance to read the current message before the next one is displayed we may need to insert a delay after each message.
ft_Pending() function displays messages by keeping track of the time of the last message and providing a delay only if the next pending message is issued much too soon after the current one.
Examples
ft_Pending( "Message one", 20, 0, 3, "W+/G" ) // Displays "Message one."
// sets row to 20, col to 0.
// wait to 3 and color to
// bright white over green.
ft_Pending( "Message two" ) // Displays "Message two", after 5 sec.
ft_Pending( "Message three" ) // Displays "Message three", after 5 sec.
// Note that default row, col, wait time and color need to be set only
// once in the very first call to ft_Pending() and only if the internal
// default values are not appropriate.
nCol is the column at which the prompt will appear.
cPrompt is the menu item string.
cColor is optional and is the color attribute of the prompt. Note that two colors are required; one for the standard setting and one for the enhanced setting (i.e. the light bar color). See the example below if this isn't clear. If cColor is not specified then the current SetColor() value is used by default.
cMessage is optional and is the message associated with the prompt. If not specified, then no message will be displayed.
nMsgRow is optional and is the row at which the message, if any, will appear. If not specified, the default is the current setting of the SET MESSAGE TO command.
nMsgCol is optional and is the column at which the message, if any, will appear. If not specified, the default is either zero or centered, depending on the current setting of the CENTER option of the SET MESSAGE TO command.
cMsgColor is optional and is the color attribute of the message. If not specified, the default is the same as the prompt color.
nTrigger is optional and is the position within the prompt string where the trigger character is located. If not specified, the default is one.
cTriggerColor is optional and is the color attribute of the trigger character. Note that two colors are required; one for the standard setting and one for the enhanced setting (i.e. the light bar color). See the example below if this isn't clear. If cTriggerColor is not specified then the default is the same color as the rest of the prompt.
nHome is optional and specifies which prompt becomes active when the home key is pressed. If not specified, the default is the first prompt.
nEnd is optional and specifies which prompt becomes active when the end key is pressed. If not specified, the default is the last prompt.
nUp is optional and specifies which prompt becomes active when the up arrow key is pressed. If not specified, the default is the previous prompt. The current setting of SET WRAP TO is obeyed.
nDown is optional and specifies which prompt becomes active when the down arrow key is pressed. If not specified, the default is the next prompt. The current setting of SET WRAP TO is obeyed.
nRight is optional and specifies which prompt becomes active when the right arrow key is pressed. If not specified, the default is the next prompt. The current setting of SET WRAP TO is obeyed.
nLeft is optional and specifies which prompt becomes active when the left arrow is pressed. If not specified, the default is the previous prompt. The current setting of SET WRAP TO is obeyed.
bExec is optional and is a code block to evaluate whenever the menu item to which it belongs is selected.
Description
Clipper's @...PROMPT and MENU TO commands are fine as far as they go. But many times you need more flexibility. As you'll no doubt notice if you read the argument list, this function is almost completely flexible. You can adjust locations and colors for every part of the prompt and its associated message. In addition, since you can control the effect of the arrow keys, you can allow both horizontal and vertical movement, or even disable certain arrow keys if you so desire. Support for nested menus is also available, since the prompts are stored in stack-based static arrays.
Note that this command can also be called using function-style syntax. See the entry for ft_Prompt() for further details.
This enhanced version of @...PROMPT requires the inclusion of the header file ftmenuto.ch in any source file that uses it. It is may be used in place of the standard Clipper @...PROMPT command. However, in the interests of functionality it is not 100% compatible. No whining! If compatibility is such a big deal then use the standard Clipper commands.
Examples
#include "ftmenuto.ch"
// Simple prompt
@ 1, 1 PROMPT "Menu choice #1"
// Prompt with color
@ 3, 1 PROMPT "Menu choice #2" COLOR "W+/R,W+/B"
// Prompt with a message
@ 5, 1 PROMPT "Menu choice #3" MESSAGE "Go to lunch"
// Prompt with pinpoint message control
@ 7, 1 PROMPT "Menu choice #4" MESSAGE "Drop Dead" ;
MSGROW 22 MSGCOL 4 MSGCOLOR "GR+/N"
// Prompt with a trigger character ("#" character)
@ 11, 1 PROMPT "Menu choice #6" TRIGGER 13
// Prompt with trigger character color control
@ 13, 1 PROMPT "Menu Choice #7" TRIGGER 13 TRIGGERCOLOR "R+/BG,G+/N"
// Prompt with right and left arrow keys disabled
@ 15, 1 PROMPT "Menu Choice #8" RIGHT 8 LEFT 8
nInitial is an optional clock value (from a call to Seconds())
from which the nSeconds seconds are to elapse. Useful for setting a minimum time between the start of events which could take a variable amount of time due to the execution of intervening code.
Returns
NIL
Description
This routine will wait a specified period of time. It provides resolution based upon the execution of the Seconds() function. It does not use an input state such as Inkey(). The specified time is the minimum time sleeping and will usually be slightly longer.
The second optional argument allows one to begin timing an event prior to executing some operation. This is useful when, for example, you input a key or mouse click and wish to do something but still want to note if the user double entered (mouse or key) within a certain time which in turn may have meaning within your program's context.
The routine correctly handles passing through midnight but will not work for more than 24 hours.
Examples
LOCAL nTime
// Example 1:
ft_Sleep( 10.0 ) // Sleep for 10.0 seconds
// Example 2:
nTime := Seconds() // usually after some interrupt from mouse or
// keyboard
// ... intervening code ...
// ft_Sleep( 0.5, nTime ) // Sleep until the system clock is
// nTime + 0.5 seconds.
cJustType is a character indicating the type of text justification. L cause the text to be left-justified in the box. Centered text is the default.
cRetWait is a character which determines if the function will wait for a key-press after displaying the box. W will cause the function to wait for a key-press before returning control to the calling routine. Not waiting is the default
cBorType is a character which determines whether a single or double border will be displayed. D will cause a double border to be displayed. A single border is the default.
cBorColor is a character string denoting the border color. N/W is the default if this parameter is not a string.
cBoxColor is a character string denoting the text color. W/N is the default if this parameter is not a string.
nStartRow is a number denoting the starting row. If 99 is passed, the box is centered vertically. If necessary, nStartRow is decreased so the entire box can be displayed.
nStartCol is a number denoting the starting column. If 99 is passed, the box is centered horizontally. If necessary, nStartCol is decreased so the entire box can be displayed.
cLine1 thru cLine8 are 1 to 8 character strings to be displayed. They are truncated to fit on the screen if necessary.
Returns
NIL
Description
ft_XBox() allows the programmer to display a message box on the screen without needing to calculate the dimensions of the box. Only the upper left corner needs to be defined. The function will calculate the lower right corner based on the number and length of strings passed.
A maximum of eight strings can be displayed. If a string is too long to fit on the screen it is truncated.
The first seven parameters are optional. The default settings are:
Lines of text are centered. Control is returned to the calling routine immediately. A single line border is painted. The border is black on white. The text is white on black. The box is centered both vertically and horizontally.
Examples
// The following displays a two-line box with default settings:
ft_XBox( ,,,,,,, "This is a test", "of the ft_XBox() function" )
// The following uses all optional parameters and displays a three-line
// box. The box is left-justified with a double border. It has a yellow
// on red border and white on blue text. The function will wait for a
// key-press before returning control to the calling routine.
ft_XBox( "L", "W", "D", "GR+/R", "W/B", 5, 10, ;
"It is so nice", ;
"to not have to do the messy chore", ;
"of calculating the box size!" )
Return the current Novell NetWare logical station number
Syntax
ft_NWLStat() β nStatNum
Arguments
None
Returns
A numeric corresponding to the current logical station number assigned by NetWare.
Description
In order to find out information about a particular node logged in to a NetWare server, you will need the logical station number, also known as a "connection number." This function will return that number. This will be a number from 1 to 100 under NetWare 286, or from 1 to 250 under NetWare 386. This is not the same as a physical station number.
nHandle is the semaphore handle, returned from a previous call to ft_NWSemOpen().
Returns
nRc, a numeric, as follows:
Β Β Β 0Β -Β success
Β 255Β -Β invalidΒ semaphoreΒ handle
Description
Call ft_NWSemClose() when the app is finished. This decrements the open count for the semaphore. If the open count hits zero, the semaphore is deleted by NetWare.
Examples
LOCAL nHandle := 0
? "Close returns:", ft_NWSemClose( nHandle )
LOCAL nInitVal := 2
LOCAL nHandle := 0
LOCAL nOpenCnt := 0
LOCAL nValue := 0
ft_NWSemOpen( "Semaphore Test", nInitVal, @nHandle, @nOpenCnt )
IF ft_NWSemWait( nHandle ) == 254
? "All slots for this resource are currently in use"
RETURN
ENDIF
ft_NWSemEx( nHandle, @nValue, @nOpenCnt )
? "Semaphore test -> Open at [" + ;
hb_ntos( nOpenCnt ) + ;
"] stations, value is [" + ;
hb_ntos( nValue ) + "]"
cSemaphore is the name of a semaphore you want to "lock." nHandle is the semaphore's handle, if you get the lock. This must be passed by reference!
Returns
lRet == .T. if you get the lock, .T. if you don't. If the lock succeeds, nHandle will contain the semaphore handle. If it fails, the value of nHandle is undefined.
Description
ft_NWSemLock() uses the Nanforum Toolkit's NetWare Semaphore API functions in order to provide a general purpose "lock" you can use in a NetWare environment.
An interesting byproduct of NetWare's semaphore functions is the "open count" which tells you how many connections have this semaphore open. This is different from the semaphore's value, which is set when the semaphore is opened and changed with Signal() and wait().
The point of semaphores is that you don't care how many users are using the resource; you merely wait on a semaphore until the resource becomes available or you give up. When you're done, you signal it and off you go.
Back to the open count. ft_NWSemLock() opens the semaphore as named in cSemaphore. After it is opened, the open count is checked. If it is anything other than 1, that means someone else has it (or you failed in your open) so the semaphore is closed and the "lock" is refused. If the value is 1, then your app is that 1 station so the "lock" is granted.
You can use a semaphore lock to control access to anything that Clipper's RLock() and FLock() cannot help you with, such as text files written with the low-level file I/O functions, etc.
Examples
LOCAL nHandle := 0
IF ft_NWSemLock( "error.log", @nHandle )
// Note, you aren't actually LOCKING this file, you are
// just locking a semaphore by the same name. As long as
// all apps that might be using this file are cooperating
// with the same kind of semaphore lock, you can effectively
// control access to the file.
ELSE
? "Couldn't lock file."
ENDIF
// Processing, then:
ft_NWSemUnlock( nHandle )
cName is the semaphore name, maximum length is 127 characters.
nInitVal is the initial value for the semaphore. It must start as a positive number, to a maximum of 127.
@nHandle is the semaphore handle. This must be passed by reference! On exit, nHandle will contain a numeric value that refers to the opened semaphore. You will need it to pass to other semaphore functions! Pass it by reference!
@nOpenCnt is the number of stations that have opened the semaphore. This must be passed by reference! On exit, nOpenCnt will contain a numeric value.
Returns
nRc, a numeric result code, as follows:
Β Β Β 0Β -Β success
Β 254Β -Β InvalidΒ semaphoreΒ nameΒ length
Β 255Β -Β InvalidΒ semaphoreΒ value
nHandle will contain the semaphore handle, and nOpenCnt will contain the number of stations that have opened the semaphore.
Description
A semaphore is simply a label that indirectly controls network activity. There is a semaphore name, which can be up to 127 characters, and an associated value, which can range from 0 to 127.
A semaphore can be used for many things, but is most often used to limit the number of users in an application, and to control access to a network resource.
A semaphore essentially allows you to place locks on resources other than files.
An application begins the process by calling ft_NWSemOpen(). If the semaphore doesn't exist, NetWare will create it. ft_NWSemOpen() returns a handle that is used in other semaphore calls.
Applications use ft_NWSemWait() to wait for a semaphore to become available. ft_NWSemWait() decrements the semaphore's value by 1. If the value > 0, then the application should be allowed to access the semaphore's resource. If the value goes negative, then the application is placed in a queue. How long your app is in the queue is determined by how you set the timeout parameter. If you cannot get the resource in the time you allot, you're let out of the queue and the value increments by 1 again.
When an application finishes with a semaphore, it should call ft_NWSemSig() to increment the value, and then ft_NWSemClose() to close the semaphore. When the semaphore's open count goes to 0, NetWare deletes it.
ft_NWSemEx() can be used to examine the value and open count without affecting them.
For an interesting discussion on the operating system aspects of semaphores, check "Operating Systems Design and Implementation" by A. Tanenbaum, page 60. For more details on NetWare's semaphore facilities, refer to Charles Rose's "Programmer's Guide to NetWare". The "Programmer's Guide" will make an excellent companion guide to the source code for all NetWare functions in the Nanforum Toolkit.
Examples
LOCAL nHandle, nOpenCnt
LOCAL nInitVal := 2
LOCAL nRc := ft_NWSemOpen( "Semaphore Test", nInitVal, ;
@nHandle, @nOpenCnt )
IF nRc != 0
? "Error:", nRc
ENDIF
Use ft_NWSemSig() when your app has finished with the resource locked by a semaphore. This will increase the value (thus making a slot available to another app).
For more information, see the description under ft_NWSemOpen().
Examples
LOCAL nHandle := 0
? "Signal returns:", ft_NWSemSig( nHandle )
nHandle is the semaphore handle returned from ft_NWSemLock()
Returns
lRet == .T. if you successfully unlock the semaphore, .F. if you don't. If this call fails, it could be that you're passing an invalid semaphore handle.
Description
This call unlocks a semaphore previously locked via ft_NWSemLock(). It is important that you get a valid semaphore handle from ft_NWSemLock() before you use this call. Make sure when you call ft_NWSemLock() that you pass a numeric parameter in for the handle by reference.
Examples
LOCAL nHandle := 0
IF ft_NWSemLock( "error.log", @nHandle )
// Note, you aren't actually LOCKING this file, you are
// just locking a semaphore by the same name. As long as
// all apps that might be using this file are cooperating
// with the same kind of semaphore lock, you can effectively
// control access to the file.
ELSE
? "Couldn't lock file."
ENDIF
// Processing, then:
ft_NWSemUnlock( nHandle )
nHandle is the semaphore handle, returned from a previous call to ft_NWSemOpen().
nTimeOut is an optional parameter telling how long you wish to wait on this semaphore. This is a numeric indicating the number of clock ticks (approx 1/18 sec) to wait. A zero (the default) means "don't wait."
LOCAL nHandle, nOpenCnt
LOCAL nInitVal := 2
ft_NWSemOpen( "Semaphore Test", nInitVal, @nHandle, @nOpenCnt )
IF ft_NWSemWait( nHandle ) == 254
? "All slots for this resource are currently in use"
ENDIF
nConnection is a connection number, or logical station number, to find a user id for. Under NetWare 286, this number can be from 1 to 100. Under NetWare 386, 1-250. If not supplied, ft_NWUID() defaults to the current connection (i.e., the connection running the application).
Returns
A string containing the user id, or "login name." The maximum length of this string, as defined by current versions of Novell NetWare, is 48 characters.
Description
ft_NWUID() returns the current NetWare user id, or "login name." This is useful for implementing security or audit trail procedures within your programs.
There is no simple way a user can "fool" this function into retrieving an incorrect value, provided a NetWare shell is loaded.
This function does not test for the existence of the NetWare shell. The behavior is undefined if no shell is loaded. You'll usually get garbage. This function has not been tested on NetWare 386.
Examples
LOCAL cUid, x
? "I am:", ft_NWUID()
FOR x := 1 TO 100
cUid := ft_NWUID( x )
IF ! cUid == ""
? Str( x, 3 ), cUid
ENDIF
NEXT
lCaseSens is a logical value denoting case sensitivity.
If .F., then search is not sensitive to case, defaults to .T.
Returns
The position of the nth occurrence of a substring
Description
This function will find the nth occurrence of a substring within a string.
Examples
LOCAL cSearch := "t"
LOCAL cTarget := "This is the day that the Lord has made."
? ft_At2( cSearch, cTarget ) // --> 9
? ft_At2( cSearch, cTarget, 2 ) // --> 17
? ft_At2( cSearch, cTarget, 2, .F. ) // --> 9
cByte is a character from hb_BChar( 0 ) to hb_BChar( 255 ).
nBitPos is a number from 0 to 7 conforming to standard right-to-left bit numbering convention and representing the position of the bit within the byte.
Returns
Returns new byte, with designated bit cleared (reset). If parameters are faulty, returns NIL.
Description
In effect, ANDs argument byte with a byte that has all bits set except the target bit. If bit is already clear (0), it remains clear. Note: Calls ft_IsBit() which is also in this Library.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code would clear bit 4 in a byte represented by hb_BChar( 115 ):
LOCAL cNewByte := ft_BitClr( hb_BChar( 115 ), 4 )
? hb_BCode( cNewbyte ) // --> 99
? cNewByte // --> "c"
// This code would clear bit 5 in the byte represented by letter "A":
? ft_BitClr( "A", 5 ) // --> "A", since bit 5 already clear
cByte is a character from hb_BChar( 0 ) to hb_BChar( 255 ).
nBitPos is a number from 0 to 7 conforming to standard right-to-left bit numbering convention and representing the position of the bit within the byte.
Returns
Returns new byte, with designated bit set. If parameters are faulty, returns NIL.
Description
In effect, ORs argument byte with a byte that has only the target bit set. If bit is already set, it remains set. Note: Calls ft_IsBit() which is also in this Library.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code would set bit 4 in a byte represented by hb_BChar( 107 ):
LOCAL cNewbyte := ft_BitSet( hb_BChar( 107 ), 4 )
? hb_BCode( cNewbyte ) // --> 123
? cNewbyte // --> "{"
// This code would set bit 5 in the byte represented by the letter "A".
? ft_BitSet( "A", 5 ) // --> "a", bit 5 set
Perform bit-wise AND on two ASCII characters (bytes)
Syntax
ft_ByteAnd( <cByte1>, <cByte2> ) β cByte
Arguments
cByte1 and cByte2 are characters from hb_BChar( 0 ) to hb_BChar( 255 ). May be passed in hb_BChar() form, as character literals, or as expressions evaluating to character values.
Returns
Returns resulting byte, as a string. If parameters are faulty, returns NIL.
Description
Can be used for any bit-wise masking operation. In effect, this is a bit-by-bit AND operation. Equivalent to AND assembler instruction.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code would mask out the high nibble (four most significant bits)
// of the byte represented by hb_BChar( 123 ) and leave the low nibble
// bits as in the parameter byte.
LOCAL cNewbyte := ft_ByteAnd( hb_BChar( 123 ), hb_BChar( 15 ) )
? hb_BCode( cNewByte ) // --> 11
? cNewByte // --> non-printable character
cByte is a character from hb_BChar( 0 ) to hb_BChar( 255 ). May be passed in hb_BChar() form, as character literals, or as expressions evaluating to character values.
Returns
Returns resulting byte, as a string. If parameters are faulty, returns NIL.
Description
Can be used for bit-wise byte manipulation. In effect, this is a bit-by-bit NEG (two's complement) operation. Equivalent to NEG assembler instruction.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code performs a bit-wise NEG on byte represented by hb_BChar( 32 ):
LOCAL cNewByte := ft_ByteNot( hb_BChar( 32 ) )
? hb_BCode( cNewByte ) // --> 224
cByte is a character from hb_BChar( 0 ) to hb_BChar( 255 ). May be passed in hb_BChar() form, as character literals, or as expressions evaluating to character values.
Returns
Returns resulting byte, as a string. If parameters are faulty, returns NIL.
Description
Can be used for bitwise byte manipulation. In effect, this is a bit-by-bit not (one's complement) operation. Equivalent to the NOT assembler instruction.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code performs a bitwise NOT on byte represented by hb_BChar( 32 ):
LOCAL cNewByte := ft_ByteNot( hb_BChar( 32 ) )
? hb_BCode( cNewByte ) // --> 223
Perform bit-wise OR on two ASCII characters (bytes)
Syntax
ft_ByteOr( <cByte1>, <cByte2> ) β cNewByte
Arguments
cByte1 and cByte2 are characters from hb_BChar( 0 ) to hb_BChar( 255 ). May be passed in hb_BChar() form, as character literals, or as expressions evaluating to character values.
Returns
Returns resulting byte, as a string. If parameters are faulty, returns NIL.
Description
Can be used for bit-wise byte manipulation. In effect, this is a bit-by-bit OR operation. Equivalent to OR assembler instruction.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code performs a bit-wise OR on two bytes represented
// by hb_BChar( 20 ) and hb_BChar( 10 ):
LOCAL cNewByte := ft_ByteOr( hb_BChar( 20 ), hb_BChar( 10 ) )
? hb_BCode( cNewByte ) // --> 30
? cNewByte // --> non-printable character
Perform bit-wise XOR on two ASCII characters (bytes)
Syntax
ft_ByteXor( <cByte1>, <cByte2> ) β cNewByte
Arguments
cByte1 and cByte2 are characters from hb_BChar( 0 ) to hb_BChar( 255 ). May be passed in hb_BChar() form, as character literals, or as expressions evaluating to character values.
Returns
Returns resulting byte, as a string. If parameters are faulty, returns NIL.
Description
Can be used for bit-wise byte manipulation. In effect, this is a bit-by-bit XOR operation. Equivalent to XOR assembler instruction.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code performs a bit-wise XOR on two bytes represented
// by hb_BChar( 32 ) and hb_BChar( 55 ):
LOCAL cNewByte := ft_ByteXor( hb_BChar( 32 ), hb_BChar( 55 ) )
? hb_BCode( cNewByte ) // --> 23
? cNewByte // --> non-printable character
Returns the numeric complement of a Clipper color string
Syntax
ft_Color2N( <cColor> ) β nValue
Arguments
cColor is a Clipper color string
Returns
The numeric complement of a color string or 0 if passed color is invalid.
Description
This function is useful when calling other functions that expect a numeric color parameter. It is often more convenient to pass a converted color string than having to calculate or look up the corresponding number.
nWhichOccurrence is the number of the occurrence to find.
lIgnoreCase is a logical indicating if the search is to be case
sensitive. The default is no case sensitivity (.T.).
Returns
The position in the string cCheckIn of the "ith" occurrence of cCheckFor.
Description
This function finds the position in a string of the "ith" time another string appears in it.
Examples
// Find the position in cMemoString of the 10th occurrence
// of "the", case insensitive
LOCAL cMemoString := hb_MemoRead( "test.txt" )
? ft_FindITh( "the", cMemoString, 10 )
cByte is a character from hb_BChar( 0 ) to hb_BChar( 255 ).
nBitPos is a number from 0 to 7 conforming to standard right-to-left
bit-numbering convention and representing the position of the bit within the byte.
Returns
.T. if designated bit is set (1), .F. if not set (0), NIL if
invalid parameters.
Description
Tests for status of any selected bit in the byte passed as a parameter. Byte must be presented in hb_BChar() form, as a literal constant, or as the one-byte character result of an expression.
This function is presented to illustrate that bit-wise operations are possible with Clipper code. For greater speed, write .c version and use the Clipper Extend system.
Examples
// This code tests whether bit 3 is set in the byte represented by
// hb_BChar( 107 ):
LOCAL lBitflag := ft_IsBit( hb_BChar( 107 ), 3 )
? lBitflag // --> .T.
// This code tests whether bit 5 is set in the byte represented by ASCII
// 65 (letter "A")
? ft_IsBit( "A", 5 ) // --> .F.
Determine the state of individual bits in a number
Syntax
ft_IsBitOn( <nNumber>, <nBit> ) β lResult
Arguments
nNumber is an integer for which a bit state needs to be checked.
nBit is a number from 0 to 15 that indicates which bit to test.
Returns
.T. if the specified bit was on., .F. if off.
Description
This function is useful when dealing with binary integers. It will come in very handy if you use the ft_int86() function, because the CPU flags are returned as a series of bits. Using this function, you can determine the state of each CPU flag.
Examples
LOCAL nCPUFlags := 0xaa
IF ft_IsBitOn( nCPUFlags, 0 )
? "The carry flag was set."
ENDIF
IF ft_IsBitOn( nCPUFlags, 7 )
? "The sign flag was set."
ENDIF
nSize is the length of the character string to be returned.
If not specified the default length is 4 bytes.
Returns
A phonetically spelled character string
Description
This function is a character function use to index and search for sound-alike or phonetic matches. It is an alternative to the SoundEx() function, and addresses some basic pronunciation rules, by looking at surrounding letters to determine how parts of the string are pronounced. ft_Metaph() will group sound-alikes together, and forgive shortcomings in spelling ability.
Examples
// FIXME
USE test
INDEX ON ft_Metaph( field->last ) TO lastname
SEEK ft_Metaph( "Philmore" )
? Found(), field->last // --> .T. Philmore
SEEK ft_Metaph( "Fillmore" )
? Found(), field->last // --> .T. Philmore
lIgnoreCase is a boolean variable to force case sensitivity (optional, defaults to .T.).
Returns
The number of times cCheckFor appears in cCheckIn
Description
This function finds the number of times a string occurs in a
second string.
Examples
LOCAL cMemoString := hb_MemoRead( "test.txt" )
// Find the number of times "the" appears in cMemoString, case
// insensitive
? ft_NoOccur( "the", cMemoString )
// Find the number of times "the" appears in cMemoString, case
// sensitive
? ft_NoOccur( "the", cMemoString, .F. )
cString is the representation of the printer control codes in text, numeric, hexadecimal, Epson command format, or any combination separated by commas.
Returns
A character string of printer control codes.
Description
This function is useful for allowing the user to enter printer control codes in text (enclosed in double quotes), numeric, hexadecimal, or Epson commands preceded by a slash and returns the printer control code equivalent.
NOTES:
- Combinations of text, numbers, hex, and commands must be
separated by commas ("A",27,&1B,/RESET).
- Text must be enclosed in double quotes ("x"). - Hexadecimal must be preceded by an ampersand (&1B). - Epson commands, listed below, must be preceded by a forward
slash (/RESET).
Epson commands: (slash commands are specific to the Epson)
A string of the same length as cString, only converted to proper name case (upper/lower case).
Description
ft_Proper() uses a brute-force algorithm to convert a string to propername case. First, it capitalizes the first letter of all words starting after a blank, dash, or apostrophe. This catches most names, including special cases such as names beginning with O' (O'Malley, O'Reilly) and hyphenated names (such as Susan Chia-Mei Lo).
Next, it does a specific adjustment for words beginning in "Mc" It finds the first 'Mc' and capitalizes the next character after it. It does this for all occurrences of Mc.
The original ft_Proper() was written in Clipper by Glenn Scott and Mark Zechiel; it was re-written in C (and thus, optimized and enhanced) by Robert DiFalco.
lCaseSens is a logical value denoting case sensitivity.
If .F., then search is not sensitive to case, defaults to .T.
Returns
The position of the nth occurrence of a reversed substring
Description
This function will find the nth occurrence of a reversed substring within a string.
Examples
LOCAL cSearch := "t"
LOCAL cTarget := "This is the day that the Lord has made."
? ft_RAt2( cSearch, cTarget ) // --> 22
? ft_RAt2( cSearch, cTarget, 2 ) // --> 20
? ft_RAt2( cSearch, cTarget, 2, .F. ) // --> 20
This function is valuable if you use a graphics library and need to know what type of graphics adapter is installed.
Examples
LOCAL nVideo := ft_Adapter()
DO CASE
CASE nVideo == 0
? "You have a monochrome adapter."
CASE nVideo == 1
? "You have a CGA adapter."
CASE nVideo == 2
? "You have an EGA adapter."
CASE nVideo == 3
? "You have a VGA adapter."
ENDCASE
nTRow, nLCol, nBRow and nRCol are the screen coordinates to clear.
nColor is an integer representing the color attribute. The formula is:
nFore + ( nBack * 16 )
The default is black.
Returns
NIL
Description
This is a high speed function to clear the screen at the given coordinates with the given color attribute. This does not change Clipper's color settings. It uses direct video writes for speed.
Examples
ft_CLS( 0, 0, MaxRow(), MaxCol(), 165 )
// This example will clear the entire screen with the colors
// bright white on magenta.
Use this function to find out what mode your display adapter is in. Uses DOS interrupt 10h to get the mode. For a table of modes available on various graphics adapters, refer to a book such as Wilton's "Programmer's Guide to PC & PS/2 Video Systems" (Microsoft Press)
Return info about the cursor on a specified video page
Syntax
ft_GetVCur( [<nPage>] ) β aCurInfo
Arguments
nPage is the video page to get the cursor information for. Defaults to the current page, as returned by ft_GetVPg().
Returns
A four-element array (aCurInfo), set up as follows:
aCurInfo[ 1 ] = Top line of cursor aCurInfo[ 2 ] = Bottom line of cursor aCurInfo[ 3 ] = Character row aCurInfo[ 4 ] = Character column
Description
ft_GetVCur() uses ft_int86() to invoke interrupt 10h, function 3, to return the character cursor location for the specified video page.
The top line and bottom line of cursor are set depending on the current cursor mode, and are only meaningful in alphanumeric video modes.
For more information on graphics programming, cursors, and cursor modes, refer to Richard Wilton's Programmer's Guide to PC and PS/2 Video Systems (Microsoft Press).
Examples
LOCAL aCurInfo := ft_GetVCur( 1 ) // Get info on cursor pos in page 1
? "Row:", aCurInfo[ 3 ]
? "Col:", aCurInfo[ 4 ]
? hb_ValToExp( aCurInfo )
For more information on graphics programming and video pages, consult a reference such as Programmer's Guide to PC and PS/2 Video Systems (Microsoft Press).
The number of items remaining in the internal stack.
Description
This is the complementary function to ft_PushVid(). At some time after saving the video states it will probably be necessary to restore them. This is done by restoring the settings from the last call to ft_PushVid(). The number of items on the internal stack is then reduced by one. Note that the use of stack logic means that items on the stack are retrieved in Last In First Out order.
The current size of the internal stack (i.e. the number of times ft_PushVid() has been called).
Description
Menus, picklists, browses, and other video-intensive items often require you to save certain video states β screen image, cursor position, and so forth. Constantly saving and restoring these items can get very tedious. This function attempts to alleviate this problem. When called, it saves the cursor position, color setting, screen image, cursor style, blink setting, scoreboard setting, snow setting, and maximum row and column to a series of static arrays. All that is needed to restore the saved settings is a call to ft_PopVid().
nTop, nLeft, nBottom, and nRight define the screen region. cAttributes is a character string containing the attribute bytes
for the screen region. This will most often be a string previously returned by ft_SaveAtt(), but any character string may be used (provided it is of the proper size).
Returns
NIL
Description
This function is similar to Clipper's RestScreen(), except that it only restores the attribute bytes. This is useful if you want to change the screen color without affecting the text.
Internals Alert:
This function calls the Clipper internals __gtSave() and __gtRest() to manipulate the the screen image. If you're too gutless to use internals, then this function isn't for you.
Examples
// FIXME
LOCAL cBuffer
// Restore attributes of row 4
ft_RestAtt( 4, 0, 4, MaxCol(), cBuffer )
// Restore attributes to middle of screen
ft_RestAtt( 10, 20, 14, 59, cBuffer )
nTRow, nLCol, nBRow, and nRCol are the coordinates of the screen region.
Returns
NIL
Description
This is a high speed function to reverse the color of a specified screen region without disturbing any text on the screen. This function will correctly reverse the color attributes in a region containing multiple color combinations.
Examples
ft_RevAttr( 0, 0, MaxRow(), MaxCol() )
// This example will change the entire screen's colors to their reverse
// attributes without changing or overwriting any text.
Reverse the color of a single character on the screen
Syntax
ft_RevChr( <nTRow>, <nLCol> ) β NIL
Arguments
nTRow, nLCol are the screen coordinates of the character.
Returns
NIL
Description
This is a high speed function to reverse the color of a single character on the screen without changing the character itself. This function is the same as ft_RevAttr() except that it changes only one character on screen and hence is faster and uses less memory.
Examples
ft_RevChr( 10, 20 )
// This example will change the text and background at 10, 20 to it's
// reverse color attributes without changing or overwriting the
// character itself.
cAction determines what action ft_RgnStack() will take. The allowable values for this parameter are "push", "pop", and "pop all". If the function is called with any other string as the first parameter no action is performed.
cAction with a value of "push" will push a saved screen region onto the stack. A value of "pop" will restore the most recently pushed screen region. "pop all" tells the function to restore all screen images which are currently on the stack.
The use of nTop, nLeft, nBottom, and nRight depends on the cAction parameter. If cAction is "push", the next four parameters define the screen region to save. If cAction is "pop" or "pop all" the following four parameters are ignored.
Returns
ft_RgnStack() returns NIL.
Description
ft_RgnStack() allows multiple screens to be saved and restored from a stack. The stack is implemented with Clipper static array that is visible only to ft_RgnStack().
The purpose of ft_RgnStack() is to allow multiple screen regions to be managed without the need to remember the original coordinates or to create variables for each one.
When called with "push", ft_RgnStack() places the saved screen area at the end of the static array. The array size is incremented by one to accommodate the new screen area.
When called with "pop", the function restores the screen image stored in the last element of the array, and the array size is decremented by one. If "pop all" is specified, all the saved screens are restored until the array is empty.
ft_RgnStack() calls ft_SavRgn() and ft_RstRgn(). Refer to the documentation for these two functions for more information.
Examples
// The following example uses ft_RgnStack() to save and restore various
// sections of the screen.
LOCAL GetList := {}
@ 0, 0, 24, 79 BOX "111111111" // fill the screen with 1's
ft_RgnStack( "push", 10, 5, 15, 15 ) // push a region
@ 0, 0, 24, 79 BOX "222222222" // fill the screen with 2's
ft_RgnStack( "push", 10, 20, 15, 30 ) // push a region
@ 0, 0, 24, 79 BOX "333333333" // fill the screen with 3's
ft_RgnStack( "push", 10, 35, 15, 45 ) // push a region
@ 0, 0, 24, 79 BOX "444444444" // fill the screen with 4's
ft_RgnStack( "push", 10, 50, 15, 60 ) // push a region
@ 0, 0, 24, 79 BOX "555555555" // fill the screen with 5's
ft_RgnStack( "push", 10, 65, 15, 75 ) // push a region
CLEAR
ft_RgnStack( "pop" ) // restore the 5's region
ft_RgnStack( "pop" ) // restore the 4's region
ft_RgnStack( "pop all" ) // restore the 3's, 2's and 1's regions
cScreen is a screen region previously returned from ft_SavRgn().
nTop and nLeft are optional parameters that define a new location for the upper left corner of the screen area contained in cScreen. Allowable values are 0 through 255.
Returns
ft_RstRgn() returns NIL.
Description
ft_RstRgn() restores a screen region previously saved with ft_SavRgn(). Calling ft_RstRgn() with cScreen as the only parameter will restore the saved region to its original location. nTop and nLeft may be used to define a new location for the upper left corner of the saved region.
nTop and nLeft are dependent upon each other. You may not specify one without the other.
ft_RstRgn() calls Clipper's RestScreen(). Refer to the Clipper documentation for more information regarding this function.
Examples
// The following example uses ft_RstRgn() to restore a saved portion
// of the screen to different locations.
LOCAL cScreen
@ 0, 0, 24, 79 BOX "111111111" // fill the screen with 1's
cScreen := ft_SavRgn( 10, 10, 20, 30 ) // save a region
@ 0, 0, 24, 79 BOX "222222222" // fill the screen with 2's
ft_RstRgn( cScreen ) // restore the 1's region
@ 0, 0, 24, 79 BOX "222222222" // fill the screen with 2's
ft_RstRgn( cScreen, 15, 15 ) // restore to a different location
@ 0, 0, 24, 79 BOX "222222222" // fill the screen with 2's
ft_RstRgn( cScreen, 20, 60 ) // restore to a different location
nTop, nLeft, nBottom, and nRight define the screen region.
Returns
A character string containing the screen attribute bytes for the specified region. If the memory to store the return value could not be allocated, the function returns NIL.
Description
This function is similar to Clipper's SaveScreen(), except that it only saves the attribute bytes. This is useful if you want to change the screen color without affecting the text.
Internals Alert:
This function calls the Clipper internal __gtMaxCol() to obtain the maximum column value for the current video mode. If you're too gutless to use internals, then this function isn't for you.
Examples
// Save attributes of row 4
? hb_StrToHex( ft_SaveAtt( 4, 0, 4, MaxCol() ) )
// Save attributes from middle of screen
? hb_StrToHex( ft_SaveAtt( 10, 20, 14, 59 ) )
nTop, nLeft, nBottom, and nRight define the portion of the screen to save. Allowable values are 0 through 255.
Returns
ft_SavRgn() returns the saved screen region and its coordinates as a character string.
Description
ft_SavRgn() is similar to Clipper's SaveScreen(), but it saves the screen coordinates as well as the display information. The saved area can be restored by passing the returned string to ft_RstRgn().
Note that the strings returned from ft_SavRgn() and Clipper's SaveScreen() are not interchangeable. A screen region saved with with ft_SavRgn() must be restored using ft_RstRgn().
ft_SavRgn() calls Clipper's SaveScreen(). Refer to the Clipper documentation for more information regarding this function.
Examples
// The following example uses ft_SavRgn() and ft_RstRgn() to save
// and restore a portion of the screen.
LOCAL cScreen
@ 0, 0, 24, 79 BOX "111111111" // fill the screen with 1's
cScreen := ft_SavRgn( 10, 10, 20, 30 ) // save a region
@ 0, 0, 24, 79 BOX "222222222" // fill the screen with 2's
ft_RstRgn( cScreen ) // restore the 1's region
nTRow, nLCol, nBRow, and nRCol are the coordinates of the screen region.
nColor is an integer representing the new color attribute. The formula is:
nFore + ( nBack * 16 )
Returns
NIL
Description
This is a high speed function to change the colors of a specified region of the screen without disturbing any text. Uses direct video writes.
Examples
ft_SetAttr( 0, 0, MaxRow(), MaxCol(), 95 )
// This example will change the entire screen's colors to bright white on
// magenta without changing or overwriting any text on the screen.
Use this function to put your display adapter into a video mode. Uses DOS interrupt 10h to set the mode. For a table of modes available on various graphics adapters, refer to a book such as Wilton's "Programmer's Guide to PC & PS/2 Video Systems" (Microsoft Press)
ft_SetVCur() sets the cursor position on a specific video page. It uses ft_int86() to invoke interrupt 10h, function 2.
For more information on graphics programming, cursors, and video pages, refer to Richard Wilton's Programmer's Guide to PC and PS/2 Video Systems (Microsoft Press).
Examples
// Set the position to row 5, column 10 on video page 1:
ft_SetVCur( 1, 5, 10 )
For more information on graphics programming and video pages, consult a reference such as "Programmer's Guide to PC and PS/2 Video Systems" (Microsoft Press).
Examples
// The following sets the current video page to 1
ft_SetVPg( 1 )
nTop is the top row of the shadow area. nLeft is the upper left column of the shadow area. nBottom is the bottom row of the shadow area. nRight is the lower right column of the shadow area. nAttr is optional and is the screen attribute to use for drawing
the shadow. If not specified, the default is 8.
Returns
NIL
Description
This function allows you to implement the popular "shadow effect." It draws a shadow using the specified screen coordinates. The shadow is drawn along the bottom and right side of the specified region.
Examples
ft_Shadow( 10, 10, 15, 50, 8 ) // draw a dim shadow
ft_Shadow( 10, 10, 15, 40, 47 ) // draw a green shadow
cString is the string to be printed on the screen.
nColor is an integer representing the color attribute. The formula is:
nFore + ( nBack * 16 )
ft_VidStr() will display the string in the current color if nColor is not passed.
Returns
NIL
Description
This is a high speed function to display a string of any ASCII characters on screen in a specified color attribute. This function is useful for constructing screens with a lot of text or repetitive screen prints where speed is important.
Examples
ft_VidStr( 10, 20, "Enter Name :", 165 )
// This example will print the specified text at coordinates 10, 20
// in bright white on top of Magenta.
cChar is the single character to print on the screen.
nColor is an integer representing the color attribute. The formula is:
nFore + ( nBack * 16 )
Returns
NIL
Description
This is a high speed function to display a single ASCII character on screen in a specified color attribute. This function is useful for constructing screens with a lot of text or repetitive screen prints where speed is important. It is faster and requires less memory than ft_VidStr().
Examples
LOCAL nX, nY
FOR nX := 1 TO MaxRow()
FOR nY := 1 TO MaxCol()
ft_WrtChr( nX, nY, "β", ( nX - 1 ) + ( nY * 16 ) )
NEXT
NEXT
// This example will write the ASCII character 249 to every location
// `ON SCREEN` in every possible COLOR combination. It will recognize
// the status of SetBlink(). It uses direct video writes FOR speed.