Muy acertada la idea de Antonio de que el uso de tecnolog铆as como XML son obligatorias. Con ese criterio mismo no habr铆a que dejar de lado
a la POO. Se me ocurre que el modelo soluci贸n ser谩 que el IDE producir谩 c贸digo XML, que contendr谩 la informaci贸n que hasta ahora
producimos con editores de recursos, y a esto se a帽adir谩 la informaci贸n propia de los aspectos propios de nuestra aplicaci贸n,
incluyendo detalles respecto de los controles, variables y las acciones asociadas a los eventos que se producen en el di谩logo.
Si el IDE producir谩 codigo XML, habr谩 un procesador que transforme ese XML en c贸digo xBase o C, y que se vincular谩 de alguna manera
con el c贸digo que nosotros escribamos en el PRG.
Este modelo coincide bastante con lo que plantea Vladimir, a lo que propondr铆a algunos agregados que me parece que ayudar铆an a controlar mejor el c贸digo.
Mirando los IDEs actuales, todos manejan m谩s o menos los mismos conceptos, es decir, una parte del c贸digo sobre la que act煤a el IDE y otra independiente con el c贸digo que escribimos, normalmente asociado a los eventos que se producen en el dialogo/ventana/formulario.
Si a partir del XML generamos una clase, subclase de Dialog/Windows/Form, que implementa los aspectos visuales, podemos
escribir una sublase con nuestro propio c贸digo implementando los eventos.
Esto es lo que hacen muchos IDEs, desde Visual Objects hasta Delphi, y es bastante simple de implementar y usar. Tiene la ventaja de que las variables tanto de los controles como de buffers de edici贸n son declaradas en la clase, por lo que nuestros m茅todos siempre tienen acceso a ellas ( como se dice, "siempre est谩n en 谩mbito" ) y no hay que declarar variables ni cosas extra帽as, ni es necesaria andar haciendo b煤squedas de controles por nombre ni cosas parecidas.
En la misma superclase el compilador de XML generar谩 el codigo de la clase, incluyendo no solo las DATAs sino tambien declarar谩 los m茅todos, aunque los declare de manera virtual. Eso ayuda en el prototipado r谩pido, y permitir铆a testear la clase sin haber escrito una sola l铆nea de c贸digo.
Por ejemplo, supongamos que el IDE produce el siguiente c贸digo XML:
prueba.xml
<FORM>
</NAME:TIPOIVA>
</NTOP:6>
</NLEFT:18>
</NHEIGHT:212>
</NWIDTH:140>
</STYLE: WS_POPUP|DS_MODALFRAME|DS_3DLOOK|WS_CAPTION|WS_SYSMENU|WS_VISIBLE >
</CAPTION: "Tipos de IVA" >
<CONTROLS>
<STATIC>
</NAME: oSayCodigo >
</TEXT:"C贸digo">
</STYLE: WS_GROUP>
</NTOP:10>
</NLEFT:12>
</NHEIGHT:8>
</NWIDTH:44>
</STATIC>
<STATIC>
</NAME: oSayDescrip >
</TEXT:"Descripci贸n">
</STYLE: WS_GROUP>
</NTOP:25>
</NLEFT:12>
</NHEIGHT:8>
</NWIDTH:44>
</STATIC>
<TGET>
</NAME:oGetTipo>
</VAR:TIPO>
</INIT: 0 >
</PICTURE:"99">
</STYLE: ES_RIGHT|WS_BORDER|WS_TABSTOP>
</NTOP:8>
</NLEFT:68>
</NHEIGHT:12>
</NWIDTH:36>
</VALID:ValidaTipo>
</TGET>
<TGET>
</NAME:oGetDescrip>
</VAR:DESCRIP>
</INIT: " " >
</STYLE: WS_BORDER|WS_TABSTOP>
</NTOP:23>
</NLEFT:68>
</NHEIGHT:12>
</NWIDTH:132>
</VALID:ValidaDescrip>
</TGET>
<TBUTTON>
</NAME:oBtnAceptar>
</TEXT:"&Aceptar">
</NTOP:117>
</NLEFT:101>
</NHEIGHT:15>
</NWIDTH:45>
</ACTION:Aceptar>
</TBUTTON>
<TBUTTON>
</NAME:oBtnCancel>
</TEXT:"&Cancelar">
</NTOP:154>
</NLEFT:101>
</NHEIGHT:15>
</NWIDTH:45>
</ACTION:Cancel>
</TBUTTON>
</CONTROLS>
</FORM>
Con esto un programa deber铆a generar un c贸digo parecido a:
prueba.frm
CLASS _TIPOIVA // FROM 驴TFORM?
DATA Form
DATA oSayCodigo
DATA oSayDescrip
DATA oGetCodigo
DATA TIPO
DATA oGetDescrip
DATA DESCRIP
DATA oBtnAceptar
DATA oBtnCancel
METHOD New()
METHOD ValidaTipo() VIRTUAL // Valida un control
METHOD ValidaDescrip() VIRTUAL // Valida otro control
METHOD Aceptar() VIRTUAL // Accion asociada a un boton
METHOD Cancel() VIRTUAL // idem
END CLASS
METHOD New() CLASS _TIPOIVA
/*
</NTOP:6>
</NLEFT:18>
</NHEIGHT:212>
</NWIDTH:140>
</STYLE: WS_POPUP|DS_MODALFRAME|DS_3DLOOK|WS_CAPTION|WS_SYSMENU|WS_VISIBLE >
</CAPTION: "Tipos de IVA" >
*/
@ 6, 18 DIALOG ::Form SIZE 140, 212 CAPTION "Tipos de IVA" STYLE WS_POPUP|DS_MODALFRAME|DS_3DLOOK|WS_CAPTION|WS_SYSMENU|WS_VISIBLE
/*
<STATIC>
</NAME: oSayCodigo >
</TEXT:"C贸digo">
</STYLE: WS_GROUP>
</NTOP:10>
</NLEFT:12>
</NHEIGHT:8>
</NWIDTH:44>
</STATIC>
*/
@ 10, 12 SAY ::oSayCodigo PROMPT "C贸digo" ...
.... m谩s controles
/*
<TGET>
</NAME:oGetTipo>
</VAR:TIPO>
</INIT: 0 >
</PICTURE:"99">
</STYLE: ES_RIGHT|WS_BORDER|WS_TABSTOP>
</NTOP:8>
</NLEFT:68>
</NHEIGHT:12>
</NWIDTH:36>
</VALID:ValidaTipo>
</TGET>
*/
@ 8, 68 GET ::oGetTipo VAR ::TIPO PICTURE "99" STYLE ES_RIGHT|WS_BORDER|WS_TABSTOP VALID ::ValidaTipo()
... mas controles
/*
<TBUTTON>
</NAME:oBtnAceptar>
</TEXT:"&Aceptar">
</NTOP:117>
</NLEFT:101>
</NHEIGHT:15>
</NWIDTH:45>
</ACTION:Aceptar>
</TBUTTON>
*/
@ 117, 101 BUTTON ::oBtnAceptar SIZE 45, 15 ACTION ::Aceptar()
RETURN Self
Adem谩s, si no existe prueba.prg lo crea con el siguiente c贸digo
prueba.prg
CLASS TIPOIVA FROM _TIPOIVA
METHOD ValidaTipo()
METHOD ValidaDescrip()
METHOD Aceptar()
METHOD Cancel()
ENDCLASS
METHOD ValidaTipo() CLASS TIPOIVA
RETURN .T.
METHOD ValidaDescrip() CLASS TIPOIVA
RETURN .T.
METHOD Aceptar() CLASS TIPOIVA
RETURN NIL
METHOD Cancel() CLASS TIPOIVA
RETURN NIL
Dej谩ndonos el c贸digo listo para seguir programando.
Algo interesante es que desde dentro de los m茅todos podemos acceder a cualquier control o variable, ya que son DATAs del m茅todo que se est谩 ejecutando. Y seguimos teniendo la independencia que ya tenemos con los recursos, entre los aspectos visuales del form y el c贸digo de la aplicacion propiamente dicho.
Tambien hasta se podr铆a ejecutar el c贸digo de la clase _ que no har谩 nada, pero ser铆a como la funcion de test que tiene el PellesC para los dialogos.
Esto se corresponde con un patron de programaci贸n GRASP, variaciones protegidas, que tiene muchos usos en temas visuales de la programaci贸n.
Un saludo,
Carlos.