Ultimamente, desarrollando una CLASE propia me han surgido una gran cantidad de problemas, que, por otra parte, me han enseñado muchas cosas nuevas y me han llevado a desarrollar nuevos procedimientos y técnicas de programación. una de esas técnicas es la que me gustaría comentar aquí, pues la veo interesante.
Resulta que en esta famosa/dichosa CLASE quito o pongo un SCROLL según que la cantidad de datos a mostrar en cada momento quepa o no quepa en la amplitud del control.
Significa que, por ejemplo, siempre que pulso una tecla tengo que controlar si el SCROLL está visible o no (existe o no existe). Supone una buena cantidad de líneas como esta:
- Code: Select all Expand view RUN
- IF ::oVSCroll # NIL
::oVSCroll:SetPos( nPos )
ENDIF
- Code: Select all Expand view RUN
- En principio lo solucioné añadiendo un DATA a mi CLASE "::bVSCRoll" que defino como:
::bVSCRoll := { || ::oVSCroll:SetPos( nPos ) } cuando creo el SCROLL
Y como
::bVSCRoll := { || NIL } al inicio de la CLASE o cuando borro el SCROLL.
Así tras programar cada tecla, y en otros sitios hago:
EVAL(::bVSCRoll) y se acabaron los IFs.
Pero resulta que además de esos IFs que enlentecen el programa hay algunos más que se repiten bastante y que quería quitar. Así que he creado un objeto ficticio, y creo que tiene posibilidades en programación. Este sería:
- Code: Select all Expand view RUN
- #include "FiveWin.ch"
CLASS VoidObject
DATA nTop,nLeft,nRight,nBottom AS NUMERIC INIT 0
DATA nWidth,nHeight AS NUMERIC INIT 0
DATA nMin,nMax,nMaxCol AS NUMERIC INIT 0
DATA lReDraw,lCaptured AS LOGICAL INIT .F.
DATA hDc,hCDC,hWnd,oWnd
DATA lVbx
METHOD New()
METHOD Paint() INLINE NIL
METHOD Refresh() INLINE NIL
METHOD Move() INLINE NIL
METHOD SetPos() INLINE NIL
METHOD SetRange() INLINE NIL
METHOD End() INLINE NIL
ENDCLASS
// *******************************************************
METHOD New() CLASS VoidObject
::oWnd := GetWndDefault()
::lVbx := .T.
::hWnd := 0
::hDc := 0
RETURN Self
Ahora:
- Code: Select all Expand view RUN
- Al inicio de la CLASE hago:
::oVSCroll := VoidObject():New()
Cuando tengo que crear el SCROLL, hago:
::oVSCroll := NIL
@ nY,nX SCROLLBAR ::oVSCroll of Self SIZE .....
Y cuando tengo que volver a quitarlo hago:
::oVSCroll := NIL
::oVSCroll := VoidObject():New()
Y ya no necesito ::bVSCRoll.
Ya no tengo que preocuparme de si el SCROLL está presente o no. Si existe, ::oVSCroll:SetPos( nPos ) me posisiona el SCROLL, y si no existe, no hace nada pues hay un método en el objeto ficticio que se llama SetPos() y que devuelve NIL sin más. La cantidad de IFs que me he quitado de encima. Lo único que hay que tener en cuenta es que en el objeto ficticio existan las variables y métodos que vamos a necesitar durante la programación, que no tienen por que ser todos, sólo los que vamos a emplear en algún momento.
Otro problema que me surgió fue: ¿cuándo sé si el SCROLL existe de verdad o es ficticio? Tenía que buscar un DATA que existiese en cualquier CLASE de FWH y se me ocurrió utilizar ::lVbx, que normalmente está en .F. y se utiliza muy muy poco (yo nunca lo he usado). En el objeto ficticio lo defino como .T. y ahora cuando ::lVbx está en .T. sé que es un objeto ficticio y si está en .F. sé que es un objeto de verdad.
Creo que añadiendo algún DATA y unos pocos métodos, este objeto ficticio podría sustituir a más de un objeto, especialmente algún TSAY, TGET, CHECKBOX o RADIOBUTTON que, en un mismo módulo, a veces se ponen y otras no, y que hay que estar constantemente comprobando si están o no presentes.
Ya os iré contando.
Saludos.