Manual TXBrowse

Post Reply
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Manual TXBrowse

Post by Antonio Linares »

Thanks to Carlos Atúncar Hernandez

REFERENCE MANUAL

TXBrowse / XBrowse

FiveWin for Harbour

Properties · Methods · Events · Columns

Based on official FiveWin examples

--- 1. Introduction

TXBrowse (invoked via the command @ X,Y XBROWSE or XBROWSER) is the most powerful grid control in FiveWin for Harbour. It allows displaying and editing data from DBF/RDD tables, ADO RecordSets, arrays, TDatabase objects, trees (TTree), and text files.

1.1 Supported Data Sources Property / EventTypeDescription and Usage ALIAS / DATASOURCERDDOpen DBF table. Usage: ALIAS 'CUST' or DATASOURCE "CUSTOMER" RECORDSET / RECSETADOADO RecordSet. Usage: RECSET oRs or RECORDSET oRs ARRAYArrayTwo-dimensional array. Usage: ARRAY aData OBJECTObjectTDatabase object or similar. Usage: OBJECT oCust DATASOURCE oTreeTTreeTTree node tree for hierarchical browsing
1.2 Methods of Creating the Browse Declarative Command

@ nRow, nCol XBROWSE oBrw OF oParent ALIAS 'CUST' AUTOCOLS LINES CELL

Programmatic (Class)

oBrw := TXBrowse():New( oWnd )
oBrw:SetRDD() // or :SetArray( aData ) / :SetRecordSet( oRs )
oBrw:CreateFromCode()

📌 NOTE: Always call :CreateFromCode() at the end of the configuration, before activating the dialog/window.

--- 2. Browse Properties (TXBrowse) 2.1 Appearance and Style PropertyTypeDescription and Usage nMarqueeStyleNumericRow/cell selector style. See MARQSTYLE_* (Section 7) nRowDividerStyleNumericDivider line style between rows. See LINESTYLE_* (Section 7) nColDividerStyleNumericDivider line style between columns. See LINESTYLE_* lColDividerCompleteLogicalIf .T., column lines extend to the header. Default: .F. nRowHeightNumericRow height in pixels. e.g.: oBrw:nRowHeight := 40 nHeaderHeightNumericHeader height in pixels. e.g.: oBrw:nHeaderHeight := 30 nDataLinesNumericText lines per data row. e.g.: := 2 for multiline nHeaderLinesNumericNumber of header lines. e.g.: := 2 nFooterLinesNumericNumber of footer lines l2007LogicalEnables Office 2007 visual style. e.g.: oBrw:l2007 := .T. nWidthsNumericUniform width for all columns in pixels
2.2 Scrolling and Columns PropertyTypeDescription and Usage nStretchColNumericColumn that expands to fill space. See STRETCHCOL_* (Section 7) nFreezeNumericNumber of frozen columns. e.g.: oBrw:nFreeze := 2 lHScrollLogicalShow/hide horizontal scrollbar. Default: .T. lVScrollLogicalShow/hide vertical scrollbar. Default: .T. lRecordSelectorLogicalShow/hide record selector (left column). Default: .T. nColSelNumericCurrently selected column index (read-only)
2.3 Colors PropertyTypeDescription and Usage bClrStdBlockStandard cell colors. { || { nTextColor, nBackColor } } bClrRowFocusBlockColor of the row with focus. e.g.: {|| {CLR_BLACK, RGB(185,220,255)}} bClrSelFocusBlockColor of selected cell/row with focus. bClrHeaderBlockHeader color. e.g.: {|| {CLR_WHITE, RGB(134,219,9)}} oDataFontsObj/BlockFont for data. Can be a font object or a block oFooterFontsObjectFont for footers

📌 NOTE: Color blocks return an array: { nTextColor, nBackColor }. Background can be RGB or a gradient array.

2.4 Background Method / PropertyTypeDescription and Usage SetBackGround(cRes)MethodSets background image. e.g.: oBrw:SetBackGround("PAPER") SetBackGround(aGrad, lVert)MethodGradient background. aGrad is the array, lVert is orientation oBrushObjectCurrent background brush
--- 3. Browse Events (TXBrowse) EventTypeDescription and Usage bChangeBlockExecuted on row change. e.g.: {|| oCol:RefreshFooter() } bRClickedBlockRight-click on data. {|nRow, nCol| ShowPopup(nRow,nCol,oBrw)} bLDClickDataBlockLeft double-click on data bKeyDownBlockKey pressed bKeyCharBlockCharacter typed bPopUpBlockRight-click popup menu bSeekBlockIncremental search while typing
--- 4. Column Properties (TXBrwColumn) 4.1 Identification and Header PropertyTypeDescription and Usage cHeaderStringHeader text. Supports CRLF for multiline nHeadStrAlignNumericHeader alignment: AL_LEFT / AL_CENTER / AL_RIGHT oHeaderFontFont ObjSpecial font for header (e.g., vertical) nPosNumericCurrent visible position nWidthNumericColumn width in pixels
4.2 Data and Formatting PropertyTypeDescription and Usage cEditPictureStringFormat/Edit mask. e.g.: :HireDate:cEditPicture := 'dd mmm yyyy' bStrDataBlockBlock returning cell text. {|| _FIELD->First} ValueVariousCurrent cell value (read/write). oBrw:oCol("City"):Value lDisplayZerosLogicalIf .F., hides zeros nDataStrAlignNumericData alignment: AL_LEFT / AL_CENTER / AL_RIGHT
4.3 Images and Bitmaps Method / PropertyTypeDescription and Usage AddResource(cRes)MethodAdd bitmap from resource nHeadBmpNoNum/BlockBitmap index for header bBmpDataBlockBlock returning bitmap index for data lBmpTransparentLogicalEnables alpha transparency bStrImageBlockBlock returning image path
--- 5. Main Methods MethodDescription CreateFromCode()Finalizes browse construction. Mandatory as the last step. SetArray(aData)Sets or changes the data array SetRDD()Configures browse for the active RDD area Refresh([lFull])Redraws browse. lFull=.T. for complete reconstruction Edit([lNew])Opens editor for current record. lNew=.T. for new record ToExcel()Exports browse to Excel Report()Generates a report or PDF SaveState()Saves columns/order/widths to a string RestoreState(c)Restores saved state
--- 6. Dynamic Column Access

XBrowse allows accessing columns by name directly as a property:

  • Direct: oBrw:Salary:nFooterType := AGGR_TOTAL
  • Via Method: oBrw:oCol("Salary"):lTotal := .T.
  • Computed Column: oBrw:NewSalary := { || oBrw:Salary:Value * 1.1 }
--- 7. Reference Constants 7.1 MARQSTYLE_* (Selector Style)
  • MARQSTYLE_DOTCELL (1): Dotted frame.
  • MARQSTYLE_SOLIDCELL (2): Solid frame.
  • MARQSTYLE_HIGHLCELL (3): Highlight cell.
  • MARQSTYLE_HIGHLROW (5): Highlight full row.
  • MARQSTYLE_HIGHLWIN7: Win7/10 gradient style.
7.2 EDIT_* (Editor Types)
  • EDIT_NONE (0): No editing.
  • EDIT_GET (1): Standard Textbox.
  • EDIT_LISTBOX: Dropdown list.
  • EDIT_GET_BUTTON: GET with action button.
7.3 AGGR_* (Footer Aggregates)
  • AGGR_TOTAL / AGGR_SUM: Sum.
  • AGGR_AVERAGE: Mean.
  • AGGR_COUNT: Count.
--- 8. Recommended Usage Pattern
  1. Define Data Source (ALIAS, ARRAY, etc.).
  2. Create browse via @ X,Y XBROWSE or New().
  3. Set Browse properties (Styles, Marquee, Colors).
  4. Configure Column properties (Headers, Editing, Bitmaps).
  5. Call MakeTotals() if using footers.
  6. Call CreateFromCode() (Always the last configuration step).
  7. Assign oWnd:oClient := oBrw.
  8. Activate window and call oBrw:SetFocus().
--- 9. Advanced Features 9.1 Incremental Filter

Code: Select all | Expand

WITH OBJECT oBrw
   :lIncrFilter := .T.
   :lSeekWild   := .T. // "Contains" search
   :cFilterFld  := "FIRST"
END
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Manual TXBrowse

Post by Antonio Linares »

REFERENCE MANUAL

TXBrowse / XBrowse

FiveWin for Harbour

Properties · Methods · Events · Columns

Based on official FiveWin examples

1\. Introduction

TXBrowse (invoked via the @ X,Y XBROWSE or XBROWSER command) is the most powerful grid control in FiveWin for Harbour. It allows displaying and editing data from DBF/RDD tables, ADO RecordSets, arrays, TDatabase objects, trees (TTree), and text files.

1.1 Supported Data Sources Property / EventTypeDescription and Usage ALIAS / DATASOURCERDDOpen DBF table. Usage: ALIAS 'CUST' or DATASOURCE "CUSTOMER" RECORDSET / RECSETADOADO RecordSet. Usage: RECSET oRs or RECORDSET oRs ARRAYArrayTwo-dimensional array. Usage: ARRAY aData OBJECTObjectTDatabase object or another with similar interface. Usage: OBJECT oCust DATASOURCE oTreeTTreeTTree node tree for hierarchical browse
1.2 Ways to Create the Browse Declarative command

@ nRow, nCol XBROWSE oBrw OF oParent ALIAS 'CUST' AUTOCOLS LINES CELL

Programmatic (class)

oBrw := TXBrowse():New( oWnd )

oBrw:SetRDD() // or :SetArray( aData ) / :SetRecordSet( oRs )

oBrw:CreateFromCode()

📌 NOTE: Always call :CreateFromCode() at the end of configuration, before activating the dialog/window.

2\. Browse Properties (TXBrowse) 2.1 Appearance and Style Property / EventTypeDescription and Usage nMarqueeStyleNumericRow/cell selector style. See MARQSTYLE\_\* constants (section 7\) nRowDividerStyleNumericDividing line style between rows. See LINESTYLE\_\* (section 7\) nColDividerStyleNumericDividing line style between columns. See LINESTYLE\_\* lColDividerCompleteLogicalIf .T., the column line extends to the header. Default: .F. nRowHeightNumericHeight of each row in pixels. Ex: oBrw:nRowHeight := 40 nHeaderHeightNumericHeader height in pixels. Ex: oBrw:nHeaderHeight := 30 nDataLinesNumericNumber of text lines per data row. Ex: := 2 for multiline nHeaderLinesNumericNumber of header lines. Ex: := 2 for 2-line headers nFooterLinesNumericNumber of column footer lines l2007LogicalActivates Office 2007 visual style. Ex: oBrw:l2007 := .T. nWidthsNumericUniform width for all columns in pixels
2.2 Scrolling and Columns Property / EventTypeDescription and Usage nStretchColNumericColumn that expands to fill available space. See STRETCHCOL\_\* (section 7\) nFreezeNumericNumber of frozen columns (don't scroll horizontally). Ex: oBrw:nFreeze := 2 lHScrollLogicalShows/hides horizontal scrollbar. Default: .T. lVScrollLogicalShows/hides vertical scrollbar. Default: .T. lRecordSelectorLogicalShows/hides the record selector (left column). Default: .T. nColSelNumericCurrently selected column number (read)
2.3 Colors Property / EventTypeDescription and Usage bClrStdBlockStandard cell color. {{ nTextColor, nBkgColor } }. Ex: {{CLR\_BLACK, CLR\_WHITE}} bClrRowFocusBlockColor of the focused row. Ex: {{CLR\_BLACK, RGB(185,220,255)}} bClrSelFocusBlockColor of the selected cell/row with focus. Same format as bClrStd bClrHeaderBlockHeader color. Ex: {{CLR\_WHITE, RGB(134,219,9)}} oDataFontsObject/BlockFont for data. Can be a font object or block {If(cond, oFontA, oFontB)} oFooterFontsObjectFont for column footers

📌 NOTE: Color blocks return a 2-element array: { nTextColor, nBkgColor }. The background can be an RGB color or even a gradient array.

2.4 Background Property / EventTypeDescription and Usage SetBackGround(cRes)MethodSets background image. Ex: oBrw:SetBackGround("PAPER") SetBackGround(aGrad, lVert)MethodGradient background. aGrad is an array of segments, lVert sets vertical/horizontal orientation oBrushObjectCurrent background brush. oBrw:oBrush:nResizeMode for mode (BCK\_TILED, etc.)
Gradient example

local aGrad := {{ .5, CLR\_BLUE, RGB(202,202,255) }, { .5, RGB(202,202,255), CLR\_BLUE }}

// In the XBROWSE command: BACKGROUND aGrad VERTICAL

// Or in code: oBrw:SetBackGround( aGrad, .T. )

2.5 Editing Property / EventTypeDescription and Usage nEditTypesNumericEdit type for ALL columns at once. Ex: oBrw:nEditTypes := EDIT\_GET lFastEditLogicalAllows fast editing without needing to press Enter first. Ex: := .T. lFormulaEditLogicalEnables formula editing in cells. Ex: oBrw:lFormulaEdit := .T. bEditWhensBlockGlobal condition for when to allow editing. {oColcondition} lAutoAppendLogicalAllows automatically adding rows when reaching the end of the array bPastEofBlockBlock executed when trying to go beyond the last record
2.6 Column Footers Property / EventTypeDescription and Usage lFooterLogicalActivates/deactivates the footer row. Ex: oBrw:lFooter := .T. cFootersArrayArray with footer texts for all columns MakeTotals(\[oCol\])MethodRecalculates totals/aggregates for footers. Called after configuring columns
2.7 Sorting and Searching Property / EventTypeDescription and Usage bSeekBlockBlock for incremental search. {cDbSeek(Upper(c))} nArrayAtNumericIndex of the current row in the array (only for ARRAY source) aArrayDataArrayReference to the data array (ARRAY source) aRowArrayArray with values of the current row BookMarkVariousBookmark of the current record (RDD/ADO) nLenNumericTotal number of records/rows in the browse
2.8 Multi-Selection Property / EventTypeDescription and Usage aSelectedArrayArray with bookmarks of selected rows (multiselect) SelectAll()MethodSelects all rows SelectNone()MethodDeselects all rows nMarqueeStyle := MARQSTYLE\_HIGHLROWMSConstantEnables multi-selection mode with Ctrl+click
2.9 Group Headers Property / EventTypeDescription and Usage SetGroupHeader(cTxt,n1,n2,oFont)MethodDefines a group header spanning columns n1 to n2. Ex: :SetGroupHeader('EMPLOYEE'+CRLF+'NAME', 1, 2, oBold) lAllowColReGroupLogicalAllows reordering columns within a group. Ex: := .T.
Example

oBrw:SetGroupHeader( 'EMPLOYEE' \+ CRLF \+ 'NAME', 1, 2, oBold )

oBrw:SetGroupHeader( 'ADDRESS', 3, 6, oBold )

2.10 Tree Browse Property / EventTypeDescription and Usage DATASOURCE oTreeTTreeTree-type data source for hierarchical browse oTreeItemTTreeItemCurrently selected node in the tree oTreeTTreeReference to the browse data tree SetTree(nil, aBmps)MethodConverts a normal browse to an automatic tree nDataTypeNumericData type. DATATYPE\_TREE if tree
2.11 State and Persistence Property / EventTypeDescription and Usage SaveState()MethodSaves the current state (columns, order, etc.) to a string RestoreState(cState)MethodRestores the state saved with SaveState() lKineticBrwLogicalEnables kinetic scrolling (touch). Ex: := .T.
2.12 Cell Tooltip Property / EventTypeDescription and Usage bCellToolTipsBlockGeneric tooltip for any cell. {oCol{oCol:Value, oCol:cHeader}} cToolTipStringSimple tooltip for the entire browse. Ex: oBrw:cToolTip := 'Text'

📌 NOTE: bCellToolTips applies to all columns, but can be overridden per column with oCols\[n\]:bCellToolTip

3\. Browse Events (TXBrowse) Property / EventTypeDescription and Usage bChangeBlockExecuted when changing rows. Ex: {oCol:RefreshFooter() } bRClickedBlockRight-click on data. {nRow, nColShowPopup(nRow,nCol,oBrw)} bLDClickDataBlockLeft double-click on data bKeyDownBlockKey pressed. {oDlg:SetText(Str(oBrw:nColSel))} bKeyCharBlockCharacter typed. {kIf(k==VK\_RETURN, ..., nil)} bPopUpBlockPopup menu on right-click. {oColMenu(o)} bSeekBlockIncremental search while typing. {cDbSeek(Upper(c))} bClrSelFocusBlockColor of row/cell with focus and active selection
4\. Column Properties (TXBrowseCol) 4.1 Identification and Header Property / EventTypeDescription and Usage cHeaderStringHeader text. Can include CRLF for multi-line. Ex: "Name" \+ CRLF \+ "Employee" nHeadStrAlignNumericAlignment of header text. AL\_LEFT / AL\_CENTER / AL\_RIGHT oHeaderFontFont objectSpecial font for the header. Can be a vertical font (NESCAPEMENT 900\) nCreationOrderNumericColumn creation order. Useful with nStretchCol nPosNumericCurrent visible position of the column nWidthNumericColumn width in pixels. Ex: :nWidth := 80 nArrayColNumericColumn index in the source array (for ARRAY source)
4.2 Data and Formatting Property / EventTypeDescription and Usage cEditPictureStringFormat/edit mask. Ex: :HireDate:cEditPicture := 'dd mmm yyyy' bStrDataBlockBlock that returns the cell text. {\_FIELD-\>First} bEditValueBlockBlock that returns the editable value. {\_FIELD-\>Married} ValueVariousCurrent cell value (read/write). oBrw:oCol("City"):Value lDisplayZerosLogicalIf .F., does not display zeros. Ex: oBrw:lDisplayZeros := .F. nDataStrAlignsNumericData alignment for ALL columns at once (browse property) nDataStrAlignNumericData alignment of the column. AL\_LEFT / AL\_CENTER / AL\_RIGHT bDataStrAlignBlockDynamic alignment. {oIf(o:oBrw:aRow\[1\]==0, AL\_CENTER, AL\_LEFT)} nDataStyleNumericDrawing style for text in the cell
4.3 Column Colors Property / EventTypeDescription and Usage bClrStdBlockColumn color. Overrides browse bClrStd. {{nText, nBkg}} bClrEditBlockColor when editing the cell. Ex: oBrw:aCols\[1\]:bClrEdit := oBrw:bClrStd oBrushObjectOwn brush (image/color background) for the column bExtendBlockCell extension (merge): {oIf(cond, nCols, 0)}. Simulates cell merging
4.4 Images and Bitmaps in Column Property / EventTypeDescription and Usage AddBmpFile(cFile)MethodAdds a bitmap from file to the column image list AddResource(cRes)MethodAdds a bitmap from resource. Ex: :AddResource("GREEN") AddBitmap(aNames)MethodAdds bitmap array. Ex: :AddBitmap({"OPEN","CLOSE","GREEN"}) nHeadBmpNoNumeric/BlockBitmap number to show in the header. 1-based. Can be a block nHeadBmpAlignNumericBitmap alignment in header. AL\_LEFT / AL\_RIGHT / AL\_CENTER nGrpBmpNoNumericBitmap number for group header bBmpDataBlockBlock that returns the bitmap number to show in data. {If(cond,1,2)} nDataBmpAlignNumericBitmap alignment in data. AL\_LEFT / AL\_CENTER / AL\_RIGHT lBmpStretchLogicalIf .T., stretches the bitmap to fill the cell lBmpTransparentLogicalIf .T., renders the bitmap with alpha transparency bStrImageBlockBlock that returns the image path for the cell. {oCol,oBrwoBrw:aRow\[2\]} bAlphaLevelBlockAlpha transparency level (0-255). {oo:oBrw:aRow\[3\]} nFootBmpNoNumericBitmap number to show in the column footer

📌 NOTE: For transparent PNG images with alpha channel, use lBmpTransparent := .T. combined with bAlphaLevel.

4.5 Column Footer Property / EventTypeDescription and Usage cFooterStringStatic footer text. Ex: oCols\[1\]:cFooter := "TOTAL" bFooterBlockDynamic block for footer. {LTrim(Str(oTxt:RecCount()))} nFooterTypeNumericType of automatic aggregate. See AGGR\_\* (section 7\) bSumConditionBlockCondition to include row in total. {u,oo:oBrw:aRow\[1\]\>0} bLClickFooterBlockLeft-click on footer. {r,c,f,oFooterAggrClick(r,c,f,o)} bRClickFooterBlockRight-click on footer RefreshFooter()MethodRefreshes the column footer lTotalLogicalActivates automatic total in footer. Ex: oCol:lTotal := .T. nTotalNumericValue of accumulated total (read/write)
4.6 Column Editing Property / EventTypeDescription and Usage nEditTypeNumericEditor type. See EDIT\_\* (section 7). Ex: := EDIT\_GET bOnPostEditBlockExecuted after confirming the edit. {oCol, xVal, nKey...} bEditBlockBlockBlock for the edit button (EDIT\_GET\_BUTTON). {r,c,oCol...} aEditListTxtArrayTexts for the edit listbox (EDIT\_GET\_LISTBOX) aEditListBoundArrayValues corresponding to the listbox texts cEditPictureStringInput mask when editing. Ex: "@K \!\!\!\!\!\!\!\!\!\!" lAutoSaveLogicalIf .T., saves automatically when leaving the cell without needing bOnPostEdit SetCheck(aBmps, xEdit)MethodConverts column to checkbox. aBmps can be {"GREEN","RED"} nBtnBmpStringBitmap path for the edit button. Ex: "c:\\\\fwh\\\\bitmaps\\\\browse.bmp" bPaintTextBlockOwner-draw for cell text. {oCol,hDC,cText,aCoordDrawText(...)}
4.7 Column Events Property / EventTypeDescription and Usage bLClickHeaderBlockLeft-click on header. {r,c,f,oCol...} bRClickHeaderBlockRight-click on header bLDClickDataBlockLeft double-click on data blDClickDatasBlockAlias of bLDClickData in some contexts bRClickDataBlockRight-click on data bLClickFooterBlockLeft-click on footer bRClickFooterBlockRight-click on footer bCellToolTipBlockCell-specific tooltip. {oColTRIM(FIELD-\>FIRST)+CRLF+TRIM(FIELD-\>LAST)} cToolTipArrayColumn tooltip as array {cText, cTitle}. Ex: {'Col: '+cHeader,'Tip'} bPopUpBlockColumn context menu. {oColMenu(o)}
4.8 Cell Anchoring (AnchorToCell) Property / EventTypeDescription and Usage AnchorToCell(oDlg)MethodPositions a dialog anchored to the current cell. Ideal for search popups
Example

oDlg:bInit := { || oCol:AnchorToCell( oDlg ) }

5\. Main Browse Methods Property / EventTypeDescription and Usage CreateFromCode()MethodFinalizes the browse construction. Always call at the end of configuration SetArray(aData)MethodSets or changes the data array. Ex: oBrw:SetArray( aData ) SetRDD()MethodConfigures the browse to use the active RDD area Refresh(\[lFull\])MethodRedraws the browse. lFull=.T. for full rebuild SetFocus()MethodSets focus to the browse Edit(\[lNew\])MethodOpens the editor for the current record. lNew=.T. for new record Delete()MethodDeletes the current record GoBottom()MethodGoes to the last record/row GoTop()MethodGoes to the first record/row InsCol(nPos)MethodInserts a column at position nPos. Returns the column object AddCol()MethodAdds a column at the end. Returns the column object MoveCol(oColA, oColB)MethodMoves column oColA before oColB oCol(cName)MethodReturns column by name. Ex: oBrw:oCol("Salary") GetVisibleCols()MethodReturns array with visible columns MakeTotals(\[oCol\])MethodRecalculates footer totals DataRect()MethodReturns array {nTop,nLeft,nBottom,nRight} of the data area FontSize(nDelta)MethodIncreases or decreases font size. Ex: :FontSize(+1) SelFont()MethodOpens dialog to select font SetAlign(nAlign)MethodChanges alignment of the active column ToExcel(\[lTitle,nMode\])MethodExports the browse to Excel Report(\[...\])MethodGenerates a printed or PDF report of the browse SaveState()MethodSaves browse state (columns, order, widths) RestoreState(cState)MethodRestores a previously saved state SelectAll()MethodSelects all rows (multiselect mode) SelectNone()MethodDeselects all rows SetBackGround(xBkg, nMode)MethodSets the browse background SetGroupHeader(c, n1, n2, oF)MethodDefines group header for columns n1 to n2 SetTree(nil, aBmps)MethodActivates automatic tree mode
6\. Dynamic Column Access

XBrowse allows accessing browse columns by name directly as a browse property, thanks to the magic of \_\_GetProperty:

6.1 By name (direct access)

oBrw:Salary:nFooterType := AGGR\_TOTAL

oBrw:Married:SetCheck( { "GREEN", "RED" }, .T. )

oBrw:HireDate:cEditPicture := 'dd mmm yyyy'

6.2 Via oCol() method

if \!Empty( oCol := oBrw:oCol( "Salary" ) )

oCol:lTotal := .T.

oCol:nEditType := EDIT\_GET

endif

6.3 By index in aCols

oBrw:aCols\[ 1 \]:bClrStd := {|| {CLR\_WHITE, CLR\_RED} }

oBrw:aCols\[ 2 \]:nHeadStrAlign := AL\_CENTER

6.4 Computed column (formula)

// Adds new column based on another

oBrw:NewSalary := { || oBrw:Salary:Value \* 1.1 }

WITH OBJECT oBrw:NewSalary

:cHeader := 'NewSalary'

:nFooterType := AGGR\_TOTAL

END

6.5 ADD TO (command)

ADD TO oBrw DATA (cAlias)-\>CITY HEADER "City" CARGO { 1, 2 }

ADD TO oBrw DATA oRs:Fields("TotSalary"):Value / oRs:Fields("Employees"):Value ;

HEADER "AVERAGE" PICTURE "999,999,999"

7\. Reference Constants 7.1 MARQSTYLE\_\* — Selector Style ConstantTypeDescription and Usage MARQSTYLE\_DOTCELL (1)ConstantDotted frame on the active cell MARQSTYLE\_SOLIDCELL (2)ConstantSolid frame on the active cell MARQSTYLE\_HIGHLCELL (3)ConstantHighlights the active cell with color MARQSTYLE\_HIGHLROWRC (4)ConstantHighlights active row and column MARQSTYLE\_HIGHLROW (5)ConstantHighlights the entire active row MARQSTYLE\_HIGHLROWMS (6)ConstantHighlights row with multi-selection support MARQSTYLE\_HIGHLWIN7ConstantWindows 7/10 gradient bar style
7.2 LINESTYLE\_\* — Divider Line Style ConstantTypeDescription and Usage LINESTYLE\_NONE (0)ConstantNo divider lines LINESTYLE\_BLACK (1)ConstantBlack lines LINESTYLE\_DARKGRAY (2)ConstantDark gray lines LINESTYLE\_FORECOLOR (3)ConstantLines in the browse text color LINESTYLE\_LIGHTGRAY (4)ConstantLight gray lines LINESTYLE\_INSET (5)ConstantInset-style lines (sunken) LINESTYLE\_RAISED (6)ConstantRaised-style lines
7.3 STRETCHCOL\_\* — Elastic Column ConstantTypeDescription and Usage STRETCHCOL\_NONEConstantNo elastic column STRETCHCOL\_LASTConstantLast column fills remaining space STRETCHCOL\_WIDESTConstantWidest column stretches nCreationOrderNumericThe nCreationOrder of a specific column can also be used
7.4 EDIT\_\* — Editor Types ConstantTypeDescription and Usage EDIT\_NONE (0)ConstantNo editing EDIT\_GET (1)ConstantStandard GET (text box) EDIT\_LISTBOXConstantDrop-down listbox EDIT\_GET\_LISTBOXConstantGET combined with listbox EDIT\_BUTTONConstantAction button beside the GET EDIT\_GET\_BUTTONConstantGET combined with button TYPE\_IMAGEConstantEditable image in the cell
7.5 AGGR\_\* — Footer Aggregate Types ConstantTypeDescription and Usage AGGR\_TOTAL / AGGR\_SUMConstantSum of all column values AGGR\_AVERAGE / AGGR\_AVGConstantAverage of values AGGR\_MAXConstantMaximum value AGGR\_MINConstantMinimum value AGGR\_COUNTConstantRecord count AGGR\_STDEVConstantStandard deviation AGGR\_STDEVPConstantPopulation standard deviation
7.6 AL\_\* — Alignment ConstantTypeDescription and Usage AL\_LEFTConstantLeft alignment AL\_CENTERConstantCenter alignment AL\_RIGHTConstantRight alignment
8\. Complete Examples 8.1 Basic browse over DBF

@ 0,0 XBROWSE oBrw OF oWnd ALIAS 'CUSTOMER' AUTOCOLS LINES CELL

oBrw:nMarqueeStyle := MARQSTYLE\_HIGHLROW

oBrw:nRowDividerStyle := LINESTYLE\_BLACK

oBrw:CreateFromCode()

oWnd:oClient := oBrw

8.2 Browse over Array with editing

@ 0,0 XBROWSE oBrw OF oDlg ARRAY aData AUTOCOLS LINES CELL FASTEDIT

oBrw:lHScroll := .F.

oBrw:lVScroll := .F.

AEval( oBrw:aCols, {|o| o:nEditType := EDIT\_GET} )

oBrw:CreateFromCode()

8.3 Browse with dynamic colors

oBrw:bClrStd := {|| {CLR\_WHITE, iif(Field-\>Married, CLR\_RED, CLR\_GREEN)} }

oBrw:aCols\[10\]:bClrStd := {|| {iif(Field-\>Salary\>100000, CLR\_HRED, CLR\_HBLUE), CLR\_GRAY}}

8.4 Browse with footer and totals

WITH OBJECT oBrw:Salary

:nFooterType := AGGR\_TOTAL

:bLClickFooter := {|r,c,f,o| FooterAggrClick(r,c,f,o)}

END

oBrw:lFooter := .T.

oBrw:MakeTotals()

oBrw:CreateFromCode()

8.5 Multi-selection with Windows 7 style

oBrw:nMarqueeStyle := MARQSTYLE\_HIGHLWIN7

WITH OBJECT oBrw:InsCol( 1 )

:cHeader := " "

:bEditValue := {|| If(AScan(oBrw:aSelected, oBrw:BookMark)\>0, .T., nil)}

:SetCheck()

:nHeadBmpNo := {|| If(Len(oBrw:aSelected)==oBrw:nLen, 1, 2)}

:bLClickHeader := {|r,c,f,oCol| If(Len(oBrw:aSelected)==oBrw:nLen, ;

Code: Select all | Expand

  oBrw:SelectNone(), oBrw:SelectAll())}

END

8.6 Group Headers with bold font

DEFINE FONT oBold NAME 'VERDANA' SIZE 0,-14 BOLD

oBrw:SetGroupHeader( 'EMPLOYEE' \+ CRLF \+ 'NAME', 1, 2, oBold )

oBrw:SetGroupHeader( 'ADDRESS', 3, 6, oBold )

oBrw:SetGroupHeader( 'OTHER', 8, 9, oBold )

oBrw:lAllowColReGroup := .T.

8.7 Image with alpha transparency

oBrw:aCols\[ 1 \]:nEditType := TYPE\_IMAGE

oBrw:aCols\[ 1 \]:lBmpStretch := .F.

oBrw:aCols\[ 1 \]:lBmpTransparent := .T.

oBrw:aCols\[ 1 \]:bStrImage := {|oCol, oBrw| oBrw:aRow\[ 2 \]}

oBrw:aCols\[ 1 \]:nDataBmpAlign := AL\_CENTER

oBrw:aCols\[ 1 \]:bAlphaLevel := {|o| o:oBrw:aRow\[ 3 \]}

8.8 Cell tooltip

oBrw:bCellToolTips := {|oCol| {oCol:Value, oCol:cHeader}}

oBrw:aCols\[1\]:bCellToolTip := {|oCol| TRIM(FIELD-\>FIRST) \+ CRLF \+ TRIM(FIELD-\>LAST)}

8.9 Cell merging (bExtend)

WITH OBJECT :aCols\[ 1 \]

:bExtend := {|o| If(o:oBrw:aRow\[1\]==0, 2, 0)} // extends 2 cols if subtotal

:bDataStrAlign := {|o| If(o:oBrw:aRow\[1\]==0, AL\_CENTER, AL\_LEFT)}

:bClrStd := {|| {CLR\_BLACK, If(oBrw:aRow\[1\]==0, CLR\_YELLOW, CLR\_WHITE)}}

END

8.10 Browse with gradient background

local aGrad := {{ .5, CLR\_BLUE, RGB(202,202,255) }, { .5, RGB(202,202,255), CLR\_BLUE }}

@ 10,10 XBROWSE oBrw ... BACKGROUND aGrad VERTICAL

// Or dynamically:

oBrw:SetBackGround( aGrad, .T. ) // .T. \= vertical

oBrw:SetBackGround( "PAPER" ) // Image resource

oBrw:SetBackGround() // Clear background

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Manual TXBrowse

Post by Antonio Linares »

9\. Recommended Usage Pattern

The following is the typical order for configuring an XBrowse completely and correctly:

  1. 1\. Define the data source (ALIAS, ARRAY, RECSET, OBJECT)

  2. 2\. Create the browse with @ X,Y XBROWSE ... or TXBrowse():New()

  3. 3\. Configure browse properties (styles, colors, marquee, scroll)

  4. 4\. Configure column properties (headers, editing, colors, bitmaps)

  5. 5\. Define group headers if applicable (SetGroupHeader)

  6. 6\. Call MakeTotals() if there are footers with aggregates

  7. 7\. Call CreateFromCode() — ALWAYS the last step

  8. 8\. Assign oWnd:oClient := oBrw (for windows)

  9. 9\. Activate the window or dialog with ON INIT oBrw:SetFocus()

📌 NOTE: CreateFromCode() MUST always be the last configuration call. Any property or method called after CreateFromCode() may have no effect.

10\. Advanced Record Selector

The record selector (the left gray column) can be fully customized to show row numbers, names, icons, and context menus.

10.1 Record Selector Properties Property / EventTypeDescription and Usage bRecSelDataBlockContent of the selector cell. {brwbrw:KeyNo} shows sequential number bRecSelHeaderString/BlockSelector header. Ex: oBrw:bRecSelHeader := "SlNo" bRecSelFooterString/BlockSelector footer. {brwbrw:nLen} shows total records nRecSelWidthNumeric/StringSelector width. If string, used as model: "9999" → width for 4 digits nRecSelHeadBmpNoNumeric/String/ArrayBitmap in selector header. Can be path, number, or line descriptor bRecSelClickBlockClick on selector header. {RecSelPopUp(oBrw)} SetRecSelBmp(xBmp)MethodSets custom bitmap in selector. nil=default, 0=no bitmap, cFile=image lRecordSelectorLogicalShows/hides entire selector. Default: .T. RecSelShowRecNo()MethodDisplays the record number in the selector (convenient shortcut) SetChecks()MethodConfigures all logical fields as checkboxes in the browse SetMultiSelectCol()MethodAdds automatic multi-selection checkbox column oMultiSelColObjectReference to the multi-selection column created by SetMultiSelectCol() SelectRow()MethodReturns .T. if the current row is selected (for use with bSumCondition) oRightColObjectColumn frozen on the RIGHT. Ex: oBrw:oRightCol := oBrw:Salary KeyNoNumericSequential number of the current row (read property of the browse)
Example: Selector with row number

WITH OBJECT oBrw

:bRecSelData := { |brw| brw:KeyNo }

:bRecSelFooter := { |brw| brw:nLen }

:bRecSelHeader := "SlNo"

:nRecSelWidth := "9999"

END

Example: Selector with region name (Array)

WITH OBJECT oBrw

:bRecSelData := { |brw| brw:aRow\[ 1 \] } // name in col 1

:bRecSelFooter := "Totals"

:bRecSelHeader := "Region"

:nRecSelWidth := "Americas" // width for the longest text

END

Example: Multi-selection with conditional totals

WITH OBJECT oBrw

:SetMultiSelectCol()

:bClrStd := { || { CLR\_BLACK, If( oBrw:SelectRow(), 0x88EDFB, CLR\_WHITE ) } }

:Salary:bSumCondition := { || oBrw:SelectRow() }

:Salary:nFooterType := AGGR\_SUM

:MakeTotals()

END

11\. GetBar and Incremental Filter 11.1 GetBar — Gets below headers

Allows displaying input fields directly below column headers to filter the browse in real time.

Property / EventTypeDescription and Usage lGetBarLogicalActivates/deactivates the GETs bar below headers. Ex: oBrw:lGetBar := .T. uBarGetValVariousInitial value of the column GET. Ex: oCol:uBarGetVal := Space(10) cBarGetPicStringMask of the GET in the bar. Ex: oCol:cBarGetPic := NumPict(FieldLen(n), FieldDec(n)) bClrEditsBlockColor of bar GETs. {{CLR\_BLACK, CLR\_YELLOW}} oHeaderFontsObjectFont for headers. Ex: oBrw:oHeaderFonts := oBold AutoFit()MethodAutomatically adjusts column width to content
11.2 Incremental Filter

Allows filtering the browse while the user types, without needing to press Enter.

Property / EventTypeDescription and Usage lIncrFilterLogicalActivates real-time incremental filter. Ex: oBrw:lIncrFilter := .T. lSeekWildLogicalIf .T., filters by content (contains). If .F., filters by beginning (starts with) cFilterFldStringName of the field to filter. Ex: oBrw:cFilterFld := "FIRST" cSeekStringCurrent search text (read) oSeekSAY ObjectSAY control showing current search text Seek(cText)MethodExecutes the search. Ex: oBrw:Seek("") to clear
12\. Internal Button Bar (nTopBarHeight / bOnAdjust)

XBrowse allows embedding a button bar directly inside the browse itself, above the data, without needing an external ButtonBar.

Property / EventTypeDescription and Usage nTopBarHeightNumericHeight in pixels of the internal bar. Ex: oBrw:nTopBarHeight := 30 bOnAdjustBlockBlock executed when creating/adjusting the browse. Internal buttons are created here EditSource(\[lNew\])MethodOpens editor for current record. lNew=.T. for new. Alias of Edit()
Complete example

oBrw:nTopBarHeight := 30

oBrw:bOnAdjust := \<||

local oBtn

@ 05,05 BTNBMP oBtn FILE "new.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:EditSource( .T. ) TOOLTIP "Add"

@ 05,45 BTNBMP oBtn FILE "edit.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:EditSource() TOOLTIP "Edit"

@ 05,85 BTNBMP oBtn FILE "delete.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:Delete() TOOLTIP "Delete"

return nil

\>

13\. Fonts and Colors per Line (Advanced Multiline)

XBrowse allows assigning different fonts and colors to each line of text within a multiline cell, using the aDataFont and aClrText properties of the column.

Property / EventTypeDescription and Usage aDataFontArray of fontsArray of font objects per line. Line N uses aDataFont\[N\]. Ex: oCols\[1\]:aDataFont := {oFont1, oFont2} aClrTextArray of colorsArray of text colors per line. nil \= default color. Ex: {CLR\_HBLUE, CLR\_HRED} nDataStrAlignNumericCan combine AL\_CENTER \+ AL\_BOTTOM for vertical+horizontal alignment aImgRectArrayImage crop in cell: {nTop%, nLeft%, nBottom%, nRight%, cShape}. Shape: "CIRCLE", nil=rect lFitGridHeightLogicalAdjusts browse height to fit exactly N complete rows nHeadStrAlignsNumericAlignment of ALL headers at once (browse property) nWidthsArray/NumericIf array, sets individual widths: {200, 250, 150}. If numeric, uniform width
Example: different fonts and colors per line

DEFINE FONT aFont1\[ 1 \] NAME "VIVALDI" SIZE 0,-30

DEFINE FONT aFont1\[ 2 \] NAME "Verdana" SIZE 0,-20

WITH OBJECT oBrw:Name

:aDataFont := aFont1

:aClrText := { CLR\_HBLUE, CLR\_HRED }

END

Example: image cropped in circular shape

WITH OBJECT oBrw:aCols\[ 3 \]

:bStrImage := { || "c:\\\\images\\\\photo.jpg" }

:aImgRect := { nil, 0.3, 0.7, nil, "CIRCLE" }

// nil \= full edge, 0.3 \= 30% from left, 0.7 \= 70% from left

END

14\. Inheritance — Derived Classes from TXBrowse

It is possible to create classes derived from TXBrowse and TXBrwColumn to customize behavior at the class level, automatically applying changes to all browses of the same type.

14.1 Creating a derived class from TXBrowse

CLASS MyBrowse FROM TXBrowse

CLASSDATA lRegistered AS LOGICAL // MANDATORY

DATA bColClass INIT { || MyXBrCol() } // own column class

METHOD New( oWnd ) CONSTRUCTOR

ENDCLASS

METHOD New( oWnd ) CLASS MyBrowse

Super:New( oWnd )

::nMarqueeStyle := MARQSTYLE\_HIGHLROWMS

::bClrStd := { || { CLR\_BLACK, RGB(255,255,206) } }

::bClrSelFocus := { || { CLR\_WHITE, CLR\_BLUE } }

::bClrRowFocus := { || { CLR\_BLACK, RGB(150,231,255) } }

return Self

14.2 Derived class from TXBrwColumn

CLASS MyXbrCol FROM TXBrwColumn

METHOD Adjust()

ENDCLASS

METHOD Adjust() CLASS MyXBrCol

if ::cDataType \== 'D'

Code: Select all | Expand

  ::cEditPicture := 'dd-mmm-yyyy'

endif

Super:Adjust()

return Self

14.3 Activating the derived class Property / EventTypeDescription and Usage CLASS MyBrowse() in commandClause@ X,Y XBROWSE oBrw CLASS MyBrowse() ... — only that browse uses the class SET XBROWSE TO MyBrowse()CommandAll browses created from here use MyBrowse() SET XBROWSE TO bXBrCommandRestores the previous class (saved with SAVE PREVIOUS TO bXBr) SetXBrowse({MyBrowse() })FunctionProgrammatic equivalent of SET XBROWSE TO lRegisteredCLASSDATAMANDATORY in derived classes. Declares the class as registered in FWH bColClassDATABlock that instantiates the column class. INIT {TXBrwColumn() } by default cDataTypeStringColumn data type: 'C', 'N', 'D', 'L', 'M', 'F' (image)
Example with SAVE PREVIOUS

SET XBROWSE TO MyBrowse() SAVE PREVIOUS TO bXBr

// ... create browses that will use MyBrowse ...

SET XBROWSE TO bXBr // restore original class

15\. Group Totals (SetGroupTotal)

In addition to group headers, it is possible to show automatic totals per group and a consolidated grand total.

Property / EventTypeDescription and Usage SetGroupTotal(cGrp, cHdr)MethodAdds a total row for a group. cGrp \= group name, cHdr \= header text SetGroupTotal(aGrps, cHdr, nAggr, oFont)MethodGrand total of multiple groups. nAggr \= AGGR\_SUM (default) nFooterTypesNumericAggregate type for ALL numeric columns at once RefreshFooters()MethodRefreshes all column footers bOnChangeBlockColumn event when value changes. {oBrw:MakeTotals(), oBrw:RefreshFooters()} lAllowColReGroupLogicalAllows moving columns between groups. Ex: := .T.
Complete example

:SetGroupHeader( 'Americas', 2, 3, oBold )

:SetGroupHeader( 'Europe', 4, 5, oBold )

:lAllowColReGroup := .T.

:SetGroupTotal( 'Americas', 'Total' )

:SetGroupTotal( 'Europe', 'Total' )

:SetGroupTotal( { 'Americas\_Total', 'Europe\_Total' }, 'Grand' \+ CRLF \+ 'Total', AGGR\_SUM, oBold )

AEval( oBrw:aCols, { |o| o:bOnChange := { || oBrw:MakeTotals(), oBrw:RefreshFooters() } }, 2 )

16\. Cell Movement Control (nMoveType)

The nMoveType property controls how the cursor moves when pressing Enter or Tab after editing a cell.

Property / EventTypeDescription and Usage nMoveTypeNumericMovement direction when confirming edit. See MOVE\_\* constants MOVE\_RIGHTConstantMoves cursor to the right cell (default for editing) MOVE\_LEFTConstantMoves cursor to the left cell MOVE\_UPConstantMoves cursor to the cell above MOVE\_DOWNConstantMoves cursor to the cell below MOVE\_NONEConstantDoes not move cursor when confirming MOVE\_FAST\_RIGHTConstantSame as MOVE\_RIGHT but with fast behavior MOVE\_FAST\_LEFTConstantSame as MOVE\_LEFT but with fast behavior nRowSelNumericCurrently selected row number (visible) nColSelNumericCurrently selected column number lColChangeNotifyLogicalIf .T., fires bChange also when changing columns lRelyOnKeyNoLogicalIf .F., uses physical position instead of KeyNo for positioning
Example

oBrw:nMoveType := MOVE\_RIGHT // on confirm, go right

// or dynamically:

oBrw:nMoveType := MOVE\_DOWN // spreadsheet-style behavior

17\. Additional Properties and Advanced Techniques 17.1 Text Highlighting (FW\_SayTextHilite)

Allows highlighting specific words within cell text with a different font and color, using bPaintText.

oBrw:aCols\[ 2 \]:bPaintText := {|oCol, hDC, cText, aRect, aColors|

FW\_SayTextHilite( hDC, cText, aRect, oFont, aColors\[1\], aColors\[2\],

Code: Select all | Expand

  { { AllTrim(cWordHL), oBold, CLR\_HRED, CLR\_HGREEN } } )

return nil

}

📌 NOTE: FW\_SayTextHilite takes an array of {cWord, oFont, nTextClr, nBkgClr} for each word to highlight.

17.2 DropFile — Dragging files onto the browse Property / EventTypeDescription and Usage DropFile(nRow, nCol, cFile)MethodHandles dropping a file onto a specific browse cell lCanPasteLogicalEnables the paste option (Ctrl+V) in the browse. Ex: oBrw:lCanPaste := .T.
17.3 Source Code Generation (PrgCode) Property / EventTypeDescription and Usage PrgCode()MethodGenerates the PRG source code of the current browse. Returns array of 4 elements with different styles RptCode()Method (column)Generates report code for the column cColStringOriginal field name of the column (for code generation)
17.4 Navigation Methods (bGoTop, bGoBottom, bSkip) Property / EventTypeDescription and Usage bGoTopBlockBlock to go to the first record. Ex: := {::nArrayAt := 1 } bGoBottomBlockBlock to go to the last record bSkipBlockBlock to skip N records. Receives nSkip, returns records actually skipped bEofBlockBlock that indicates end of data. Ex: := {::nArrayAt \> ::nRows } bKeyCountBlockBlock that returns total records. Ex: := {::nRows } bKeyNoBlockBlock to get/set the current position (KeyNo) bBookMarkBlockBlock to get/set the current record bookmark GoLeft(), GoRight()MethodsNavigate to left/right column. Overridable in derived classes GoUp(\[n\]), GoDown(\[n\])MethodsNavigate rows up/down. Overridable GetDisplayColsWidth()MethodReturns total width of visible columns BrwWidth()MethodReturns the width of the browse data area aCellCoor()MethodReturns coordinates {nTop,nLeft,nBottom,nRight} of active cell SetHScroll(l)MethodShows/hides horizontal scrollbar. Returns the new state lAdjustedLogicalIndicates if CreateFromCode() has already been called (.T. after creation)
18\. Progress Bars in Cells (SetProgBar)

XBrowse allows displaying a progress bar directly within a numeric cell, visualizing the value as a percentage of a given maximum. Ideal for dashboards and queued processes.

Property / EventTypeDescription and Usage SetProgBar(uMax, nHeight, bClr)Method (col)Activates progress bar. uMax=max value (number or block), nHeight=bar height (nil=auto), bClr=block {nFill, nBack} uMax as blockBlock{nMaxSal } — maximum is dynamically recalculated on each paint uMax as numberNumeric100 — fixed percentage, cell value taken as % of 100 RefreshCurrent()MethodRefreshes only current row. Much more efficient than Refresh() in ongoing processes CargoVariousGeneral-purpose property. Ex: oBrw:Cargo := .F. for cancellation signal bClrSelBlockSelected row color without focus. := :bClrSelFocus to equalize both states lDisplayZerosLogicalIf .F., cells with value 0 are displayed empty. Useful at start of progress bars
19\. Advanced Painting (bPaintRow / bPaintHeader / bPaintFooter)

XBrowse exposes painting hooks at the row, header, and full footer level, allowing full visual control using GDI.

19.1 bPaintRow — Painting complete rows Property / EventTypeDescription and Usage bPaintRowBlock{brw,nRow,nCol,nHt,lHL,lSel,nRowPos,nColSel,oColSel... } — row painting hook Return .T.LogicalIf returns .T., XBrowse does not paint that row (the block painted it completely) Return .F.LogicalIf returns .F., XBrowse will paint normally over the block's work GetDC()MethodGets the Device Context of the browse for GDI drawing ReleaseDC()MethodReleases the DC obtained with GetDC() SayText(cText,aRect,cAlign,oFont,nClr)MethodDraws text with the internal browse DC ReadImage(cFile)MethodLoads image from file. Returns handle DrawImage(aBmp, aRect)MethodDraws an image in the indicated rectangle lDrawBorderLogicalIf .T., draws border around the browse nColorBoxNumericMarquee border color. Ex: oBrw:nColorBox := CLR\_HRED lHoverSelectLogicalIf .T., selects the record when hovering the mouse (without clicking) AddVar(cName, xVal)MethodAdds variable accessible within blocks as ::cName oFontObjectBrowse font. Accessible from TDataRow: oRow:oBrw:oFont
19.2 bPaintHeader and bPaintFooter Property / EventTypeDescription and Usage bPaintHeaderBlock{brw,hDC,aCols,nLast,hWPen,hGPen,hCPenBrwHeader(...) } — paints the complete header bPaintFooterBlock{brw,hDC,aCols,nLast,nGridW,nBrwH,hWPen,hGPenBrwFooter(...) } — paints the complete footer oCol:PaintHeader(nRow,nil,nHt,lSel,hDC)Method (col)Paints standard header of ONE column within the custom hook oCol:PaintFooter(nRow,nil,nHt)Method (col)Paints standard footer of ONE column oCol:PaintData(nRow,nil,nHt,lHL,lSel,n,nPos)Method (col)Paints data cell of ONE column — useful in bPaintRow oCol:nDisplayColNumericLeft X position of the column (px from browse left edge) lAllowColSwappingLogicalIf .F., prevents reordering columns by dragging the header
20\. Advanced Editing 20.1 EDIT\_BUTTON — Custom popup editor Property / EventTypeDescription and Usage nEditType := EDIT\_BUTTONConstant (col)Shows button in cell when entering edit mode bEditBlockBlock (col){nRow, nCol, oColEditFunc(nRow,nCol,oCol) } — invoked on button click bOnPostEditBlock (col){oCol, xVal, nKey... } — post-edit. xVal=new value, nKey=confirm key EDIT\_LISTBOXConstant (col)Shows a drop-down listbox as cell editor aEditListTxtArray (col)Items for EDIT\_LISTBOX: { {1,'one',10}, {2,'two',20} } nLbxAtNumeric (col)Index of current selection in aEditListTxt (read-only useful in bOnChange) bClrEditBlock (col)Edit color for ONE column: {{ CLR\_BLACK, CLR\_YELLOW } } bClrEditsBlock (browse)Edit color for ALL browse columns bOnChangeBlock (col)Executed when value changes during editing of that column bOnChangesBlock (browse)Executed when any column changes. Global for the entire browse
20.2 CurrentRow() — Editing in independent dialog Property / EventTypeDescription and Usage CurrentRow()MethodReturns TDataRow object of the current row. Fields accessible as oRow:First, oRow:Salary oRow:Modified()MethodReturns .T. if there are unsaved changes oRow:Save()MethodSaves TDataRow changes to the original source oRow:Undo()MethodDiscards pending changes oRow:oBrwObjectReference to the parent browse. Ex: oRow:oBrw:oFont, oRow:oBrw:Age:cEditPicture ON DBLCLICKClause@ X,Y XBROWSE ... ON DBLCLICK RowEdit( oBrw:CurrentRow() ) DATABASE oObjCommandCreates a TDatabase object from the active area SelectCol(nPos, lCenter)MethodMoves focus to column. lCenter=.T. centers the column in view
21\. Sort Combo (oSortCbx / cSortOrder)

XBrowse can be automatically linked to an external ComboBox so the user can change the display order without additional code.

Property / EventTypeDescription and Usage oSortCbxObjectReference to an external ComboBox. XBrowse fills it with available indexes and changes order on selection cSortOrderStringName of the active order. Can be bound to the ComboBox VAR AUTOSORTClauseEnables sorting by clicking on the column header nColorBoxNumericSelection box color (MARQSTYLE\_SOLIDCELL style). Ex: CLR\_HRED cHeadersArrayArray of headers assigned via code. Ex: oBrw:cHeaders := { "Name", "Last Name" } lExcelCellWiseLogicalIf .T., the Excel export maintains cell-by-cell structure
22\. Swapping Browses, SetRDD and TPages 22.1 Showing/hiding alternate browses Property / EventTypeDescription and Usage Hide()MethodHides the browse without destroying it Show()MethodShows a hidden browse Enable()MethodEnables the browse for user interaction Disable()MethodDisables the browse (no keyboard/mouse response) SetRDD()MethodChanges the RDD data source to the active area at that moment. Ex: Customer-\>( oBrw:SetRDD() ) REDEFINE XBROWSECommandLinks browse from a resource to an object. Ex: REDEFINE XBROWSE oBrw ID 10 OF oDlg
Example: swap with tabs

aBrw\[1\]:CreateFromCode() ; aBrw\[2\]:CreateFromCode()

aBrw\[2\]:Hide() // hide at start

static function ChangeBrw( nNew, nOld, aBrw )

aBrw\[ nOld \]:Hide()

aBrw\[ nNew \]:oWnd:oClient := aBrw\[ nNew \]

aBrw\[ nNew \]:Enable() ; aBrw\[ nNew \]:Show() ; aBrw\[ nNew \]:oWnd:Resize()

return nil

22.2 Browse as page selector (TPages)

@ 10,20 XBROWSE oXBrw DATASOURCE { "First", "Second" } AUTOCOLS HEADERS "Page" NOBORDER

oXBrw:bChange := { || oPages:SetOption( oXBrw:BookMark ) }

oXBrw:CreateFromCode()

oPages := TPages():New( 10, 200, 380, 580, oDlg )

23\. Gradient in Selected Rows

XBrowse supports gradient arrays in selection color blocks, creating Office/Vista-style visual effects.

Property / EventTypeDescription and Usage bClrSelFocus with aGradBlock{{ CLR\_BLACK, aSelGrad } } — gradient in focused row bClrRowFocus with aGradBlock{{ CLR\_BLACK, aRowGrad } } — gradient in visible rows without focus aRowGrad (example)Array{ {.5, RGB(232,241,252), RGB(232,241,252)}, {.5, RGB(210,225,244), RGB(235,243,253)} } aSelGrad (example)Array{ {.5, RGB(255,255,251), RGB(255,237,178)}, {.5, RGB(255,218,103), RGB(255,233,162)} }
24\. Advanced Images — Image \+ Text and SetColsAsRows 24.1 Image and text in the same cell Property / EventTypeDescription and Usage aImgRect := { nil,nil,-40,nil }ArrayReserves 40px at the bottom for text. The image occupies the rest aImgRect := "CIRCLE"StringCircular-shaped image centered in cell aImgRect := "ELLIPSE"StringElliptical-shaped image nCellHeightNumeric (col)Height dedicated to this cell within a multiline row (with SetColsAsRows) SetColsAsRows(aColNos)Method (col)Stacks columns in the same visual cell in separate rows. Ex: :SetColsAsRows( {2,3} ) oDataFontObject (col)Font for the data text of an individual column nDataStrAlign := AL\_TOPNumericAligns text to the top of cell nDataStrAlign := AL\_BOTTOMNumericAligns text to the bottom (useful with image above)
25\. Miscellaneous: UTF-8, Excel, Synchronized DBF Structure 25.1 UTF-8 Support Property / EventTypeDescription and Usage UTF8TOUTF16(field)ExpressionConverts UTF-8 text to UTF-16 for correct display in XBrowse lExcelCellWiseLogicaloBrw:lExcelCellWise := .T. — cell-by-cell Excel export SetFont(oFont)MethodAssigns Unicode font to the browse. Ex: "Segoe UI" for Unicode languages nWidths as numberNumericoBrw:nWidths := 230 — same width for all columns
25.2 Excel sheet browse (oRange)

oRange := GetExcelRange( cFile, "Customers", "A1:E12" )

@ 0,0 XBROWSE oBrw OF oWnd AUTOCOLS DATASOURCE oRange CELL LINES FOOTERS

oBrw:Sales:bFooter := { || oRange:Application:WorkSheetFunction:Sum( oRange:Columns(5) ) }

26\. Insertable Dynamic Subtotals (Array)

It is possible to insert subtotal rows within an array browse, calculated via blocks that are automatically re-evaluated when the user edits data.

Property / EventTypeDescription and Usage IsTotalRow(aRow)Own functionDetects if current row is a subtotal. Ex: Empty( aRow\[1\] ) → is total row bEditWhenBlock (col){\!IsTotalRow( oBrw:aRow ) } — disables editing in subtotal rows bSumConditionBlock (col){n,o\!IsTotalRow( o:oBrw:aRow ) } — excludes subtotal rows from footer total bEditValue with blockBlock (col)If array value is a block ('{...}'), it is evaluated with XEval(). Useful for dynamic subtotals MakeSumBlock(aData,nCol,nFrom,nLast)Own functionCreates a block {FW\_ArrSum(...) } that dynamically sums the indicated range AIns(aData, nPos, xVal, .T.)FunctionInserts an element at position nPos of the array, shifting others FW\_ArrSum(aData, nCol)FWH FunctionSums the values of column nCol from array aData
27\. Transparent Watermark (bPaintBack / lTransparent)

XBrowse allows drawing an image as a semi-transparent watermark behind the data, using the bPaintBack hook and the lTransparent property.

Property / EventTypeDescription and Usage lTransparentLogicalIf .T., the browse uses transparent background (bPaintBack hook controls the background) bPaintBackBlock{Self... } — background painting hook. Self \= the browse. Must paint background and maintain lTransparent := .T. hDCHandle (internal)::hDC — browse Device Context accessible inside bPaintBack oBrush:hBrushHandle::oBrush:hBrush — browse background brush handle DataRect():aRectArrayBrowse data area rectangle. Useful for scaling the watermark image DrawImage(aImage, aRect, nil, nil, nAlpha)MethodDraws image with alpha transparency level (0=opaque, 255=invisible). Ex: nAlpha=64 oWnd:ReadImage(cFile,,lAlpha)MethodReads image with alpha support (.T.). Returns handle for use with DrawImage PalBmpFree(aImage)FunctionFrees memory of image loaded with ReadImage
28\. Advanced XBROWSER: CALC, Internal Buttons and SETUP

The XBROWSER command has additional options for displaying quick-start browses with extended functionality.

Property / EventTypeDescription and Usage XBROWSER aData CALCCommandOpens XBROWSER with a built-in editable spreadsheet (calculator mode) XBROWSER aData COLUMNS {1,2,3}CommandShows only the indicated columns XBROWSER ... SETUP codeblockCommandExecutes a code block after creating the browse. oBrw available as variable BUTTON\_PRINTConstantIndex of the print button in the XBROWSER bar. oBrw:oWnd:aControls\[BUTTON\_PRINT\] BUTTON\_SHEETConstantIndex of the sheet/export button in the XBROWSER bar oBtn:cCaptionStringChanges the button text oBtn:bActionBlockChanges the button action
29\. Exporting Selected Records to Excel (aSelected)

XBrowse allows exporting to Excel only a subset of records by specifying an array of record numbers in the aSelected property before calling ToExcel().

Property / EventTypeDescription and Usage aSelectedArrayArray of RecNos to export. Ex: oBrw:aSelected := { 10, 25, 30 }. Must be cleared after ToExcel() ToExcel()MethodExports browse data to Excel. If aSelected is not empty, exports only those records DBEVAL(bBlock, bCond)FunctionTraverses records of the active area evaluating bBlock only when bCond is .T. cAliasStringAlias of the RDD data source of the browse. Ex: (oBrw:cAlias)-\>( DBEVAL(...) )
Example: export only records from State X

// 1\. Build array of RecNos that meet the condition

local aRecNo := {}

local bCondi := { || (oBrw:cAlias)-\>STATE \== cState }

(oBrw:cAlias)-\>( DBEVAL( { || AAdd( aRecNo, RECNO() ) }, bCondi ) )

// 2\. Position on first matching record and refresh

(oBrw:cAlias)-\>( DBSeek( cState, .T. ) )

oBrw:Refresh()

// 3\. Assign, export and clear

oBrw:aSelected := aRecNo

oBrw:ToExcel()

oBrw:aSelected := {}

Appendix A — Complete Reference Examples

This section contains complete, functional examples extracted directly from the FiveWin/XBrowse example files. They are the most direct reference for implementing each feature.

A.1 Basic browse with RDD, editing and footer (testxbr3.prg)

\#include 'fivewin.ch'

\#include 'xbrowse.ch'

USE CUSTOMER NEW ALIAS CUST SHARED VIA "DBFCDX"

SET ORDER TO TAG FIRST

GO TOP

DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12

DEFINE DIALOG oDlg SIZE 700,400 PIXEL FONT oFont TITLE "XBrowse RDD"

@ 10,10 XBROWSE oBrw SIZE \-10,-10 PIXEL OF oDlg ;

DATASOURCE "CUST" AUTOCOLS AUTOSORT ;

CELL LINES NOBORDER FOOTERS

WITH OBJECT oBrw

:nEditTypes := EDIT\_GET

:Married:SetCheck()

:Salary:nFooterType := AGGR\_SUM

:nStretchCol := STRETCHCOL\_WIDEST

:MakeTotals()

:CreateFromCode()

END

ACTIVATE DIALOG oDlg CENTERED ON INIT ( CUST-\>(dbGoTop()), oBrw:SetFocus(), .F. )

A.2 Array browse with internal button bar (xbrbar.prg)

@ 20,20 XBROWSE oBrw SIZE \-20,200 PIXEL OF oDlg ;

DATASOURCE "STATES" AUTOCOLS CELL LINES NOBORDER

oBrw:nTopBarHeight := 30

oBrw:bOnAdjust := \<||

@ 05,05 BTNBMP oBtn FILE "new.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:EditSource( .T. ) TOOLTIP "Add"

@ 05,45 BTNBMP oBtn FILE "edit.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:EditSource() TOOLTIP "Edit"

@ 05,85 BTNBMP oBtn FILE "delete.bmp" SIZE 30,20 PIXEL OF oBrw NOBORDER ;

Code: Select all | Expand

  ACTION oBrw:Delete() TOOLTIP "Delete"

return nil

\>

oBrw:nEditTypes := EDIT\_GET

oBrw:CreateFromCode()

A.3 Record selector with row number and popup (xbrecsel.prg)

WITH OBJECT oBrw

:nHeaderHeight := 60

:SetChecks()

:bRecSelData := { |brw| brw:KeyNo }

:bRecSelFooter := { |brw| brw:nLen }

:bRecSelHeader := "SlNo"

:bRecSelClick := { || RecSelPopUp( oBrw ) }

:nRecSelWidth := "9999"

:AutoFit()

:CreateFromCode()

END

A.4 Group totals with grand total (xbgrpsum.prg)

WITH OBJECT oBrw

:SetGroupHeader( 'Americas', 2, 3, oBold )

:SetGroupHeader( 'Europe', 4, 5, oBold )

:lAllowColReGroup := .T.

:SetGroupTotal( 'Americas', 'Total' )

:SetGroupTotal( 'Europe', 'Total' )

:SetGroupTotal( { 'Americas\_Total', 'Europe\_Total' }, 'Grand' \+ CRLF \+ 'Total', AGGR\_SUM, oBold )

END

AEval( oBrw:aCols, { |o|

o:cEditPicture := '99,999.99'

o:nFooterType := AGGR\_SUM

o:bOnChange := { || oBrw:MakeTotals(), oBrw:RefreshFooters() } }, 2 )

oBrw:MakeTotals()

oBrw:CreateFromCode()

A.5 Incremental filter with wildcard (xbincflt.prg)

WITH OBJECT oBrw

:lIncrFilter := .T.

:lSeekWild := .T. // search 'contains'

:cFilterFld := "FIRST"

:nStretchCol := STRETCHCOL\_WIDEST

END

@ 10,10 COMBOBOX oBrw:cFilterFld ITEMS aHdrs ;

ON CHANGE ( oBrw:Seek(""), oBrw:SetFocus() )

@ 10,70 COMBOBOX nWild ITEMS { "Starts with", "Contains" } ;

ON CHANGE ( oBrw:lSeekWild := (nWild==2), oBrw:Seek(""), oBrw:SetFocus() )

A.6 Dynamic progress bars with cancellation (xbrprogd.prg)

WITH OBJECT oBrw:aCols\[ 2 \]

:SetProgBar( 100,, { || { RGB(161,224,255), CLR\_WHITE } } )

:cEditPicture := "999.99 %"

:bClrSel := :bClrSelFocus := oBrw:bClrStd

END

oBrw:lDisplayZeros := .F.

oBrw:nStretchCol := 2

oBrw:CreateFromCode()

// Process with row-by-row update:

for n := 1 to oBrw:nLen

nTotal := HB\_RandomInt( 100, 2000 )

oBrw:aArrayData\[ n, 4 \] := nTotal

oBrw:RefreshCurrent()

for i := 1 to nTotal STEP 10

Code: Select all | Expand

  SysWait( 0.01 )

  oBrw:nArrayAt := n

  oBrw:aArrayData\[ n, 2 \] := i / nTotal \* 100

  oBrw:aArrayData\[ n, 3 \] := i

  oBrw:RefreshCurrent()

  if oBrw:Cargo \== .F. ; EXIT ; endif

next

if oBrw:Cargo \== .F. ; EXIT ; endif

next

A.7 Watermark with alpha PNG image (xbwaterm.prg)

aImage := oWnd:ReadImage( "c:\\\\fwh\\\\bitmaps\\\\pngs\\\\logo.png",, .T. ) // .T. \= with alpha

@ 20,20 XBROWSE oBrw ... DATASOURCE "CUSTOMER" AUTOCOLS NOBORDER CELL LINES

WITH OBJECT oBrw

:lTransparent := .T.

:bPaintBack := { |Self|

Code: Select all | Expand

  FillRect( ::hDC, GetClientRect(::hWnd), ::oBrush:hBrush )

  ::DrawImage( aImage, ::DataRect():aRect, nil, nil, 64 ) // 64 \= 25% opaque

  ::lTransparent := .T.

  return nil }

:CreateFromCode()

END

// When done:

PalBmpFree( aImage )

A.8 Dynamic subtotals in array (xbsubtot.prg)

// Subtotal rows: aRow\[1\] empty \= is subtotal

oBrw:bClrStd := { || { CLR\_BLACK, If( Empty(oBrw:aRow\[1\]), CLR\_YELLOW, CLR\_WHITE ) } }

WITH OBJECT oBrw:aCols\[ nCol \]

:bEditValue := { |x,o| If( x==nil .or. ValType(oBrw:aRow\[o:nArrayCol\])=='B',

Code: Select all | Expand

  XEval( oBrw:aRow\[o:nArrayCol\] ),

  oBrw:aRow\[o:nArrayCol\] := x ) }

:bEditWhen := { || \!Empty( oBrw:aRow\[1\] ) }

:bSumCondition := { |n,o| \!Empty( o:oBrw:aRow\[1\] ) }

:bOnChange := { || oBrw:Refresh() }

:nFooterType := AGGR\_SUM

END

// Insert the subtotal row:

AIns( oBrw:aArrayData, nRowLast+1, Array(Len(oBrw:aRow)), .T. )

oBrw:aArrayData\[nRowLast+1, nCol\] := { || FW\_ArrSum( aRows, nCol ) } // dynamic block

A.9 Export filtered records to Excel (xbxlsel.prg)

// Build array of RecNos meeting the condition

local aRecNo := {}

(oBrw:cAlias)-\>( DBEVAL( { AAdd( aRecNo, RECNO() ) }, { STATE \== cState } ) )

(oBrw:cAlias)-\>( DBSeek( cState, .T. ) )

oBrw:Refresh()

// Export only those records

oBrw:aSelected := aRecNo

oBrw:ToExcel()

oBrw:aSelected := {}

A.10 Derived class with column and own behavior (xbrchild.prg)

CLASS MyBrowse FROM TXBrowse

CLASSDATA lRegistered AS LOGICAL

DATA bColClass INIT { || MyXBrCol() }

METHOD New( oWnd ) CONSTRUCTOR

ENDCLASS

METHOD New( oWnd ) CLASS MyBrowse

Super:New( oWnd )

::nMarqueeStyle := MARQSTYLE\_HIGHLROWMS

::bClrStd := { || { CLR\_BLACK, RGB(255,255,206) } }

::bClrSelFocus := { || { CLR\_WHITE, CLR\_BLUE } }

::bClrRowFocus := { || { CLR\_BLACK, RGB(150,231,255) } }

return Self

CLASS MyXbrCol FROM TXBrwColumn

METHOD Adjust()

ENDCLASS

METHOD Adjust() CLASS MyXBrCol

if ::cDataType \== 'D'

Code: Select all | Expand

  ::cEditPicture := 'dd-mmm-yyyy'

endif

Super:Adjust()

return Self

// Specific use:

@ 10,10 XBROWSE oBrw CLASS MyBrowse() OF oDlg ALIAS 'SALES' AUTOCOLS SIZE 200,70 PIXEL

// Global use:

SET XBROWSE TO MyBrowse() SAVE PREVIOUS TO bXBr

regards, saludos

Antonio Linares
www.fivetechsoft.com
Jack
Posts: 307
Joined: Wed Jul 11, 2007 11:06 am

Re: Manual TXBrowse

Post by Jack »

Great,
Philippe

Post Reply