Hola Antonio.
Efectivamente, sería más práctico plantearme utilizar recursos, el problema es que no se qué o cuántos controles voy a tener que presentar cada ves, principalmente listbox's, una vez será uno, otra tres o ninguno, por lo que no tengo más remedio que utilizar oCtrl:New() en vez de oCtrl:Redefine().
Prueba este código:
#include "FiveWin.ch"
STATIC oWMain,oMenu
FUNCTION MAIN()
DEFINE WINDOW oWMain MDI TITLE " PRUEBA PANEL" MENU PonMenu()
ACTIVATE WINDOW oWMain MAXIMIZED
RETURN NIL
*
FUNCTION PonMenu()
MENU oMenu
MENUITEM "Crea Child" ACTION CrearChild()
ENDMENU
RETURN NIL
*
FUNCTION CrearChild()
LOCAL nHeight := GetSysMetrics(17)-GetSysMetrics(15) // ALTO AREA CLIENTE - ALTO MENU
LOCAL nWidth := GetSysMetrics(0) // ANCHO PANTALLA
LOCAL oWin,oDlO,oBot
*
DEFINE WINDOW oWin MDICHILD OF oWMain
DEFINE DIALOG oDlO OF oWin STYLE nOr(WS_CHILD,WS_VISIBLE)
@ 100,100 BUTTONBMP oBot PROMPT "Prueba" SIZE 50,12 OF oDlO PIXEL ACTION Dialogo(oDlO)
ACTIVATE DIALOG oDlO NOWAIT ON INIT oDlO:Move(0,0,nWidth,nHeight)
ACTIVATE WINDOW oWin MAXIMIZED
RETURN NIL
*
FUNCTION Dialogo(oDlg)
LOCAL oDlC,oPan,oSay
*
DEFINE DIALOG oDlC OF oDlg STYLE nOr(WS_POPUP,WS_VISIBLE,WS_CAPTION,WS_SYSMENU,WS_DLGFRAME) SIZE 600,400
oPan := TPanel():New(10,10,580,380,oDlC)
@ 10,20 SAY oSay PROMPT "PRUEBA" OF oPan SIZE 60,15
ACTIVATE DIALOG oDlC CENTER ON INIT oPan:Move(10,10,580,380)
RETURN NIL
La verdad es que no es necesaria tanta parafernalia, sólo bastan un Dialogo, un Panel y un SAY sobre el panel para que falle la compilación. El inconveniente es que cuando se crea el TSAY, al final de su método New() llama a ::DefControl(), pero resulata que el ::oWnd es el TPANEL que es un control, no un Dialogo, y TCONTROL no tiene método DefControl() por lo que el TSAY no tiene más remedio que fallar.
Buscando una solución le definí un DefControl estándar al TAPNEL, tal que así:
METHOD DefControl( oCtrl ) CLASS TPanel
DEFAULT oCtrl:nId := oCtrl:GetNewId()
IF ::aControl = NIL
::aControls := {}
ENDIF
AAdd( ::aControls, oCtrl )
oCtrl:hWnd = 0
RETURN NIL
Ya no falla la construcción del TSAY pero no se inicializa porque cuando el Dialogo recibe el mensaje "INITIATE" inicializa todos sus controles pero no ese TSAY porque no le pertenece, pertenece al TPANEL.
La solución pasaría por definirle un METHOD INITIATE( hDlg ) al uso al TPANEL añadiéndole al final:
IF ::aControls # NIL
ASend( ::aControls, "INITIATE()", ::hWnd )
ENDIF
Pero aparece otro problema. El flujo del programa, efectivamente, intienta incializar el TSAY, pero cuando llega a:
IF( ( ::hWnd := GetDlgItem( hDlg, ::nId ) ) # 0 )
falla porque GetDlgItem( hDlg, ::nId ) devuelve 0 y se corta. Seguramente porque TPANEL no es un dialogo. El caso es que he probado con GetWindow( ::hWnd, GW_CHILD ), pero también devuelve 0, lo ponga donde lo ponga, en el INITITE del TPANEL o en el del TSAY y no lo comprendo por TCOMBO lo utiliza y funciona.
Por ahora he encontrado una solución provisional definiendo el DefControl() del TPANEL de esta manera:
METHOD DefControl( oCtrl ) CLASS TFondo
::oWnd:DefControl( oCtrl )
SetParent(oCtrl:hWnd,::hWnd)
RETURN NIL
Y el TSAY se dibuja. El problema es que se pinta tanto sobre el TPANEL como sobre el DIALOG, porque en realidad, aunque le digo que su window padre es el TPANEL, en realidad es un ::aControls del DIALOG, por lo tanto cuando se pinta, lo hace a caballo entre los dos, es decir se ve entero pero parte sobre el DIALOG y parte sobre el TPANEL. Podría modificar el nLeft del TSAY para que sólo se dibujara sobre el TPANEL, pero no me sirve porque cuando presente los controles del TPANEL necesito que las paretes que no caben sobre el TPANEL no se pinten sobre el DIALOGO sino que aparezcan cortadas ( el dialogo tiene más cosas además del TPANEL). El TPANEL tiene que aprentar un folio sobre el que se escriben las cosas, y las que no caben no pueden pintarse sobre la mesa (el DIALOG).
La solución pasa por definirle al TSAY un ::hWnd dependiente del TPANEL durante la inicialización pero no atino a hacerlo. Pensé que GetWindow(::hWnd,GW_CHILD) serviría, pero no lo hace y no sé porqué.
Antonio, tu tienes mucha más esperiencia que yo en este campo, eres el maestro, si tu no encuentras la solución no la va a encontrar nadie y tendré que desistir de esta opción para mi programa. Claro que tampoco quiero que le dediques todo tu valioso tiempo en este asunto.
Si puedes hacer algo, muchas gracias, y si no, pues tampoco pasa nada.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55