FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ejemplo de encabezados
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Ejemplo de encabezados
Posted: Thu Nov 06, 2025 07:59 PM
Saludos al foro:

En un xBrowse es posible tener estas tres líneas de encabezados?, como en la imagen adjunta

Gracias

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ejemplo de encabezados
Posted: Fri Nov 07, 2025 05:59 AM
Revisa FWH\samples\testhead.prg
function TestHeader

   local oWnd, oBrw, oBold
   local cAlias   := cGetNewAlias( 'CUST' )

   USE "..\data\CUSTOMER" NEW SHARED Alias ( cAlias )

   DEFINE FONT oBold NAME 'VERDANA' SIZE 0,-14 BOLD
   DEFINE WINDOW oWnd MDICHILD OF WndMain()

   @ 0, 0 XBROWSE oBrw OF oWnd ;
      COLUMNS 'First', 'Last', 'Street', 'City', 'State', ;
              'Zip',   'HireDate', 'Married', 'Age' ;
      /* HEADERS 'First' + CRLF + 'Name', 'Last' + CRLF + 'Name'*/ ;
      COLSIZES 100,100,100,100 ;
      ALIAS cAlias CELL LINES ;
      FOOTERS AUTOSORT

   WITH OBJECT oBrw
      :SetGroupHeader( 'EMPLOYEE' + CRLF + 'NAME',    1, 2, oBold )
      :SetGroupHeader( 'ADDRESS', 3, 6, oBold )
      :SetGroupHeader( 'OTHER',   8, 9, oBold )
      :Married:SetCheck()
      :nStretchCol   := :Street:nCreationOrder
   END
   AEval( oBrw:aCols, { |o| o:nHeadStrAlign := AL_CENTER } )

   WITH OBJECT oBrw:aCols[ 6 ]
      :AddBmpFile( '..\bitmaps\mail.bmp' )
      :nGrpBmpNo  := 1
   END

   oBrw:bRClicked := { || oBrw:SetGroupHeader( 'CITY', 5, 6, oBold ) }
   oBrw:lAllowColReGroup  := .t.
   oBrw:CreateFromCode()
   oWnd:oClient := oBrw

   ACTIVATE WINDOW oWnd ;
      ON INIT oBrw:SetFocus() ;
      VALID( oBold:End(), .t. )

return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ejemplo de encabezados
Posted: Fri Nov 07, 2025 09:05 AM

El componente xbrowse (clase TXBrowse) soporta múltiples cabeceras a través de dos enfoques principales:

1. Cabeceras de Grupo mediante el Método SetGroupHeader()

El mecanismo principal para múltiples cabeceras es el método SetGroupHeader(), que permite crear cabeceras que abarcan múltiples columnas:

Archivo: source/classes/xbrowse.prg (L519-519)

Code (text): Select all Collapse
   METHOD SetGroupHeader( cGrpHdr, nFrom, nUpto, oFont, nAlign, nHeight )

Este método acepta seis parámetros: el texto de la cabecera de grupo (cGrpHdr), la columna inicial (nFrom), la columna final (nUpto), fuente opcional (oFont), alineación opcional (nAlign) y altura opcional (nHeight). El sexto parámetro para altura personalizada se añadió como una mejora:

Archivo: whatsnew.txt (L2908-2913)

Code (text): Select all Collapse
- GroupHeaders:
  - When group headers are specified, oBrw:nHeaderHeight assigned by the programmer
  was being ignored. Now this value is considered.
  - Sixth parameter nHeight is added to method SetGroupHeader. If specified, this value
  is used for the group header.

Detalles de Implementación:

El sistema de cabeceras de grupo funciona mediante:

  • Establecer la propiedad cGrpHdr en columnas individuales dentro del rango especificado
  • El método CalcHdrHeight() procesa estas cabeceras de grupo y construye la estructura del array aHeaderTop durante la inicialización del browse

Este método detecta cambios en las cabeceras de grupo comparando la propiedad cGrpHdr de cada columna, calcula las alturas apropiadas y almacena la información de grupo en el array aHeaderTop con la estructura: { cGrpHdr, oCol, nStartPos, nEndPos, nHeight, aBitmap }.

Ejemplo de Uso:
Archivo: samples/test/testhead.prg (L51-53)

Code (text): Select all Collapse
      :SetGroupHeader( 'EMPLOYEE' + CRLF + 'NAME',    1, 2, oBold )
      :SetGroupHeader( 'ADDRESS', 3, 6, oBold )
      :SetGroupHeader( 'OTHER',   8, 9, oBold )

2. Cabeceras Multi-línea mediante la Propiedad nHeaderLines

El segundo enfoque utiliza la propiedad nHeaderLines combinada con caracteres CRLF en el texto de la cabecera para crear múltiples líneas dentro de las cabeceras regulares de columna:

Archivo: samples/test/testxbrw.prg (L230-236)

Code (text): Select all Collapse
   oBrw:nHeaderLines        := 2
   oBrw:nDataLines          := 2
   oBrw:SetRDD()

   for nFor := 1 to Fcount()
      oBrw:aCols[ nFor ]:cHeader := "Field: " + ltrim( str( nFor ) ) + CRLF + FieldName( nFor )
   next

Cuando nHeaderLines se establece en un valor mayor que 1, el método CalcHdrHeight() asegura que la altura de la cabecera acomode el número especificado de líneas calculando FontHeight * nHeaderLines.

Archivo: source/classes/xbrowse.prg (L1850-1928)

Code (text): Select all Collapse
METHOD CalcHdrHeight() CLASS TXBrowse

   local nFor, nLen, nCol, oCol, nHeight
   local cGrpHdr
   local aGroup

   if HB_ISNUMERIC( ::nHeaderHeight ) .and. ::nHeaderHeight < 1
      ::nHeaderHeight := 1
   endif

   if ::lHeader //.and. ::nHeaderHeight == nil
      nLen           := Len( ::aCols )
      nHeight        := 0
      ::aHeaderTop   := {}
      if ::lGrpHeader == nil
         ::lGrpHeader   := .f.
         for nFor := 1 to nLen
            if ! Empty( ::aCols[ nFor ]:cGrpHdr )
               ::lGrpHeader := .t.
            endif
         next
      endif
      if ::lGrpHeader .or. ::nHeaderHeight == nil
         if ::lGrpHeader
            nHeight     := 0
            for nFor := 1 to nLen
               oCol     := ::aCols[ nFor ]
               if oCol:cGrpHdr != cGrpHdr
                  if aGroup != nil
                     AAdd( ::aHeaderTop, aGroup )
                     for nCol := aGroup[ 3 ] to aGroup[ 4 ]
                        ::aCols[ nCol ]:nGrpHeight := aGroup[ 5 ]
                     next
                     aGroup  := nil
                  endif
                  cGrpHdr     := oCol:cGrpHdr
                  if ! Empty( oCol:cGrpHdr )
                     // new group starts
                     aGroup      := { oCol:cGrpHdr, oCol, nFor, nFor, oCol:HeaderHeight( .t. ), ;
                                      oCol:aBitmap( oCol:nGrpBmpNo ) }
                  endif
               else
                  // same group or nogroup
                  if ! Empty( oCol:cGrpHdr )
                     aGroup[ 2 ]      := oCol
                     aGroup[ 4 ]      := nFor
                     aGroup[ 5 ]      := Max( aGroup[ 5 ], oCol:HeaderHeight( .t. ) )
                     if ! Empty( oCol:nGrpBmpNo )
                        aGroup[ 6 ]    := oCol:aBitmap( oCol:nGrpBmpNo )
                     endif
                  endif
               endif
            next
            if aGroup != nil
               AAdd( ::aHeaderTop, aGroup )
               for nCol := aGroup[ 3 ] to aGroup[ 4 ]
                  ::aCols[ nCol ]:nGrpHeight := aGroup[ 5 ]
               next
               aGroup  := nil
            endif
         endif

         for nFor := 1 to nLen
            nHeight  := Max( nHeight, ::aCols[ nFor ]:HeaderHeight() )
         next
//         DEFAULT ::nGetBarHeight   := FontHeight( Self, IfNil( ::oFont, ::oWnd:oFont ) ) + 8
         if ::nHeaderLines > 1
            nHeight  := Max( nHeight, FontHeight( Self, ::oWnd:oFont ) * ::nHeaderLines )
         endif
         nHeight  := nHeight + ROW_EXTRAHEIGHT + 3 // lines to give 3d look
         if ::nHeaderHeight != nil
            nHeight  := Max( ::nHeaderHeight, nHeight )
         endif
         ::nHeaderHeight   := nHeight

      endif
   endif

return ::nHeaderHeight

Notas

  • Cabeceras de Grupo son ideales para agrupar visualmente columnas relacionadas bajo cabeceras de categoría comunes (por ejemplo, agrupar columnas "Nombre" y "Apellido" bajo una cabecera "NOMBRE DEL EMPLEADO")
  • Cabeceras Multi-línea son más adecuadas para envolver títulos de columna largos o agregar texto descriptivo debajo de los nombres de columna
  • Ambos enfoques pueden usarse juntos en el mismo browse
  • La propiedad lAllowColReGroup habilita la reagrupación de columnas en tiempo de ejecución para cabeceras de grupo
  • Las cabeceras de grupo soportan fuentes personalizadas, alineación, bitmaps y alturas para una presentación visual mejorada
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: Ejemplo de encabezados
Posted: Sat Nov 08, 2025 05:45 PM

de cosas que se entera uno y no sabemos
gracias Maestro Linares :D

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ejemplo de encabezados
Posted: Sat Nov 08, 2025 06:11 PM

Maestro Antonio:

Revise tus sugerencia pero seguramente no las entendí, lo que busco son tres líneas de encabezado

SuperGroupHeader() GroupHeader() Header()

Las dos últimas líneas las tengo claras de como definirlas pero me falta el SuperGroupHeader que abarque dos o mas GroupHeader

Espero haberme dado a entender

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ejemplo de encabezados
Posted: Sun Nov 09, 2025 08:45 AM

Armando,

headers.prg

#include "FiveWin.ch"

function Main()

   local aData := { { 10000, 235000, 90, 2115 } }

   XBROWSER aData SETUP BrwSetup( oBrw )

return nil

function BrwSetup( oBrw )

   oBrw:SetGroupHeader( 'DIESSEL' + CRLF + "COMPRAS" + Space( 28 ) + "CONSUMOS", 1, 4 )
   oBrw:aCols[ 1 ]:cHeader = "Litros"
   oBrw:aCols[ 2 ]:cHeader = "Importe"
   oBrw:aCols[ 3 ]:cHeader = "Litros"
   oBrw:aCols[ 4 ]:cHeader = "Importe"

return nil

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ejemplo de encabezados
Posted: Wed Nov 12, 2025 02:57 AM

Master:

Excelente !, lo voy a probar.

Muchas gracias

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero

Continue the discussion