Quique,
Me dejastes pensando con esto que comentastes:
> con la gran ventaja de poder hacer llamado a la original, algo así como si fuera un método de la clase superior
Y he jugado un poco con el asunto, creando la Clase TFunction
Ojo, este código solo sirve para Harbour, ya que xHarbour usa un tipo distinto para @name(), asi que habría que modificarlo para xHarbour. Mis saludos a Vic y nuestra invitación a visitarnos
test.prg
Code: Select all
#include "FiveWin.ch"
function Main()
local oTime := TFunction():New( @Time() )
local oMyTime := TFunction():New( @MyTime() )
MsgInfo( oTime:Exec() )
oTime:Swap( oMyTime )
MsgInfo( Time() )
MsgInfo( oTime:Original() )
oTime:Restore()
MsgInfo( Time() )
return nil
function MyTime()
return "now"
CLASS TFunction
DATA pFunction
DATA hPointer
METHOD New( pFunction )
METHOD Exec() INLINE HB_ExecFromArray( ::pFunction, HB_aParams() )
METHOD Swap( oFunction ) INLINE FunSwap( ::pFunction, oFunction:pFunction )
METHOD Restore() INLINE FunRestore( ::pFunction, ::hPointer )
METHOD Original() INLINE HB_ExecFromArray( GenSymbol( @FunDummy(), ::hPointer ), HB_aParams() )
ENDCLASS
METHOD New( pFunction ) CLASS TFunction
::pFunction = pFunction
::hPointer = FunPtr( pFunction )
return Self
#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapiitm.h>
#include <hbstack.h>
#include <windows.h>
HB_FUNC( FUNPTR )
{
PHB_ITEM pFunction = hb_param( 1, HB_IT_SYMBOL );
hb_retnl( ( LONG ) ( pFunction ? hb_itemGetSymbol( pFunction )->value.pFunPtr : 0 ) );
}
HB_FUNC( FUNSWAP )
{
PHB_ITEM pFirst = hb_param( 1, HB_IT_SYMBOL );
PHB_ITEM pLast = hb_param( 2, HB_IT_SYMBOL );
if( pFirst && pLast )
{
hb_itemGetSymbol( pFirst )->value.pFunPtr = hb_itemGetSymbol( pLast )->value.pFunPtr;
}
}
HB_FUNC( FUNRESTORE )
{
PHB_ITEM pFunction = hb_param( 1, HB_IT_SYMBOL );
PHB_SYMB pSymbol = hb_itemGetSymbol( pFunction );
if( pSymbol )
pSymbol->value.pFunPtr = ( void * ) hb_parnl( 2 );
}
HB_FUNC( GENSYMBOL )
{
PHB_SYMB pSymbol = hb_dynsymSymbol( hb_dynsymFindName( "FUNDUMMY" ) );
pSymbol->value.pFunPtr = ( void * ) hb_parnl( 2 );
hb_itemPutSymbol( hb_stackReturnItem(), pSymbol );
}
HB_FUNC( FUNDUMMY )
{
}
#pragma ENDDUMP