Page 1 of 2

Bug en los operadores fwh2409 xharbour 64 bits (solucionado)

Posted: Thu Jan 16, 2025 11:38 pm
by leandro
Hola buenas tardes para todos, nos hemos encontrado con el problema que, en algunas ocasiones, xbrowse nos pinta ********* en algunos valores, no sabemos por qué se genera, no es siempre, como pueden ver en la imagen, se presenta en la columna Salario Devengado, es el mismo valor que está en la columna Salario Básico, pero en esta muestra los asteriscos, realmente esta super extraño.

Image

Esta es la manera como definimos el xbrowse

El problema empezó a suceder cuando compilamos la aplicación con FW2409_64 bits, hicimos la prueba con la versión anterior en 32 bits y no se generar el inconveniente.

Code: Select all | Expand

	@ 100, 5 XBROWSE oBrw ;
	SIZE 385 ,160 OF oSelf:oDlgSpt PIXEL ;
	LINES STYLE FLAT NOBORDER ;
	DATASOURCE ::aRspNm AUTOCOLS 

	ReArrangeCols( oBrw, ::aCols1 )

	WITH OBJECT oBrw
		:lRecordSelector 		:= .T.
		:lHScroll        	:= .T.
		:lVScroll        	:= .T.
		:l2007           	:= .F.
		:lFitGridHeight  		:= .T.
		:nHeaderHeight   		:= 21
		:nRowHeight      	:= 21
		:nMarqueeStyle   		:= MARQSTYLE_HIGHLROW
		:lColDividerComplete 	:= .t.
		:nColorPen       	:= CLR_HGRAY
		:lFullGrid       	:= .T.
		:nStretchCol        	:= STRETCHCOL_LAST
		:bClrHeader      	:= { || { CLR_WHITE, oLamcla:nClrBrwCab, CLR_HGRAY } }
		:lFooter         	:= .t.
		:nFooterLines    		:= 1
		:nFooterHeight   		:= 25
		:nFreeze		 		:= 4
		//:bRClicked 	       	:= {|nRow, nCol | if(!::lNueva,::mRegNomi( nRow,nCol,oBrw, cbModi, cbEnv, cnImpPg, cbNaj, cbAgre, cnEDian, cbBrCmp, cbElm, ::aRspNm[oBrw:nArrayAt]["rfidnm"] ),) }
		:bRClicked 	       	:= {|nRow, nCol | ::mRegNomi( nRow,nCol,oBrw, cbModi, cbEnv, cnImpPg, cbNaj, cbAgre, cnEDian, cbBrCmp, cbElm, ::aRspNm[oBrw:nArrayAt]["rfidnm"] ) }
		:bKeyDown 	       	:= {|nKey,oGet,nCol|::TecItemNomi(nKey,oGet,nCol, cbModi, cbEnv, cnImpPg, cbNaj, cbAgre, cnEDian, cbGraba, cbElm, ::aRspNm[oBrw:nArrayAt]["rfidnm"])}
		:nRecSelColor        	:= RGB( 255, 255, 255 )

		:bClrStd   			:= {|| if(Len( ::aRspNm ) > 0 , ;
								{ CLR_BLACK,clrEstFondo(::aRspNm[oBrw:nArrayAt]["estado"]) } ,;
								{ CLR_BLACK,clrEstFondo("S") } ) }	
		:bClrSelFocus 		:= {|| if(Len( ::aRspNm ) > 0 , ;
								{ CLR_WHITE,clrEstSelec(::aRspNm[oBrw:nArrayAt]["estado"]) } ,;
								{ CLR_WHITE,clrEstSelec("S") }) }		
		:SetFont( oFont1Cja )
		
	END

	WITH OBJECT oBrw

		//Colocamos los titulos a las columnas
		FOR j:=1 TO len(::aColTt)
			:aCols[j]:cHeader  := ::aColTt[j]
			:aCols[j]:oHeaderFont = oFontCja	
		NEXT 

		//Ahora las especiales
		:aCols[2]:cFooter      = "Nro.Comp » "+alltrim(transform(len(::aRspNm),oLamcla:PIC3))
		:aCols[2]:oFooterFont := oFontCja

		:aCols[3]:cFooter      = "TOTALES »"
		:aCols[3]:oFooterFont := oFontCja
		
		:aCols[6]:bClrStd    		:= {|| { _CLR_GRIS, if(Len( ::aRspNm ) > 0 , colorEstado2_nm( ::aRspNm[oBrw:nArrayAt]["estado"] , ::aRspNm[oBrw:nArrayAt]["rfidnm"] ),) }  }
		:aCols[6]:bClrSelFocus	:= {|| { CLR_WHITE,if(Len( ::aRspNm ) > 0 ,colorEstado_nm( ::aRspNm[oBrw:nArrayAt]["estado"] , ::aRspNm[oBrw:nArrayAt]["rfidnm"] ),) }  }
		:aCols[6]:bStrData 		:= { || if(Len( ::aRspNm ) > 0 , nombreEstado_nm( ::aRspNm[oBrw:nArrayAt]["estado"] ) , ::aRspNm[oBrw:nArrayAt]["rfidnm"] ) }
	
		:aCols[nColDev]:oFooterFont := oFontCja
		:aCols[nColDev]:bClrStd      = {|| {Rgb(55,55,55),nRGB(212,212,212) }  }
		:aCols[nColDev]:bClrSelFocus = {|| {CLR_WHITE,nRGB(139,139,139) }  }
		
		:aCols[nColDed]:oFooterFont := oFontCja
		:aCols[nColDed]:bClrStd      = {|| {Rgb(55,55,55),nRGB(255,187,187) }  }
		:aCols[nColDed]:bClrSelFocus = {|| {CLR_WHITE,nRGB(255,117,117) }  }

		:aCols[nColPag]:oFooterFont := oFontCja
		:aCols[nColPag]:bClrStd      = {|| {Rgb(55,55,55),nRGB(187,255,187) }  }
		:aCols[nColPag]:bClrSelFocus = {|| {CLR_WHITE,nRGB(0,210,0) }  }
		
		//Colocamos los totales en donde sea necesario
		//y tambien ajustamos el ancho de las columnas
		FOR i:=1 TO len(::aColTl)
			if ::aColTl[i] 
				:aCols[i]:nFooterType  := AGGR_SUM
				:aCols[i]:cFooterPicture := oLamcla:PIC7
				:aCols[i]:cEditPicture := oLamcla:PIC7
				:aCols[i]:oFooterFont := oFontCja
			endif
			:aCols[i]:nWidth = ::aColAn[i]	
		NEXT
		
		:MakeTotals()
		
		//Dejamos fija la columna en la derecha
		:oRightCol     := :aCols[nColPag]

	END

	oBrw:CreateFromCode()

Re: Bug en los pictures de xbrowse, creo

Posted: Fri Jan 17, 2025 1:51 pm
by leandro
Bueno parece que no es el xbrowse :oops: :oops:

Se me hace que pueden ser los hash; en este caso, cuando cambiamos de 29 a 30 días laborados, salen los asteriscos, notamos que también en el get salen los asteriscos.

Voy a intentar reproducir el error en un exe externo, estaré comentando si encuentro solución o más preguntas.

Image

Image

Re: Bug en los pictures fw2409 64 bits (hash / xbrowse ?)

Posted: Fri Jan 17, 2025 2:36 pm
by leandro
Bueno logramos reproducir el error y parece que no es ni el xbrowse, ni los hash, ahora si no tengo ni idea que pueda ser :shock:

Cuando hacemos la multiplicación por 29 días, funciona correctamente
Image

pero cuando la hacemos por 30 días, tenga sus asteriscos jejejejeje
Image

Tambien notamos que, si hacemos la división por 60, también arroja los asteriscos.
Image

El codigo es tan sencillo como esto:

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

Local nSalario := 2032212
Local nDias := 30 //Si lo cambiamos a 30 salen los asteriscos
Local nTotal := (nSalario/30) * nDias

msginfo(nTotal)

return nil



Re: Bug en los operadores fw2409 64 bits

Posted: Fri Jan 17, 2025 3:03 pm
by leandro
Bueno, parece que el problema es en 64 bits, creamos el mismo ejemplo en 32 bits y funciona correctamente.

Image

Re: Bug en los operadores fw2409 64 bits

Posted: Fri Jan 17, 2025 3:03 pm
by karinha
Leandro, prueba:

Code: Select all | Expand

// Testing GETs - C:\FWH..\SAMPLES\TESTGET.PRG y TESTGET.RC

#include "FiveWin.ch"

FUNCTION Main()

   LOCAL oDlg, oGet, oGet2, oGet3, oGet4
   LOCAL cCad := "Testing    " // pad("Testing Gets",40)
   LOCAL cText := "                "
   LOCAL nNum := 0
   LOCAL dDat := Date()
   LOCAL nSalario := 2032212
   LOCAL nDias    := 30 // Si lo cambiamos a 30 salen los asteriscos
   LOCAL nTotal   := 0
   LOCAL nTotSal  := nSalario / 30

   nTotal := nTotSal * nDias   // Aqui Leandro, prueba.

   nNum   := nTotal

   SET CENTURY ON
   SET DATE BRITISH
   SET TIME FORMAT TO "HH:MM:SS"
   SET EPOCH TO YEAR( DATE() ) - 30
   SET SOFTSEEK OFF
   SET WRAP ON
   SETCANCEL( .F. )
   SET CONFIRM ON
   SET DELETED ON
   SET _3DLOOK ON
   SET UNIQUE OFF
   SET ESCAPE OFF
   SET EXACT ON       // CONTROLA O :=, = e ==
   SET EXCLUSIVE OFF
   SET MULTIPLE OFF
   SET OPTIMIZE ON

   DEFINE DIALOG oDlg TITLE "TGet from " + FWDESCRIPTION

   oDlg:lHelpIcon := .F.

   @ 1,    2 SAY "Text..:" OF oDlg

   @ 1,    6 GET oGet VAR cCad OF oDlg SIZE 60, 10 COLOR "W/G" PICTURE "@K" ;
      PLACEHOLDER "CueBanner" // NO FUNCIONA.

   @ 1.8,  2 SAY "Salario:" OF oDlg

   @ 2,    6 GET oGet2 VAR nNum OF oDlg SIZE 60, 12 PICTURE "@E 9,999,999,999.99" RIGHT

   @ 2.6,  2 SAY "Date:" OF oDlg

   @ 3,    6 GET oGet3 VAR dDat PICTURE "@D 99/99/9999" OF oDlg SIZE 60, 10 CENTER

   @ 4,    2 SAY "Text..:" OF oDlg

   @ 4,    6 GET oGet4 VAR cText PICTURE "@!" OF oDlg SIZE 80, 10   ;
      PLACEHOLDER "CueBanner" // FUNCIONA.

   @ 4,    7 BUTTON "&Ok" OF oDlg SIZE 30, 12 ACTION oDlg:End()
   @ 4,   16 BUTTON "&Cancel" SIZE 30, 12 OF oDlg ACTION oDlg:End() CANCEL

   TGet():SetColorFocus( nRGB( 200, 120, 120 ) )

   ACTIVATE DIALOG oDlg CENTERED

   SET CONFIRM OFF

RETURN NIL

// ------------------------------------------------------------------------//

PROCEDURE appsys // XBase++ requirement
RETURN

/*
// TESTGET.RC
#ifndef __64__
  1 24 "C:\FWH\SAMPLES\winxp\WindowsXP.Manifest"
#endif

#ifdef __64__
  1 24 "winxp\WindowsXP.Manifest64"
#endif

*/
Regards, saludos.

Re: Bug en los operadores xharbour 64 bits

Posted: Fri Jan 17, 2025 3:12 pm
by leandro
Joao gracias por responder

Mismo error

No tiene que ver con los pictures y parece ser que el problema es a 64 bits

Image

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Fri Jan 17, 2025 3:25 pm
by karinha
Realmente hay un error en el TGET.PRG del FWH de 64 bits, en 32 bits funciona perfectamente.

Regards, saludos.

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Fri Jan 17, 2025 10:30 pm
by Enrico Maria Giordano
I confirm the problem but only with xHarbour/BCC64 (with Harbour it works fine). I have no clue about the cause. Any ideas?

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sat Jan 18, 2025 8:46 am
by Enrico Maria Giordano
This is a minimal sample (console, no FWH, the problem is only with xHarbour/BCC64):

Code: Select all | Expand

FUNCTION MAIN()

    ? 2032212 / 30 * 30

    INKEY( 0 )

    RETURN NIL

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sat Jan 18, 2025 11:31 pm
by Antonio Linares
When we compile Enrico's example we get this pcode:

HB_P_PUSHDOUBLE, 255, 255, 255, 255, 83, 2, 63, 65, 255, 255, /* 2032212.000000000000000000000000000000000, 255, 255 */

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sat Jan 18, 2025 11:37 pm
by Antonio Linares
Harbour generates the double this way:

Code: Select all | Expand

         case HB_P_PUSHDOUBLE:
            hb_vmPushDoubleConst( HB_PCODE_MKDOUBLE( &pCode[ 1 ] ),
                                  ( int ) *( const unsigned char * ) &pCode[ 1 + sizeof( double ) ],
                                  ( int ) *( const unsigned char * ) &pCode[ 2 + sizeof( double ) ] );
            pCode += 3 + sizeof( double );
            break;
xHarbour this way:

Code: Select all | Expand

         case HB_P_PUSHDOUBLE:
            HB_TRACE( HB_TR_DEBUG, ( "HB_P_PUSHDOUBLE" ) );

            hb_vmPushDoubleConst( HB_PCODE_MKDOUBLE( &pCode[ w + 1 ] ),
                                  ( int ) *( BYTE * ) &pCode[ w + 1 + sizeof( double ) ],
                                  ( int ) *( BYTE * ) &pCode[ w + 1 + sizeof( double ) + sizeof( BYTE ) ] );

            w += 1 + sizeof( double ) + sizeof( BYTE ) + sizeof( BYTE );
            break;

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sat Jan 18, 2025 11:45 pm
by Antonio Linares
Harbour's implementation:

Code: Select all | Expand

static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec )
{
   HB_STACK_TLS_PRELOAD
   PHB_ITEM pItem = hb_stackAllocItem();

   HB_TRACE( HB_TR_DEBUG, ( "hb_vmPushDoubleConst(%lf, %d, %d)", dNumber, iWidth, iDec ) );

   pItem->type = HB_IT_DOUBLE;
   pItem->item.asDouble.value = dNumber;

   if( iDec == HB_DEFAULT_DECIMALS )
      pItem->item.asDouble.decimal = ( HB_USHORT ) hb_stackSetStruct()->HB_SET_DECIMALS;
   else
      pItem->item.asDouble.decimal = ( HB_USHORT ) iDec;

   if( iWidth == HB_DEFAULT_WIDTH )
      pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber );
   else
      pItem->item.asDouble.length = ( HB_USHORT ) iWidth;
}
xHarbour's implementation:

Code: Select all | Expand

static void hb_vmPushDoubleConst( double dNumber, int iWidth, int iDec )
{
   HB_THREAD_STUB
   PHB_ITEM pItem;

   HB_TRACE( HB_TR_DEBUG, ( "hb_vmPushDoubleConst(%lf, %d, %d)", dNumber, iWidth, iDec ) );

   pItem                      = hb_stackAllocItem();
   pItem->type                = HB_IT_DOUBLE;
   pItem->item.asDouble.value = dNumber;

   if( iDec == HB_DEFAULT_DECIMALS )
      pItem->item.asDouble.decimal = hb_stackSetStruct()->HB_SET_DECIMALS;
   else
      pItem->item.asDouble.decimal = ( UINT ) iDec;

   if( iWidth == HB_DEFAULT_WIDTH )
      pItem->item.asDouble.length = ( UINT ) HB_DBL_LENGTH( dNumber );
   else
      pItem->item.asDouble.length = ( UINT ) iWidth;
}

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sun Jan 19, 2025 7:19 am
by Antonio Linares
If we code:

? 2032212
then we get:
HB_P_PUSHLONG, 84, 2, 31, 0, /* 2032212 */

As soon as we divide it then we get a double:
? 2032212 / 30
HB_P_PUSHDOUBLE, 102, 102, 102, 102, 198, 137, 240, 64, 255, 255, /* 67740.40000000000000000000000000000000000, 255, 255 */

In this case, dividing and multiplying for the same number, we also get a double:
? 2032212 / 30 * 30
HB_P_PUSHDOUBLE, 255, 255, 255, 255, 83, 2, 63, 65, 255, 255, /* 2032212.000000000000000000000000000000000, 255, 255 */

If we multiply before and divide later, we don't get a double:
? 2032212 * 30 / 30
HB_P_PUSHLONG, 84, 2, 31, 0, /* 2032212 */

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sun Jan 19, 2025 7:43 am
by Antonio Linares
With this simple test we can check that the double number is properly storadge inside the xHarbour item:

Code: Select all | Expand

FUNCTION MAIN()

    ? Test( 2032212 / 30 * 30 )

    INKEY( 0 )

    RETURN NIL

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>
#include <stdio.h>

HB_FUNC( TEST )
{
   char buffer[ 50 ];
   double number = hb_parnd( 1 );
   sprintf( buffer, "%f", number );
   OutputDebugString( buffer ); 
   hb_retnd( number );
}

#pragma ENDDUMP
Image

Re: Bug en los operadores fwh2409 xharbour 64 bits

Posted: Sun Jan 19, 2025 8:04 am
by Antonio Linares
Checking where the error may come from:

Code: Select all | Expand

function Main()

   Test( 2032212 / 30 * 30, 50, 2 )

return nil

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>
#include <hbapiitm.h>
#include <stdio.h>

HB_FUNC( TEST )
{
   OutputDebugString( hb_itemStr( hb_param( 1, HB_IT_DOUBLE ), 
                                  hb_param( 2, HB_IT_NUMERIC ), hb_param( 3, HB_IT_NUMERIC ) ) );
}

#pragma ENDDUMP