Page 1 of 1

Ejemplo de encabezados

Posted: Thu Nov 06, 2025 7:59 pm
by Armando
Saludos al foro:

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

Gracias

Image

Re: Ejemplo de encabezados

Posted: Fri Nov 07, 2025 5:59 am
by Antonio Linares
Revisa FWH\samples\testhead.prg

Code: Select all | Expand

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

Re: Ejemplo de encabezados

Posted: Fri Nov 07, 2025 9:05 am
by Antonio Linares

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: Select all | Expand

   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: Select all | Expand

- 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: Select all | Expand

      :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: Select all | Expand

   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: Select all | Expand

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

Re: Ejemplo de encabezados

Posted: Sat Nov 08, 2025 5:45 pm
by sysctrl2

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


Re: Ejemplo de encabezados

Posted: Sat Nov 08, 2025 6:11 pm
by Armando

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


Re: Ejemplo de encabezados

Posted: Sun Nov 09, 2025 8:45 am
by Antonio Linares

Armando,

headers.prg

Code: Select all | Expand

#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   

Image


Re: Ejemplo de encabezados

Posted: Wed Nov 12, 2025 2:57 am
by Armando

Master:

Excelente !, lo voy a probar.

Muchas gracias