SP_MBRZCLICK

MBRZCLICK()

  Short:
  ------
  MBRZCLICK() Checks for mouse click on current Tbrowse row/col

  Returns:
  --------
  <lClicked> => if the mouse clicked on the current Tbrowse cursor row and
                column.

  Syntax:
  -------
  MBRZCLICK(oTBrowse, nMouseRow, nMouseCol)

  Description:
  ------------
  Determines if the mouse coordinates <nMouseRow> and <nMouseCol>
  are within the area of the current Tbrowse row and column.

  Examples:
  ---------
  from MCHOICE():

   case nLastKey == K_MOUSELEFT
         do case
         case ISMOUSEAT(nMouseR, nMouseC, nBottom,nRight-3, nBottom, nRight-2)
            oTb:down()
            IFMOUSEHD({||oTb:down()},oTb)
         case MBRZMOVE(oTb,nMouseR, nMouseC,nTop+1,nLeft+1,nBottom-1,nRight-1)
            keyboard chr(K_ENTER)
         case MBRZCLICK(oTb,nMouseR, nMouseC)   //<-----here
            EXIT
         endcase
   endcase

  Source:
  -------
  S_MOOSE.PRG

 

SP_BROWSESDF

BROWSESDF()

  Short:
  ------
  BROWSESDF() Tbrowse an SDF file

  Returns:
  --------
  Nothing

  Syntax:
  -------
  BROWSESDF(cFile,aDesc,aTypes,aLengths)

  Description:
  ------------
  Tbrowses an SDF file <cFile>, using column headers in
  <aDesc>, with field 'types' in <aTypes>, and field lengths in
  <aLengths>

  Examples:
  ---------

   //sample.sdf looks like this:

   //AHLBERG              STEPHEN           23.4519890226
   //SMITH                JEFF              45.0019890301
   //SMITH                DENNIS             0.0019890313
   //ALVARADO             DAVID             25.0019890330

   //note: widths have to be exact

   browseSDF("sample.sdf",{"Last","First","Due","Date"},;
                          {"C","C","N","D"},;
                          {20,15,8,8})

  Source:
  -------
  S_BRSDF.PRG

 

SP_BROWSEDELIM

BROWSEDELIM()

  Short:
  ------
  BROWSEDELIM() Tbrowse a delimited file

  Returns:
  --------
  Nothing

  Syntax:
  -------
  BROWSEDELIM(cFile,aDesc,aTypes,aLens,[cFieldDelim],;
            [cCharDelim])

  Description:
  ------------
  Browse delimited file <cFile>.

  Column titles are contained in <aDesc> (one for each 'field').

  Field types are contained in <aTypes>, Field lengths
  are contained in <aLens>.

  [cFieldDelim] - Field delimiter - default is a comma [,]

  [cCharDelim] - Character type delimiter - default is
  a double quote [""]

  Examples:
  ---------

   //sample.asc looks like  this:

   //"AHLBERG","STEPHEN",23.45,19890226
   //"SMITH","JEFF",45.00,19890301
   //"SMITH","DENNIS",0.00,19890313
   //"ALVARADO","DAVID",25.00,19890330
   //"AMPOLSUK","EARL",60.00,19890406
   //"ANDRADE","GARRY",55.00,19890301
   //"ANDRADE","WALT",99.99,19890703

   browsedelim("sample.asc",{"First","Last","Due","Date"},;
                          {"C","C","N","D"},;
                          {15,25,6,8})

  Source:
  -------
  S_BDELIM.PRG

 

SP_BROWSE2D

BROWSE2D()

  Short:
  ------
  BROWSE2D() Popup  tbrowse of 2 dimension array (array of arrays)

  Returns:
  --------
  <nSelection> => selected item, 0 if none

  Syntax:
  -------
  BROWSE2D(nTop,nLeft,nBottom,nRight,aArr,[aHead],[cColor],;
        [cTitle],[bExcept])

  Description:
  ------------
  Pops up a box at <nTop,nLeft,nBottom,nRight> and
  tbrowses array contained in <aArr>.

  <aArr> must be a 2 dimensioned array, like the ones
  returned from DIRECTORY() or DBSTRUCT().

  i.e. { array(n),array(n),array(n) } where <n> is the
  same length for each subarray.

  [aHead] an array of column headers matching the
  number of elements in a single subarray of <aArr>. Default is
  none.

  [cColor] popup box color. Default is sls_popcol()

  [cTitle] title string for the box. Default is none.

  [bExcept] is a codeblock that will be evaluated for
  any exception keys - any keys other than up/ down/ right/ left/
  pgup/ pgdn/ home/ end/ enter/ esc. [bExcept] will be passed the
  parameters: key value, tbrowse object, element

  Examples:
  ---------

   proc test

   local a := directory()
   browse2d(5,5,20,40,a, ;
           {"File","Size","Date","Time","Attribute"},,"Choose a File")

   use customer
   a := dbstruct()
   browse2d(5,5,20,40,a,nil,nil,nil,;
    {|k|msg(str(k)+" is not a valid key")})
   // note the exception block

  Source:
  -------
  S_2DBRZ.PRG

 

SP_AASKIP

AASKIP()

  Short:
  ------
  AASKIP() Use for skipblock for arrays in Tbrowse

  Returns:
  --------
  <nSkipcount> => number skipped, forward or backward

  Syntax:
  -------
  AASKIP(nSkip,@nElement,nMaxRows)

  Description:
  ------------
  Use this to create the SKIPBLOCK for a tbrowse that browses
  an array, as in :

    aTbrowseObject:SKIPBLOCK := {|n|aaskip(n,@nElement,len(aArray)}

  <nSkip>      is passed in by Tbrowse as a +- value, or
               as zero.

  <nElement>   is the current array element number.
               PASSED IN BY REFERENCE!

  <nMaxrows>   refers to the length of the array being
               browsed

  Examples:
  ---------
  // this example browses the fields in a database

   local nLastKey,  nElement    := 1
   local aArray := dbstruct()
   local oTb        := tBrowseNew(2,2,20,78)
   oTb:addcolumn(tbcolumnew("Name",{||aArray[nElement,1]}))
   oTb:addcolumn(tbcolumnew("Type", {||aArray[nElement,2]}))
   oTb:addcolumn(tbcolumnew("Len " , {||aArray[nElement,3]}))
   oTb:addcolumn(tbcolumnew("Deci",  {||aArray[nElement,4]}))
   oTb:Skipblock        := {|n|aaskip(n,@nElement,len(aArray)}
   oTb:goTopBlock       := {||nElement := 1}
   oTb:goBottomBlock    := {||nElement := len(aArray)}

   while .t.
     while !oTb:stabilize()
     end
     nLastKey := inkey(0)
     do case
        /// various actions.....
     endcase
   end

  Notes:
  -------
  Aaskip() is used by a lot of SuperLib functions, but
  is very useful by itself for creating array tbrowses.

  Source:
  -------
  S_AASKIP.PRG

 

 

C5 UI – TBrowse Classes

C5 UI – TBrowse Classes

TBrowse :

Provides objects for browsing table-oriented data.

Description :

A TBrowse object is a general purpose browsing mechanism for table-oriented data. TBrowse objects provide a sophisticated architecture for acquiring, formatting, and displaying data. Data retrieval and file positioning are performed via user-supplied code blocks, allowing a high degree of flexibility and interaction between the browsing mechanism and the underlying data source. The format of individual data items can be precisely controlled via the TBColumn data retrieval code blocks; overall display formatting and attributes can be controlled by sending appropriate messages to the TBrowse object.

A TBrowse object relies on one or more TBColumn objects. A TBColumn object contains the information necessary to define a single column of the browse table (see TBColumn class in this chapter).

During operation, a TBrowse object retrieves data by evaluating code blocks. The data is organized into rows and columns and displayed within a specified rectangular region of the screen. The TBrowse object maintains an internal browse cursor. The data item on which the browse cursor rests is displayed in a highlighted color. (The actual screen cursor is also positioned to the first character of this data item.)

Initially, the browse cursor is placed on the data item at the top left of the browse display. Messages can then be sent to the TBrowse object to navigate the displayed data, causing the browse cursor to move. These messages are normally sent in response to user keystrokes.

New data is automatically retrieved as required by navigation requests. When navigation proceeds past the edge of the visible rectangle, rows or columns beyond that edge are automatically brought into view. When new rows are brought into view, the underlying data source is repositioned by evaluating a code block.

Note: TBrowse objects do not clear the entire window before output during redisplay operations. Part of the window may still be cleared when data from the existing display is scrolled.

Class Functions :

TBrowseNew() :

Create a new TBrowse object

 TBrowseNew(<nTop>, <nLeft>, <nBottom>, <nRight>)
 --> objTBrowse

Returns a new TBrowse object with the specified coordinate settings. The TBrowse object is created with no columns and no code blocks for data positioning. These must be provided before the TBrowse object can be used.

TBrowseDB() :

Create a new TBrowse object for browsing a database file

 TBrowseDB(<nTop>, <nLeft>, <nBottom>, <nRight>)
 --> objTBrowse

Returns a new TBrowse object with the specified coordinate settings and default code blocks for data source positioning within database files. The default code blocks execute the GO TOP, GO BOTTOM, and SKIP operations.

Note that TBrowseDB() creates an object with no column objects. To make the TBrowse object usable, you must add a column for each field to be displayed

Exported Instance Variables:

autoLite : Logical value to control highlighting (Assignable)

Contains a logical value. When autoLite is set to true (.T.), the stabilize method automatically highlights the current cell as part of stabilization. The default for autoLite is true (.T.).

cargo : User-definable variable  (Assignable)

Contains a value of any data type provided as a user-definable slot. TBrowse:cargo allows arbitrary information to be attached to a TBrowse object and retrieved later.

colCount : Number of browse columns

Contains a numeric value indicating the total number of data columns in the browse. For each column, there is an associated TBColumn object.

colorSpec : Color table for the TBrowse display (Assignable)

Contains a character string defining a color table for the TBrowse display. As a default, the current SETCOLOR() value is copied into this variable when the TBrowse object is created (see the SETCOLOR() reference in this chapter).

colPos : Current cursor column position (Assignable)

Contains a numeric value indicating the data column where the browse cursor is currently located. Columns are numbered from one, starting with the leftmost column.

colSep : Column separator character  (Assignable)

Contains a character value that defines a column separator for TBColumns that do not contain a column separator of their own (see TBColumn class in this chapter for more information).

footSep : Footing separator character (Assignable)

Contains a character value that defines a footing separator for TBColumns not containing a footing separator of their own (see TBColumn class in this chapter).

freeze : Number of columns to freeze (Assignable)

Contains a numeric value that defines the number of data columns frozen on the left side of the display. Frozen columns are always visible, even when other columns are panned off the display.

goBottomBlock : Code block executed by TBrowse:goBottom() (Assignable)

Contains a code block executed in response to the TBrowse:goBottom() message. This block is responsible for repositioning the data source to the last record displayable in the browse. Typically the data source is a database file, and this block contains a call to a user-defined function that executes a GO BOTTOM command.

goTopBlock : Code block executed by TBrowse:goTop() (Assignable)

Contains a code block that is executed in response to the TBrowse:goTop() message. This block is responsible for repositioning the data source to the first record displayable in the browse. Typically the data source is a database file, and this block contains a call to a user-defined function that executes a GO TOP command.

headSep : Heading separator character  (Assignable)

Contains a character value that defines a heading separator for TBColumns not containing a heading separator of their own (see TBColumn class in this chapter).

hitBottom : Indicates the end of available data (Assignable)

Contains a logical value indicating whether an attempt was made to navigate beyond the end of the available data. TBrowse:hitBottom contains true (.T.) if an attempt was made; otherwise it contains false (.F.). During stabilization, the TBrowse object sets this variable if TBrowse:skipBlock indicates it was unable to skip forward as many records as requested.

hitTop : Indicates the beginning of available data  (Assignable)

Contains a logical value indicating whether an attempt was made to navigate past the beginning of the available data. TBrowse:hitTop contains true (.T.) if an attempt was made; otherwise it contains false (.F.). During stabilization, the TBrowse object sets this variable if TBrowse:skipBlock indicates that it was unable to skip backward as many records as requested.

leftVisible : Indicates position of leftmost unfrozen column in display

Contains a numeric value indicating the position of the leftmost unfrozen column visible in the browse display. If every column is frozen in the display, TBrowse:leftVisible contains zero.

nBottom : Bottom row number for the TBrowse display  (Assignable)

Contains a numeric value defining the bottom screen row used for the TBrowse display.

nLeft : Leftmost column for the TBrowse display (Assignable)

Contains a numeric value defining the leftmost screen column used for the TBrowse display.

nRight : Rightmost column for the TBrowse display (Assignable)

Contains a numeric value defining the rightmost screen column used for the TBrowse display.

nTop : Top row number for the TBrowse display  (Assignable)

Contains a numeric value defining the top screen row used for the TBrowse display.

rightVisible : Indicates position of rightmost unfrozen column in display

Contains a numeric value indicating the position of the rightmost unfrozen column visible in the browse display. If all columns visible in the display are frozen, TBrowse:rightVisible contains zero.

rowCount : Number of visible data rows in the TBrowse display

Contains a numeric value indicating the number of data rows visible in the browse display. Only data rows are included in the count. Rows occupied by headings, footings, or separators are not included.

rowPos : Current cursor row position

skipBlock : Code block used to reposition data source (Assignable)

Contains a code block that repositions the data source. During stabilization, this code block is executed with a numeric argument when the TBrowse object needs to reposition the data source. The numeric argument passed to the block represents the number of records to be skipped. A positive value means skip forward, and a negative value means skip backward. A value of zero indicates that the data source does not need to be repositioned, but the current record may need to be refreshed. Typically the data source is a database file, and this block calls a user-defined function that executes a SKIP command to reposition the record pointer.

The block must return the number of rows (positive, negative, or zero) actually skipped. If the value returned is not the same as the value requested, the TBrowse object assumes that the skip operation encountered the beginning or end of file.

stable : Indicates if the TBrowse object is stable  (Assignable)

Contains a logical value indicating whether the TBrowse object is stable. It contains true (.T.) if the TBrowse object is stable; otherwise, it contains false (.F.). The browse is considered stable when all data has been retrieved and displayed, the data source has been repositioned to the record corresponding to the browse cursor, and the current cell has been highlighted. When navigation messages are sent to the TBrowse object, TBrowse:stable is set to false (.F.). After stabilization is performed using the TBrowse:stabilize() message, TBrowse:stable is set to true (.T.).

Exported Methods:

Cursor Movement Methods :

down() : Moves the cursor down one row

down() --> self

Moves the browse cursor down one row. If the cursor is already on the bottom row, the display is scrolled up and a new row is brought into view. If the data source is already at the logical end of file and the browse cursor is already on the bottom row, TBrowse:hitBottom is set true (.T.).

end() : Moves the cursor to the rightmost visible data column

end() --> self

Moves the browse cursor to the rightmost data column currently visible.

goBottom() : Repositions the data source to the bottom of file

goBottom() --> self

Repositions the data source to logical bottom of file (by evaluating the TBrowse:goBottomBlock), refills the display with the bottommost available data, and moves the browse cursor to the lowermost data row for which data is available. The pan position of the window is not changed.

goTop() : Repositions the data source to the top of file

goTop() --> self

Repositions the data source to the logical beginning of file (by evaluating the TBrowse:goTopBlock), refills the display with the topmost available data, and moves the browse cursor to the uppermost data row for which data is available. The pan position of the window is not changed.

home() : Moves the cursor to the leftmost visible data column

home() --> self

Moves the browse cursor to the leftmost unfrozen column on the display.

left() : Moves the cursor left one column

left() --> self

Moves the browse cursor left one data column. If the cursor is already on the leftmost displayed column, the display is panned and the previous data column (if there is one) is brought into view.

pageDown() : Repositions the data source downward

pageDown() --> self

Repositions the data source downward and refills the display. If the data source is already at the logical end of file (i.e., the bottommost available record is already shown), the browse cursor is simply moved to the lowermost row containing data. If the data source is already at the logical end of file and the browse cursor is already on the bottom row, TBrowse:hitBottom is set true (.T.).

pageUp() : Repositions the data source upward

pageUp() --> self

Repositions the data source upward and refills the display. If the data source is already at logical beginning of file (i.e., the topmost available record is already shown), the browse cursor is simply moved to the top data row. If the data source is already at logical beginning of file and the browse cursor is already on the first data row, TBrowse:hitTop is set true (.T.).

panEnd() : Moves the cursor to the rightmost data column

panEnd() --> self

Moves the browse cursor to the rightmost data column, causing the display to be panned completely to the right.

panHome() : Moves the cursor to the leftmost visible data column

panHome() --> self

Moves the browse cursor to the leftmost data column, causing the display to be panned all the way to the left.

panLeft() : Pans left without changing the cursor position

panLeft() --> self

Pans the display without changing the browse cursor, if possible. When the screen is panned with TBrowse:panLeft(), at least one data column out of view to the left is brought into view, while one or more columns are panned off screen to the right.

panRight() : Pans right without changing the cursor position

panRight() --> self

Pans the display without changing the browse cursor, if possible. When the screen is panned with TBrowse:panRight(), at least one data column out of view to the right is brought into view, while one or more columns are panned off the screen to the left.

right() : Moves the cursor right one column

right() --> self

Moves the browse cursor right one data column. If the cursor is already at the right edge, the display is panned and the next data column (if there is one) is brought into view.

up() : Moves the cursor up one row

up() --> self

Moves the browse cursor up one row. If the cursor is already on the top data row, the display is scrolled down and a new row is brought into view. If the data source is already at the logical beginning of file and the browse cursor is already on the top data row, TBrowse:hitTop is set true (.T.).

Miscellaneous Methods :

addColumn() : Adds a TBColumn object to the TBrowse object

addColumn(<objColumn>) --> self

Adds a new TBColumn object to the TBrowse object and TBrowse:colCount is increased by one.

colorRect() : Alters the color of a rectangular group of cells

colorRect(<aRect>, <aColors>) --> self

Directly alters the color of a rectangular group of cells. <aRect> is an array of four numbers (top, left, bottom, and right). The numbers refer to cells within the data area of the browse display, not to screen coordinates. <aColors> is an array of two numbers. The numbers are used as indexes into the color table for the browse. These colors will become the normal and highlighted colors for the cells within the specified rectangle.

Cells that are colored using colorRect retain their color until they are scrolled off the screen up or down. Horizontal panning has no affect on these colors and, in fact, cells that are currently off screen left or right can be colored even if they are not visible.

This example colors the entire virtual window (on and off screen):

aRect := {1, 1, browse:rowCount, browse:colCount} browse:colorRect( aRect, {2, 1} )

colWidth() : Returns the display width of a particular column

colWidth(<nColumn>) --> nWidth

Returns the display width of column number <nColumn> as known to the browse. If <nColumn> is out of bounds or not supplied or not a number, the method returns zero.

configure() : Reconfigures the internal settings of the TBrowse object

configure() --> self

Causes the TBrowse object to reexamine all instance variables and TBColumn objects, reconfiguring its internal settings as required. This message can force reconfiguration when a TBColumn object is modified directly.

deHilite() : Dehighlights the current cell

deHilite() --> self

Causes the current cell (the cell to which the browse cursor is positioned) to be dehighlighted. This method is designed for use when TBrowse:autoLite is set to false (.F.).

delColumn() : Delete a column object from a browse

delColumn(<nPos>) --> objColumn

This new method allows a column to be deleted from a browse. The return value is a reference to the column object being deleted so that the column object may be preserved.

forceStable() : Performs a full stabilization .

forceStable()

Performs a full stabilization of the TBrowse. It is analogous to the following code, only slightly faster:

         DO WHILE .NOT. oBrowse:stabilize()
         ENDDO

getColumn() : Gets a specific TBColumn object

getColumn(<nColumn>) --> objColumn

Returns the TBColumn object specified by <nColumn>.

hilite() : Highlights the current cell

hilite() --> self

Causes the current cell (the cell to which the browse cursor is positioned) to be highlighted. This method is designed for use when TBrowse:autoLite is set to false (.F.).

insColumn() : Insert a column object in a browse

insColumn(<nPos>, <objColumn>) --> objColumn

This method allows a column object to be inserted into the middle of a browse. The return value is a reference to the column object being inserted.

invalidate() : Forces redraw during next stabilization

invalidate() --> self

TBrowse:invalidate() causes the next stabilization of the TBrowse object to redraw the entire TBrowse display, including headings, footings, and all data rows. Note that sending this message has no effect on the values in the data rows; it simply forces the display to be updated during the next stabilization. To force the data to be refreshed from the underlying data source, send the TBrowse:refreshAll() message.

refreshAll() : Causes all data to be refreshed during the next stabilize

refreshAll() --> self

Internally marks all data rows as invalid, causing them to be refilled and redisplayed during the next stabilize loop.

refreshCurrent() : Causes the current row to be refreshed on next stabilize

refreshCurrent() --> self

Internally marks the current data row as invalid, causing it to be refilled and redisplayed during the next stabilize loop.

setColumn() : Replaces one TBColumn object with another

setColumn(<nColumn>, <oColumnNew>) --> oColumnCurrent

Replaces the TBColumn object indicated by <nColumn> with the TBColumn object specified by <oColumnNew>. The value returned is the current TBColumn object.

stabilize() : Performs incremental stabilization

stabilize() --> lStable

Performs incremental stabilization. Each time this message is sent, some part of the stabilization process is performed. Stabilization is performed in increments so that it can be interrupted by a keystroke or other asynchronous event.

If the TBrowse object is already stable, a value of true (.T.) is returned. Otherwise, a value of false (.F.) is returned indicating that further stabilize messages should be sent. The browse is considered stable when all data has been retrieved and displayed, the data source has been repositioned to the record corresponding to the browse cursor, and the current cell has been highlighted.

TBColumn :

Provides the column objects TBrowse objects.

Description :

A TBColumn object is a simple object containing the information needed to fully define one data column of a TBrowse object (see the TBrowse reference in this chapter). TBColumn objects have no methods, only exported instance variables.

Class Function :

TBColumnNew() :

Create a new TBColumn object.

TBColumnNew(<cHeading>, <bBlock>) --> objTBColumn

Exported Instance Variables :

block : Code block to retrieve data for the column (Assignable)

Contains a code block that retrieves data for the column. Any code block is valid, and no block arguments are supplied when the block is evaluated. The code block must return the appropriate data value for the column.

cargo : User-definable variable (Assignable)

Contains a value of any data type provided as a user-definable slot, allowing arbitrary information to be attached to a TBColumn and retrieved later.

colorBlock : Code block that determines color of data items (Assignable)

Contains an optional code block that determines the color of data items as they are displayed. If present, this block is executed each time a new value is retrieved via the TBColumn:block (the data retrieval block). The newly retrieved data value is passed as an argument to the TBColumn:colorBlock, which must return an array containing two numeric values. The values returned are used as indexes into the color table of the TBrowse object as described in the TBColumn:defColor reference below.

The TBColumn:colorBlock allows display colors for data items based on the value of the data being displayed. For example, negative numbers may be displayed in a different color than positive numbers.

colSep : Column separator character (Assignable)

Contains an optional character string that draws a vertical separator to the left of this column if there is another column to the left of it. If no value is supplied for TBColumn:colSep, the value contained in TBrowse:colSep is used instead.

defColor : Array of numeric indexes into the color table (Assignable)

Contains an array of two numeric values used as indexes into the color table in the TBrowse object. The first value determines the unselected color which displays headings, footings, etc. It also displays data values when the browse cursor is not on the data value being displayed. The second value determines the selected color. The selected color displays the current browse cell.

The default value for TBColumn:defColor is {1, 2}. This causes the first two colors in the TBrowse color table to be used for unselected and selected, respectively. Note that colors set using TBColumn:colorBlock override those set by TBColumn:defColor.

footing : Column footing (Assignable)

Contains a character value that defines the footing for this data column.

footSep : Footing separator character (Assignable)

Contains a character value that draws a horizontal line between the data values and the footing. If it does not contain a character value: TBrowse:footSep is used instead.

heading : Column heading (Assignable)

Contains a character value that defines the heading for this data column.

headSep : Heading separator character (Assignable)

Contains an optional character string that draws a horizontal separator between the heading and the data values. If it does not contain a character value, the TBrowse:headSep is used instead.

width : Column display width  (Assignable)

Contains a numeric value that defines the display width for the column. If TBColumn:width is not explicitly set, the width of the column will be the greater of: the length of the heading, the length of the footing, or the length of the data at the first evaluation of TBColumn:block.

If this instance variable is explicitly set, the width of the column will be TBColumn:width. Displayed headings, footings, and data will all be truncated to this width when necessary. The width of the displayed data will be the length at the first evaluation of TBColumn:block for all data types other than character. Character data will be extended to TBColumn:width for display purposes.

Example :

This example is a code fragment that creates a TBrowse object and adds some TBColumn objects to it:

USE Customer NEW
//
// Create a new TBrowse object
objBrowse := TBrowseDB(1, 1, 23, 79)
//
// Create some new TBColumn objects and
// add them to the TBrowse object
objBrowse:addColumn(TBColumnNew( "Customer", ;
                    {|| Customer->Name} ))
objBrowse:addColumn(TBColumnNew( "Address", ;
                    {|| Customer->Address} ))
objBrowse:addColumn(TBColumnNew( "City", ;
                    {|| Customer->City} ))
.
. <statements to actually browse the data>
.
CLOSE Customer

For a simple and working sample look at here.