FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posts: 410
Joined: Sun Jan 31, 2010 03:30 PM
Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Fri Feb 13, 2026 03:46 PM

Buen dia....

Estoy en plan de investigar, validar, probar, desarrollar con asistencia de IA ,,,,
por hoy solo les comentare de mi ultima experiencia (hoy feb 13) , mas adelante les comentare lo que he hecho en los ultimos 8 dias...

Por ahora... lo de hoy... genere un promt basico con gemini 3 pro (ultra)..."me puedes ayudar a revisar codigo escrito en xharbour + fivewin"..... al final ME DICE SI... colocame un par de funciones y revisamos..

  1. Tenia dudas de unas funciones genericas...generador dinamico de formularios ()...
    despues de unos 10 minutos... me genero un reporte con posibles errores... me genero informe... y las funciones requeridas para reemplazar mi funcion,.. despues de 1 o 2 horas de prueba y error...e interactuando con gemini... no funcionaba del todo ....

Previo a esta tarea , habia consultado cual IA me recomienda para evaluar codigo (x)harbour + fivewin....
me puso en primer lugar "CURSOR"... pero como tengo cuenta con gemini 3 ... plan ultra.. inicie con ellos y obtune el resultado anterior...

Me voy con CURSOR... version libre.... copie las mismas funciones.... resultado... reporte de fallas potenciales y mejoras (ahora les paso el informe)
en 5 minutos me genero las nuevas funciones ....compile con ellas... CERO ...errores

LA PROBE ... FUNCIONADO OK....

Bueno tendre que ajustarla el diseño particular que tenia... porque me quito todo lo desconocido o que lo manejaba con metodos propios... bueno al final un generador de formularios dinamico - limpio... pero funcionalmente igual

Saludos

JONSSON RUSSI

Anexo funciones anteriores y nuevas (CURSOR)

Nota: A los expertos favor analizar cambios.. y nos realimentan de lo que hizo la IA o AI .!!!!!!

FUNCTION MAIN()   
   

   LOCAL vVecOpc,vVecVar,vVecGet,vVecPic,vVecVal,vVecWen,vVecMen,vVecAnc

   PRIVATE xCamCla := SPACE(12), cCamDes := SPACE(40), cCodDia := SPACE(10)


   vVecOpc := {"C¢digo",;
               "Descripci¢n",;
               "C•digo DIAN"}


   vVecVar := {"xCamCla","cCamDes","cCodDia"}

   vVecGet := {"G","G","G"}


   vVecPic := {"@!X", "@!X", "@!X"}

   vVecVal := {"!EMPTY(xCamCla)","",""}      //

   vVecWen := {}

   vVecAnc := {12,40,12}

   vVecMen := {{"",0},{"",0},{"",0}}

   IF 1 == 1
      IF !Wcaptura(9,10,vVecOpc,@vVecVar,vVecGet,vVecPic,vVecVal,vVecWen,vVecMen,vVecAnc,;
         "Creaci¢n de  : Unidades de Medida",2,NIL )
         RETURN
      ENDIF
   ELSE
      // VERSION IA-CURSOR
      IF !cursor_Wcaptura(9,10,vVecOpc,@vVecVar,vVecGet,vVecPic,vVecVal,vVecWen,vVecMen,vVecAnc,;
         "Creaci¢n de  : Unidades de Medida",2,NIL )
         RETURN
      ENDIF
   

   ENDIF

ENDIF


FUNCTION __Wcaptura( nFilArr,nColIzq,vVecOpc,vVecVar,vVecGet,vVecPic,vVecVal,;
                     vVecWen,vVecMen,vVecAnc,cMenTit,nNroBot,cActBot,fFunUsu,;
                     cUbiVen,lVlrVar,vVecCpo,cAliTab,lAnexar,vVecDbc,vVecCha,;
                     vVecRad,vVecCom,vVecBot,cFunInc,vVecCol,nAncAdi,vVecVer,;
                     cBotFor,oDlgPad,lFocBot,vVecFol,cAjuFon,cTitAce,cTitSal )

  LOCAL oRadMen,oGet, oDlg
  LOCAL nSayMay, nLonSar, nGetMay, nAncPan, cVarCha
  LOCAL nColSay := 10, nEspFil := 0.1, hFont
  LOCAL VecBotCap := {1,2,3,4,5}, K := 15,  L := 0,  M := 0, ; // k:= 7
        nColGet := 0,  JJ,  F := .6, cVarVal, cVarWen, oPanel1

  LOCAL cAliAct := ALIAS() , lAjuDer := .F.


  LOCAL cPreCod2 := cCodPro2 := cPrePlu2 := xCodPlu2 := cPreRef2 := xRefPro2 := 0

  LOCAL nNroOpc := 1 , nLonRad := 0, xVarInv := ""
  LOCAL nFilSup := 8.7, nFilInf := 33.4 , nPixAdi := 0 , nLinAdi := 0
  LOCAL oPanel2, lValVal := .F. , nValue := 3, nLonGet := 0
  LOCAL nSayPri := .T., nGetPri := .T., nPriBot := 0, nAnchoGet
  LOCAL N := 6*F, J := 0, R := 0
  LOCAL oCajDia,  Z := 10, a := {} , ZZ, oBrush   // .T.
  LOCAL nFacFon := 1 , nFacRad := 0.1, Q := 0
  LOCAL vVecAux := {}, oFont

  LOCAL VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VF10, VF11, VF12, ENTER :=  ""

  LOCAL nMulFol := 7.57, nTamDia := 22 , SW_FONDO := .F.

  LOCAL oFld , oDlgGra , oWndTem ,  nAjuMov := 0  , SW_DIALOG_WIN := .F.
  LOCAL SW := .F., SW_TAB := .F.
  LOCAL cTamPag := ""

  LOCAL  nNroPan := 1, JI := 0
  LOCAL aPanWin := FW_GetAllMonitors()

  LOCAL nMulAju := 2
  LOCAL cPorAju := "1"


  localizaRegistro("CAJ","cCodigoCaj",M->cCajIni)

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.1", "ART"
     ENDIF
  ENDIF


  DEFAULT cTitSal := "Salir"
  DEFAULT cTitAce := "Aceptar"

  IF PARAMETRO(410)
     FOR JI := 1 TO LEN(aPanWin)
         IF ( aPanWin[JI]:LPRIMARY )
             nNroPan := JI
         ENDIF
     NEXT
  ENDIF

  IF PARAMETRO(372,@cTamPag)

 IF cTamPag == NIL .OR. EMPTY(cTamPag)
    cTamPag := "0"
 ENDIF

 IF VAL(cTamPag) > 0
    nTamDia := VAL(cTamPag)
 ENDIF

  ENDIF

  hb_gcAll()


  GUARDATECLAS_FWX(@VF1,@VF2,@VF3,@VF4,@VF5,@VF6,@VF7,@VF8,@VF9,@VF10,@VF11,@VF12,@ENTER)


  MEMVAR oBoton1, oBoton2, oBoton3

  MEMVAR oGet1 , oGet2 , oGet3 , oGet4 ,  oGet5 , oGet6 , oGet7 , oGet8 , oGet9 , oGet10 ,  ;
         oGet11 ,  oGet12 ,  oGet13 ,  oGet14 ,  oGet15 ,  oGet16 ,  oGet17 ,  oGet18 ,  oGet19 ,;
         oGet20 , oGet21 , oGet22,  oGet23 ,  oGet24 ,  oGet25 ,  oGet26 ,  oGet27 ,  oGet28 ,;
         oGet29 , oGet30 , oGet31,  oGet32 ,  oGet33 ,  oGet34 ,  oGet35 ,  oGet36 ,  oGet37 ,;
         oGet38 , oGet39 , oGet40,  oGet41 ,  oGet42 ,  oGet43 ,  oGet44 ,  oGet45 ,  oGet46 ,  oGet47 ,  oGet48 ,;
         oGet49 , oGet50 , oGet51,  oGet52 ,  oGet53 ,  oGet54 ,  oGet55 ,  oGet56 ,  oGet57 ,;
         oGet58 , oGet59 , oGet60

  MEMVAR oSay1 , oSay2 , oSay3 , oSay4 , oSay5 , oSay6 , oSay7 , oSay8 ,oSay9 , oSay10 , oSay11 , oSay12 ,;
         oSay13 ,oSay14 , oSay15 , oSay16 , oSay17 , oSay18 , oSay19 , oSay20 , oSay21 , oSay22,;
         oSay23 ,oSay24 , oSay25 , oSay26 , oSay27 , oSay28 , oSay29 , oSay30 , oSay31 , oSay32,;
         oSay33 ,oSay34 , oSay35 , oSay36 , oSay37 , oSay38 , oSay39 , oSay40 , oSay41 , oSay42,;
         oSay43 ,oSay44, oSay45 , oSay46 , oSay47 , oSay48 , oSay49 , oSay50 , oSay51 , oSay52,;
         oSay53 ,oSay54 , oSay55 , oSay56 , oSay57 , oSay58 , oSay59 , oSay60

  MEMVAR oDt1, oDt2, oDt3, oDt4, oDt5, oDt6, oDt7, oDt8, oDt9, oDt10, oDt11, oDt12, oDt13, oDt14, oDt15,;
         oDt16, oDt17, oDt18, oDt19, oDt20, oDt21, oDt22, oDt23, oDt24, oDt25, oDt26, oDt27, oDt28, oDt29, oDt30,;
         oDt31, oDt32, oDt33, oDt34, oDt35, oDt36, oDt37, oDt38, oDt39, oDt40, oDt41, oDt42, oDt43, oDt44, oDt45,;
         oDt46, oDt47, oDt48, oDt49, oDt50, oDt51, oDt52, oDt53, oDt54, oDt55, oDt56, oDt57, oDt58, oDt59, oDt60

  PRIVATE oDt1, oDt2, oDt3, oDt4, oDt5, oDt6, oDt7, oDt8, oDt9, oDt10, oDt11, oDt12, oDt13, oDt14, oDt15,;
          oDt16, oDt17, oDt18, oDt19, oDt20, oDt21, oDt22, oDt23, oDt24, oDt25, oDt26, oDt27, oDt28, oDt29, oDt30,;
          oDt31, oDt32, oDt33, oDt34, oDt35, oDt36, oDt37, oDt38, oDt39, oDt40, oDt41, oDt42, oDt43, oDt44, oDt45,;
          oDt46, oDt47, oDt48, oDt49, oDt50, oDt51, oDt52, oDt53, oDt54, oDt55, oDt56, oDt57, oDt58, oDt59, oDt60

  PRIVATE oGet1 , oGet2 , oGet3 , oGet4 ,  oGet5 , oGet6 , oGet7 , oGet8 , oGet9 , oGet10 ,  ;
          oGet11 ,  oGet12 ,  oGet13 ,  oGet14 ,  oGet15 ,  oGet16 ,  oGet17 ,  oGet18 ,  oGet19 ,;
          oGet20 , oGet21 , oGet22,  oGet23 ,  oGet24 ,  oGet25 ,  oGet26 ,  oGet27 ,  oGet28 ,;
          oGet29 , oGet30 , oGet31,  oGet32 ,  oGet33 ,  oGet34 ,  oGet35 ,  oGet36 ,  oGet37 ,;
          oGet38 , oGet39 , oGet40,  oGet41 ,  oGet42 ,  oGet43 ,  oGet44 ,  oGet45 ,  oGet46 ,  oGet47 ,  oGet48 ,;
          oGet49 , oGet50 , oGet51,  oGet52 ,  oGet53 ,  oGet54 ,  oGet55 ,  oGet56 ,  oGet57 ,;
          oGet58 , oGet59 , oGet60

  PRIVATE oSay1 , oSay2 , oSay3 , oSay4 , oSay5 , oSay6  , oSay7 , oSay8 ,oSay9 , oSay10 , oSay11 , oSay12 ,;
          oSay13 ,oSay14 , oSay15 , oSay16 , oSay17 , oSay18 , oSay19 , oSay20 , oSay21 , oSay22,;
          oSay23 ,oSay24 , oSay25 , oSay26 , oSay27 , oSay28 , oSay29 , oSay30 , oSay31 , oSay32,;
          oSay33 ,oSay34 , oSay35 , oSay36 , oSay37 , oSay38 , oSay39 , oSay40 , oSay41 , oSay42,;
          oSay43 ,oSay44, oSay45 , oSay46 , oSay47 , oSay48 , oSay49 , oSay50 , oSay51 , oSay52,;
          oSay53 ,oSay54 , oSay55 , oSay56 , oSay57 , oSay58 , oSay59 , oSay60


  PRIVATE oBoton1, oBoton2, oBoton3


  DEFAULT vVecDbc := {}, vVecCha := {}, vVecRad := {} , vVecCom := {} , vVecBot := {}, vVecCol := {}

  DEFAULT lVlrVar := .T., lAnexar := .F.

  DEFAULT nAncAdi := 0, lFocBot := .F.

  SET ESCAPE ON

  IF nAncAdi < 0  // PO AHORA .. PARA ANULAR LOS AJUSTES NEGATIVOS
     nAncAdi := 0
  ENDIF


  HB_SetCodePage("ESWIN")


  nFacRad := 0.0

  IF PARAMETRO(180,@cPorAju)   // AJUSTE PARA TABLETAS CON WINDOWS
     nFacFon := 1
     nAjuMov := 10
  ENDIF


  IF !EMPTY(getCampoRS("CAJ","cResAuxCaj",nil) ) .AND. VAL(getCampoRS("CAJ","cResAuxCaj",nil)) > 0
     PARAMETRO(466,NIL,getCampoRS("CAJ","cResAuxCaj",nil) )
  ENDIF

  PARAMETRO(466,@cPorAju)

  IF !EMPTY(cPorAju)

  //IF !EMPTY(getCampoRS("CAJ","cResAuxCaj",nil) )
     nFacFon := val(cPorAju)
     if nFacFon == 0
        nFacFon := 1
     endif
  ENDIF


  IF LEN(vVecOpc) == 0
     IF SELECT(cAliAct) <> 0
        SELECT(cAliAct)
     ENDIF
     ALERTA("Error. Vector de opciones esta vacio")
     RETURN .F.
  ENDIF

  SET _3DLOOK ON

  FOR J := 1 TO LEN( vVecOpc ) // adiciona al tama¤o de la pantalla * C/control radio button
      IF vVecGet[J] == "R"
         nPixAdi += 4
      ENDIF
  NEXT J

  SW_TAB := .F.

  nLinAdi := (nPixAdi/12)
  IF ( LEN(vVecOpc) <= nTamDia )
     nTamVen := ((LEN(vVecOpc)+ 3.5 + nLinAdi ) * 1.6)
  ELSE
     nTamVen := (( nTamDia + 3.5 + nLinAdi ) * 1.6)
     IF PARAMETRO(286)
        SW_TAB := .T.
     ENDIF
  ENDIF


  IF cActBot <> NIL
     S_lActCap := .F.
     nFilInf := nFilSup + nTamVen
  ENDIF


  IF getHvar("cIniMet") == "S"  // SOLO AL INICIO DE LA METRO
     IF GetWndDefault() == NIL
        DEFINE WINDOW oWndTem TITLE "" STYLE nOr( WS_POPUP, WS_MAXIMIZE )
        ACTIVATE WINDOW oWndTem ON INIT ( oDlgPad := GetWndDefault(), oWndTem:END())
     ENDIF
  ENDIF

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.2", "ART"
     ENDIF
  ENDIF


  IF oDlgPad == NIL
     DEFINE DIALOG oDlg OF OwND  TITLE HB_OEMTOANSI(cMenTit)   ;
                   FROM nFilSup, 0 TO nFilInf, (90+nAncAdi-nAjuMov)*nFacFon // BRUSH oBrush

  ELSE                   //OF oDlgPad

 DEFINE DIALOG  oDlg OF oDlgPad TITLE HB_OEMTOANSI(cMenTit) ;
               FROM nFilSup, 0 TO nFilInf, (90+nAncAdi-nAjuMov)*nFacFon

               //STYLE nOr( WS_VISIBLE, WS_CHILD,WS_MINIMIZEBOX )

  ENDIF

   oDlg:bInit := { || initDialogoWcaptura( oDlg, nFilArr,nColIzq,vVecOpc,vVecVar,vVecGet,vVecPic,vVecVal,;
                                           vVecWen,vVecMen,vVecAnc,cMenTit,nNroBot,cActBot,fFunUsu,;
                                           cUbiVen,lVlrVar,vVecCpo,cAliTab,lAnexar,vVecDbc,vVecCha,;
                                           vVecRad,vVecCom,vVecBot,cFunInc,vVecCol,nAncAdi,vVecVer,;
                                           cBotFor,oDlgPad,lFocBot,vVecFol,cAjuFon,cTitAce,cTitSal,;
                                           nFilSup,nFilInf,nMulFol,nTamDia,SW_FONDO,nFacFon) }

   IF cUbiVen == NIL          //oCajDia1


 ACTIVATE DIALOG oDlg CENTER  ;  // NOMODAL junio 08 2020  //oDlg:SetFocus() x nil
          VALID ( EVALUABOTOM(vVecBot,nNroBot,'ACTIVE BOTON',,IF(S_lActCap ,cFunInc,"N") ) , ; //lActCap
                  NoEstoyAdentro(@lVlrVar) ,;
                  RestauraVentana( vVecVar ) )


  ELSE   // por defecto o normal


 ACTIVATE DIALOG oDlg  CENTER  ;                 // oDlg:SetFocus()
          VALID ( EVALUABOTOM(vVecBot,nNroBot,'ACTIVE BOTON',,IF(S_lActCap,cFunInc,"N") ) , ;  //lActCap
                  NoEstoyAdentro(@lVlrVar) ,;
                  RestauraVentana( vVecVar ) )


  ENDIF


  IF SELECT(cAliAct) <> 0
     SELECT(cAliAct)
  ENDIF


  RECUPERATECLAS_FWX(VF1,VF2,VF3,VF4,VF5,VF6,VF7,VF8,VF9,VF10,VF11,VF12,ENTER)

  IF oWndTem <> NIL
     oWndTem:END()
  ENDIF

  oDlg:Hide()
  oDlg:Destroy()



RETURN S_lActCap  // lActCap

//**************************************************************************************************

STATIC FUNCTION initDialogoWcaptura( oDlg,nFilArr,nColIzq,vVecOpc,vVecVar,vVecGet,vVecPic,vVecVal,;
                                     vVecWen,vVecMen,vVecAnc,cMenTit,nNroBot,cActBot,fFunUsu,;
                                     cUbiVen,lVlrVar,vVecCpo,cAliTab,lAnexar,vVecDbc,vVecCha,;
                                     vVecRad,vVecCom,vVecBot,cFunInc,vVecCol,nAncAdi,vVecVer,;
                                     cBotFor,oDlgPad,lFocBot,vVecFol,cAjuFon,cTitAce,cTitSal,;
                                     nFilSup,nFilInf,nMulFol,nTamDia,SW_FONDO,xFacFon)

  LOCAL oCajDia1, oRadMen,oGet
  LOCAL nSayMay, nLonSar, nGetMay, nAncPan, cVarCha
  LOCAL nColSay := 10, nEspFil := 0.1, hFont
  LOCAL VecBotCap := {1,2,3,4,5}, K := 15,  L := 0,  M := 0, ; // k:= 7
        nColGet := 0,  JJ,  F := .6, cVarVal, cVarWen, oPanel1

  LOCAL cAliAct := ALIAS() , lAjuDer := .F.


  LOCAL cPreCod2 := cCodPro2 := cPrePlu2 := xCodPlu2 := cPreRef2 := xRefPro2 := 0

  LOCAL nNroOpc := 1 , nLonRad := 0, xVarInv := ""
  LOCAL nPixAdi := 0 , nLinAdi := 0
  LOCAL oPanel2, lValVal := .F. , nValue := 3, nLonGet := 0
  LOCAL nSayPri := .T., nGetPri := .T., nPriBot := 0, nAnchoGet
  LOCAL N := 6*F, J := 0, R := 0
  LOCAL oCajDia,  Z := 10, a := {} , ZZ, oBrush   // .T.
  LOCAL nFacRad := 0.1, Q := 0
  LOCAL vVecAux := {}, oFont

  LOCAL VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VF10, VF11, VF12, ENTER :=  ""

  LOCAL oFld , oDlgGra , oWndTem , cPorAju := "", nAjuMov := 0  , SW_DIALOG_WIN := .F.
  LOCAL SW := .F., SW_TAB := .F.
  LOCAL cTamPag := ""
  LOCAL  nNroPan := 1, JI := 0
  LOCAL aPanWin := FW_GetAllMonitors()
  LOCAL nMulAju := 2, H := 1
  LOCAL oObjSay , oObjGet, oObjDat, cSarSay
  local nFacFon := 1

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.3", "ART"
     ENDIF
  ENDIF


  IF PARAMETRO(410)
     FOR JI := 1 TO LEN(aPanWin)
         IF ( aPanWin[JI]:LPRIMARY )
             nNroPan := JI
         ENDIF
     NEXT
  ENDIF



  DEFAULT cTitSal := "Salir"
  DEFAULT cTitAce := "Aceptar"


  if xFacFon <> nil
     nFacFon := xFacFon
  endif

  IF GetSysMetrics(1) > 768 .and. cAjuFon == nil
     DEFINE FONT oFont NAME "Tahoma" SIZE 0, -14
     IF xFacFon == 1
        nFacFon += 0.2
     ENDIF
  ELSE
     DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
     nFacFon += 0
  ENDIF


  oDlg:SetFont( oFont )

  MM := 1
  NN := 1
  FOR J := 1 TO  LEN(vVecOpc)
      IF NN > nTamDia
         ++MM
         NN := 1
      ENDIF
      ++NN
  NEXT J

  IF vVecFol <> NIL  .AND. LEN(vVecFol) == MM

 IF MM == 00

    @ 0, 1 FOLDER oFld ITEMS vVecFol[1] ;
                  OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF
 ELSEIF MM == 2

    @ 0, 1 FOLDER oFld ITEMS vVecFol[1],vVecFol[2] ;
                  OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF
 ELSEIF MM == 3

    @ 0, 1 FOLDER oFld ITEMS vVecFol[1],vVecFol[2],vVecFol[3] ;
                  OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 3 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF
 ELSEIF MM == 4

    @ 0, 1 FOLDER oFld ITEMS vVecFol[1],vVecFol[2],vVecFol[3],vVecFol[4] ;
                  OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 3 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 4 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF
 ENDIF

  ELSE



 IF MM == 00

    @ 0, 1 FOLDER oFld ITEMS "&Basicos" ;
                  OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF

 ELSEIF MM == 2


    @ 0, 1 FOLDER oFld ITEMS "&Basicos", "&Adicional 1" ;
               OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF

 ELSEIF MM == 3

    @ 0, 1 FOLDER oFld ITEMS "&Basicos", "&Adicional 1", "&Adicional 2" ;
               OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 3 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF
 ELSEIF MM == 4

    @ 0, 1 FOLDER oFld ITEMS "&Basicos", "&Adicional 1", "&Adicional 2","&Adicional 3" ;
               OF oDlg PIXEL SIZE ((355+nAncAdi)*nFacFon)*nMulAju, ((nFilInf-nFilSup)*nMulFol)*nMulAju
    IF SW_DIALOG_WIN
       oFld:aDialogs[ 1 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 2 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 3 ]:setcolor( M->cColorTexto,M->cColorFondo)
       oFld:aDialogs[ 4 ]:setcolor( M->cColorTexto,M->cColorFondo)
    ENDIF

 ENDIF

  ENDIF

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.4", "ART"
     ENDIF
  ENDIF


  IF SW_DIALOG_WIN
     oDlg:setColor(M->cColorTexto,M->cColorFondo)
  ENDIF

  try

 //BUSCA EL SAY MAS ANCHO
 nSayMay := LEN(vVecOpc[1])
 FOR J := 1 TO LEN(vVecOpc)
     nLonSar := GETTEXTWIDTH(0,vVecOpc[J],oFonAct:hFont)
     IF nLonSar > nSayMay
        nSayMay := nLonSar
     ENDIF
 NEXT J

 IF vVecWen == NIL .OR. LEN(vVecWen) == 0
    vVecWen := ARRAY(LEN(vVecOpc))
    FOR J := 1 TO LEN(vVecOpc)
        vVecWen[J] := ""
    NEXT J
 ENDIF

 //BUSCA EL GET MAS ANCHO
 nGetMay := vVecAnc[1]
 FOR J := 1 TO LEN(vVecAnc)
    IF vVecAnc[J] > nGetMay
       nGetMay := vVecAnc[J]
    ENDIF
 NEXT J
  catch
     mymen("Error. En estructura para browse - Russoft ERP")
     return .f.
  end

  nGetMay :=  GETTEXTWIDTH(0,REPLI("x",nGetMay),oFonAct:hFont)  // * .7

  MM := 1
  NN := 1
  FOR J := 1 TO  LEN(vVecOpc)  // LEN(vVecOpc)      // TEXTO

  //vVecOpc[J] := HB_OEMTOANSI( vVecOpc[J] )

  IF NN > nTamDia
     K := 15
     L := 0
     M := 0
     ++MM
     NN := 1
  ENDIF
  ++NN

  IF LEN(vVecOpc) > nTamDia
     oCajDia1 :=  oFld:aDialogs[ MM ]
  ELSE
     oCajDia1 :=  oDlg
  ENDIF

  M += L + K
  //
  IF J<>1
     M := M + nEspFil
  ElSE

  ENDIF
  //

  IF UPPER(vVecGet[J]) == 'R'
     M := M + 1  // 4
  ENDIF
  SW := .F.
  cSarSay := vVecOpc[J]
  IF " " $ cSarSay
     SW := .T.
  ELSEIF "‚" $ cSarSay
     SW := .T.
  ELSEIF "¡" $ cSarSay
     SW := .T.
  ELSEIF "¢" $ cSarSay
     SW := .T.
  ELSEIF "£" $ cSarSay
     SW := .T.
  ELSEIF "¤" $ cSarSay
     SW := .T.
  ELSEIF "µ" $ cSarSay
     SW := .T.
  ELSEIF "" $ cSarSay
     SW := .T.
  ELSEIF "Ö" $ cSarSay
     SW := .T.
  ELSEIF "é" $ cSarSay
     SW := .T.
  ELSEIF "é" $ cSarSay
     SW := .T.
  ELSEIF "¥" $ cSarSay
     SW := .T.
  ENDIF

  IF SW
     cSarSay :=  HB_OEMTOANSI(cSarSay)
  ENDI


 IF SW_DIALOG_WIN            // OemToAnsi

     @ M*nMulAju, nColSay*nMulAju SAY cSarSay  PIXEL  SIZE ((nSayMay+IF(nAncAdi==0,2,nAncAdi/4))*nFacFon)*nMulAju ,(10*nFacFon)*nMulAju OF oCajDia1 ;
                  COLOR M->cColorTexto,M->cColorFondo

 ELSE

     @ M*nMulAju, nColSay*nMulAju SAY cSarSay  PIXEL  SIZE ((nSayMay+IF(nAncAdi==0,2,nAncAdi/4))*nFacFon)*nMulAju ,(10*nFacFon)*nMulAju OF oCajDia1


 ENDIF

  L := 12
  K := 0
  NEXT J

  nColGet := ( ( ( nSayMay + nColSay ) / 2 ) +  IF(nAncAdi==0,30,30+nAncAdi/4) ) * nFacFon
  nColGet := nColGet*nMulAju

  K := 12*nMulAju //4
  H := 1
  L := 0
  Q := 0

  J := 1

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.5", "ART"
     ENDIF
  ENDIF


  ///

 MM := 1
 NN := 1
 DO WHILE J <= LEN(vVecOpc)

    IF NN > nTamDia
       K := 12*nMulAju
       H := 1
       L := 0
       Q := 0
       ++MM
       NN := 1
    ENDIF
    ++NN

    IF LEN(vVecOpc) > nTamDia
       oCajDia1 := oFld:aDialogs[ MM ]
       oDlgGra  := oFld:aDialogs[ MM ]
    ELSE
       oCajDia1 :=  oDlg
       oDlgGra  :=  oDlg
    ENDIF

    IF SW_TAB
       oDlgGra := oCajDia1
    ENDIF

    //oCajDia1 :=  oFld:aDialogs[ MM ]

    H += ( L + K )

    // vVecCom,vVecWen,vVecCha

    IF LEN(vVecCom) >= J
       FOR R := 1 TO LEN(vVecCom[J])
           vVecCom[J,R] := HB_OEMTOANSI(vVecCom[J,R])
       NEXT
    ENDIF

    //***WHEN

    IF LEN(vVecWen) >= J
       IF EMPTY( vVecWen[J] ) .OR. vVecWen[J] == NIL
          vVecWen[J] := ".T."
       ENDIF
    ENDIF

    //***ON CHANGE
    IF LEN( vVecCha ) >= J
       IF EMPTY( vVecCha[J] ) .OR. vVecCha[J] == NIL
          vVecCha[J] := ".T."
       ENDIF
    ENDIF

    //***VALID
    IF EMPTY( vVecVal[J] ) .OR. ( vVecVal[J] == NIL )
       vVecVal[J] := ".T."
    ENDIF
                                    //cPreCod2, cCodPro2,cPrePlu2,xCodPlu2,cPreRef2,xRefPro2
    // EXEPCION PARA AYUDA EN CREAR CODIGO, PLU O REF PROVEEDOR
    IF lAnexar .and. cAliTab == "ART"
       TRY
          IF UPPER(ALLTRIM(vVecOpc[2])) == "CODIGO"
             IF EMP->cCodConEmp == 'S' .AND. EMP->nConSugEmp > 0
                cPreCod2 := ALLTRIM(EMP->cPreCodEmp)
                cCodPro2 :=  cPreCod2+;
                         ALLTRIM(STR(EMP->nConSugEmp+1,16-LEN(cPreCod2),0))+;
                             SPACE(16-LEN(cPreCod2)-LEN(ALLTRIM(STR(EMP->nConSugEmp+1,16-LEN(cPreCod2),0))))
                &(vVecVar[2]) := cCodPro2
             ENDIF
          ENDIF

       IF UPPER(ALLTRIM(vVecOpc[3])) == "P.L.U."
          IF EMP->cCodConEmp == 'S' .AND. EMP->nPluSugEmp > 0
             cPrePlu2 := ALLTRIM(EMP->cPrePluEmp)
             xCodPlu2 := cPrePlu2+;
    		     ALLTRIM(STR(EMP->nPluSugEmp+1,16-len(cPrePlu2),0))+SPACE(16-len(cPrePlu2)-;
    		     LEN(ALLTRIM(STR(EMP->nPluSugEmp+1,16-len(cPrePlu2),0))))
              &(vVecVar[3]) := xCodPlu2
          ENDIF

       ENDIF

       IF UPPER(ALLTRIM(vVecOpc[4])) == "REFERENCIA PROVEEDOR"
          IF EMP->cCodConEmp == 'S' .AND. EMP->nRefSugEmp > 0
             cPreRef2 := ALLTRIM(EMP->cPreRefEmp)

             xRefPro2 := cPreRef2+;
   	     ALLTRIM(STR(EMP->nRefSugEmp+1,16-len(cPreRef2),0))+SPACE(16-len(cPreRef2)-;
   	     LEN(ALLTRIM(STR(EMP->nRefSugEmp+1,16-len(cPreRef2),0))))

             &(vVecVar[4]) := xRefPro2
          ENDIF
       ENDIF

       CATCH

       END

    ENDIF

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.6", "ART"
     ENDIF
  ENDIF


//***********NUEVO

       oObjSay := GetNew()
       oObjGet := GetNew()
       oObjDat := GetNew()

       BuildGetX( oCajDia1, @H, @nColGet,nEspFil, oFonAct:hFont,nFacFon,;
                  @oObjGet,@oObjDat,@oObjSay  ,;
                  @nGetPri,@nSayPri,;
                  vVecGet[J],if(len(vVecCol)>=J,vVecCol[J],vVecCol),;
                                 vVecAnc[J],vVecVar[J],vVecPic[J],;
                                 if(len(vVecWen)>=J,vVecWen[J],vVecWen)  ,;
                                 vVecVal[J],;
                                 if(len(vVecDbc)>=J, vVecDbc[J],vVecDbc) ,;
                                 if(len(vVecCom)>=J, vVecCom[J],vVecCom) ,;
                                 if(len(vVecRad)>=J, vVecRad[J],vVecRad))

                                 //vVecCom,vVecWen,vVecCha

       IF oObjGet <> NIL
          &("M->oGet"+ALLTRIM(STR(J,0))) := oObjGet // oGetHash[J]
       ENDIF
       IF oObjSay <> NIL
          &("M->oSay"+ALLTRIM(STR(J,0))) := oObjSay // oSayHash[J]
       ENDIF
       IF oObjDat <> NIL
          &("M->oDpt"+ALLTRIM(STR(J,0))) := oObjDat // oDPTHash[J]
       ENDIF

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.7", "ART"
     ENDIF
  ENDIF


// FIN NUEVO

    L := 12*nMulAju
    K := 0
    J := J + 1

    IF SW_TAB
       nFilBot := 300*nMulAju
       nAncPan := ( 350 + ( nAncAdi * 3.65 ) )*nMulAju

       nColDe1 := ( ( nAncPan - 100  ) / 3 )

       IF cActBot <> NIL

          JJ := nFilBot

          IF cActBot == "BOTONTERMINAR"


             nColDe1 := ((355*nMulAju+nAncAdi)*nFacFon - 140*nMulAju)

             IF ! M->SW_FONDO

                @ 270*nMulAju,  ( ((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4)) BUTTONBMP oBoton2 ;
                         BITMAP   "imagenes/level2.bmp" ;
                         NOBORDER;
                         PROMPT cTitSal TEXTRIGHT OF oDlgGra;
                         PIXEL SIZE 55*nMulAju,16*nMulAju ;
                         ACTION ( (S_lActCap := .F.), oDlg:END() )  UPDATE CANCEL

             ELSE

                @ 270*nMulAju , (((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4)) BTNBMP oBoton2 ;
                         FILE   "imagenes/level2.bmp" ;
                         NOBORDER;
                         PROMPT cTitSal TEXTRIGHT OF oDlgGra;
                         PIXEL SIZE 55*nMulAju,22*nMulAju ;
                         ACTION ( (S_lActCap := .F.), oDlg:END() )  UPDATE CANCEL
             ENDIF
          ELSE

             IF ! M->SW_FONDO

                @ 245*nMulAju , (((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4)) BUTTONBMP  oBoton1  ; //BUTTONBMP
                            BITMAP   "imagenes/level1.bmp" ;
                            PROMPT cTitAce TEXTRIGHT OF oDlgGra ;
                            PIXEL SIZE 55*nMulAju,16*nMulAju  ;
                            NOBORDER;
                            ACTION ( IF( ValidaValid(vVecOpc,vVecVar,vVecVal,vVecGet,nEspFil,nColGet,vVecPic,vVecVer), lValVal := .T.,lValVal := .F. ) ,;
                                     IF( fFunUsu == NIL .OR. !lValVal ,"" ,;
                                         IF( fFunUsu =="GRABARTABLA",_GRABARTABLA(vVecVar,vVecCpo,cAliTab,lAnexar,vVecAux), ;
                                             &(fFunUsu) ) ), ;
                                     (S_lActCap := lValVal )      , ;
                                     IF (lValVal,oDlg:END(),"") )


                @ 270*nMulAju , (((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4))  BUTTONBMP  oBoton2  ;         //BUTTONBMP
                            BITMAP   "imagenes/level2.bmp" ;
                            NOBORDER  ;
                            PROMPT cTitSal TEXTRIGHT  OF oDlgGra;
                            PIXEL SIZE 55*nMulAju,16*nMulAju ;
                            ACTION ( (S_lActCap := .F.), oDlg:END() ) UPDATE CANCEL
             ELSE


                @ 245*nMulAju , (((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4)) BTNBMP  oBoton1  ; //BUTTONBMP
                            FILE   "imagenes/level1.bmp" ;
                            PROMPT cTitAce TEXTRIGHT OF oDlgGra ;
                            PIXEL SIZE 55*nMulAju,22*nMulAju  ;
                            NOBORDER;
                            ACTION ( IF( ValidaValid(vVecOpc,vVecVar,vVecVal,vVecGet,nEspFil,nColGet,vVecPic,vVecVer), lValVal := .T.,lValVal := .F. ) ,;
                                     IF( fFunUsu == NIL .OR. !lValVal ,"" ,;
                                         IF( fFunUsu =="GRABARTABLA",GRABARTABLA(vVecVar,vVecCpo,cAliTab,lAnexar,vVecAux), ;
                                             &(fFunUsu) ) ), ;
                                     (S_lActCap := lValVal )      , ;
                                     IF (lValVal,oDlg:END(),"") )

                @ 270*nMulAju , (((355*nMulAju+nAncAdi)*nFacFon - 120*nMulAju)-(nAjuMov*4)) BTNBMP  oBoton2  ;         //BUTTONBMP
                            FILE   "imagenes/level2.bmp" ;
                            NOBORDER  ;
                            PROMPT cTitSal TEXTRIGHT  OF oDlgGra;
                            PIXEL SIZE 55*nMulAju,22*nMulAju ;
                            ACTION ( (S_lActCap := .F.), oDlg:END() ) UPDATE CANCEL

             ENDIF

          ENDIF

       ENDIF

       IF  M->SW_FONDO
          TRY
             IF oBoton1 <> NIL
                oBoton1:lBorder := .F.
                oBoton1:bClrGrad :=  bClrGrad
             ENDIF
           CATCH
          END
          TRY
             oBoton2:lBorder := .F.
             oBoton2:bClrGrad :=  bClrGrad
          CATCH
          END
       ENDIF
    ENDIF

 ENDDO

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.8", "ART"
     ENDIF
  ENDIF


   // 355
IF !SW_TAB

  nAncPan := (350 + ( nAncAdi * 3.65 ))*nMulAju

  nColDe1 := ( ( nAncPan - 100  ) / 3 )

  IF LEN(vVecOpc) <= nTamDia   // PARA QUE LOS BOTONES SE MUESTREN EN CUALQUIER TAB
     nFilBot := ( ( LEN(vVecOpc)+ 1.5 + nEspFil ) * 12 ) + nPixAdi - IF(LEN(vVecOpc)>nTamDia,10,0)
  ELSE

 nFilBot := ( ( nTamDia+ 1.5 + nEspFil ) * 12 ) + nPixAdi - IF(LEN(vVecOpc)>nTamDia,10,0)
  ENDIF

  nFilBot := nFilBot *nMulAju

  if nFacFon > 1.2
     nFacFon += 0.5
  endif


  //nFilBot := 80

  IF cActBot <> NIL

 JJ := nFilBot

 IF cActBot == "BOTONTERMINAR"

    //nColDe1 := ( ( nAncPan-50 ) / 2 )

    nColDe1 := ((355*nMulAju+nAncAdi) - 140*nMulAju)


    IF ! M->SW_FONDO

       @ (nFilBot-2) ,( nColDe1-(nAjuMov*1.5))*nFacFon BUTTONBMP oBoton2 ;
                BITMAP   "imagenes/level2.bmp" ;
                NOBORDER;
                PROMPT cTitSal TEXTRIGHT OF oDlgGra;
                PIXEL SIZE 55*nMulAju,16*nMulAju ;
                ACTION ( (S_lActCap := .F.), oDlg:END() )  UPDATE CANCEL

    ELSE

       @ (nFilBot-2) , (nColDe1-(nAjuMov*1.5))*nFacFon BTNBMP oBoton2 ;
                FILE   "imagenes/level2.bmp" ;
                NOBORDER;
                PROMPT cTitSal TEXTRIGHT OF oDlgGra;
                PIXEL SIZE 55*nMulAju,22*nMulAju ;
                ACTION ( (S_lActCap := .F.), oDlg:END() )  UPDATE CANCEL
    ENDIF
 ELSE

    IF ! M->SW_FONDO



       @ nFilBot , ( ((355*nMulAju+nAncAdi) - 210*nMulAju)-(nAjuMov*4) )*nFacFon BUTTONBMP  oBoton1  ; //BUTTONBMP
                   BITMAP   "imagenes/level1.bmp" ;
                   PROMPT cTitAce TEXTRIGHT OF oDlgGra ;
                   PIXEL SIZE 55*nMulAju,16*nMulAju  ;
                   NOBORDER;
                   ACTION ( IF( ValidaValid(vVecOpc,vVecVar,vVecVal,vVecGet,nEspFil,nColGet,vVecPic,vVecVer), lValVal := .T.,lValVal := .F. ) ,;
                            IF( fFunUsu == NIL .OR. !lValVal ,"" ,;
                                IF( fFunUsu =="GRABARTABLA",GRABARTABLA(vVecVar,vVecCpo,cAliTab,lAnexar,vVecAux), ;
                                    &(fFunUsu) ) ), ;
                            (S_lActCap := lValVal )      , ;
                            IF (lValVal,oDlg:END(),"") )


       @ nFilBot , ( ((355*nMulAju+nAncAdi) - 140*nMulAju)-(nAjuMov*4))*nFacFon  BUTTONBMP  oBoton2  ;         //BUTTONBMP
                   BITMAP   "imagenes/level2.bmp" ;
                   NOBORDER  ;
                   PROMPT cTitSal TEXTRIGHT  OF oDlgGra;
                   PIXEL SIZE 55*nMulAju,16*nMulAju ;
                   ACTION ( (S_lActCap := .F.), oDlg:END() ) UPDATE CANCEL
    ELSE


       @ (nFilBot-2) , (((355*nMulAju+nAncAdi) - 210*nMulAju)-(nAjuMov*4))*nFacFon BTNBMP  oBoton1  ; //BUTTONBMP
                   FILE   "imagenes/level1.bmp" ;
                   PROMPT cTitAce TEXTRIGHT OF oDlgGra ;
                   PIXEL SIZE 55*nMulAju,22*nMulAju  ;
                   NOBORDER;
                   ACTION ( IF( ValidaValid(vVecOpc,vVecVar,vVecVal,vVecGet,nEspFil,nColGet,vVecPic,vVecVer), ;
                                                                lValVal := .T.,lValVal := .F. )  ,;
                            IF( fFunUsu == NIL .OR. !lValVal ,"" ,;
                                IF( fFunUsu =="GRABARTABLA",GRABARTABLA(vVecVar,vVecCpo,cAliTab,lAnexar,vVecAux), ;
                                    &(fFunUsu) ) ), ;
                            (S_lActCap := lValVal )      , ;
                            IF (lValVal,oDlg:END(),"") )

       @ (nFilBot-2) , (((355*nMulAju+nAncAdi) - 140*nMulAju)-(nAjuMov*4))*nFacFon  BTNBMP  oBoton2  ;         //BUTTONBMP
                   FILE   "imagenes/level2.bmp" ;
                   NOBORDER  ;
                   PROMPT cTitSal TEXTRIGHT  OF oDlgGra;
                   PIXEL SIZE 55*nMulAju,22*nMulAju ;
                   ACTION ( (S_lActCap := .F.), oDlg:END() ) UPDATE CANCEL

    ENDIF

 ENDIF

  ENDIF


  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.9", "ART"
     ENDIF
  ENDIF

  IF  M->SW_FONDO

 TRY
    IF oBoton1 <> NIL
       oBoton1:lBorder := .F.
       oBoton1:bClrGrad :=  bClrGrad
    ENDIF
  CATCH

 END

 TRY
    oBoton2:lBorder := .F.
    oBoton2:bClrGrad :=  bClrGrad
 CATCH

 END

  ENDIF

ENDIF

TRY
   IF (lFocBot,oBoton1:SetFocus(),nil)
   xdisplay(oDlg,13,.T.,nil)
   IF(PARAMETRO(410),FW_GetMonitor( nNroPan ):Center( oDlg ), .T. )
CATCH
   FWLOG "ERROR __WCAPTURA", "FW_GetMonitor"
END

  IF oKernel:hVar["CONTROL_ERROR"]
     IF SELECT("ART") == 0
        FWLOG "For50_64 : ART CERRADA-2.1.10", "ART"
     ENDIF
  ENDIF

  oKernel:hVar["CONTROL_ERROR"] := .F.


RETURN

//**********************************************************************

FUNCTION BuildGetX( oCajDia1, H, nColGet,nEspFil, oFonAct,nFacFon,;
                           oGetHash,oDPTHash,oSayHash ,;
                           nGetPri,nSayPri,;
                           vVecGet,vVecCol,vVecAnc,vVecVar,vVecPic,vVecWen,vVecVal,vVecDbc,vVecCom,vVecRad)

LOCAL nLonRad := 0
LOCAL N := 0
LOCAL Q := 0
LOCAL oGrpTot

LOCAL cAliTab1
LOCAL cIteSel1
LOCAL cLisIte1
LOCAL oRad
LOCAL Z  := 10
LOCAL nMulAju := 2
LOCAL nFacRad := 0 // 0.1
LOCAL nColRad := 0


DO CASE

   CASE UPPER(vVecGet) == 'G'   // GET NORMAL

        IF nGetPri == .T.
           nGetPri := .F.
        ELSE
           H := H + nEspFil
        ENDIF


        IF VALTYPE( &(vVecVar) ) == "D"
           @ H, nColGet DTPICKER oDPTHash VAR &(vVecVar) SIZE 60*nMulAju,10*nMulAju PIXEL OF oCajDia1;
                WHEN  &(vVecWen) ;
                VALID ( &(vVecVal) )

                oDPTHash:bChange = { || If( oDPTHash:lClosed, oDPTHash:PostMsg( WM_KEYDOWN, VK_RIGHT ),), oDPTHash:Refresh() }
        ELSE
           IF ( vVecCol == NIL .OR. ( len(vVecCol) == 0 )  .OR. IF(len(vVecCol) > 0, IF(vVecCol <> "OCULTA",.T.,.F.), .F. ) )

              @ H, nColGet GET oGetHash VAR &(vVecVar) PIXEL ;
                                         SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
                                         UPDATE;
                                         OF  oCajDia1 ;
                                         PICTURE vVecPic;
                                         COLOR CLR_BLUE,CLR_WHITE;
                                         WHEN  ( &(vVecWen) ) ;
                                         VALID ( &(vVecVal)  .AND. RefreshVariable(oGetHash) )



           ELSE

              @ H, nColGet GET oGetHash VAR &(vVecVar) PIXEL ; //UPDATE ;
                               SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
                               OF  oCajDia1 ;
                               UPDATE;
                               PICTURE vVecPic;
                               COLOR "W/W" , "W/W";
                               WHEN  ( &(vVecWen) ) ;
                               VALID ( &(vVecVal ) .AND. RefreshVariable(oGetHash) )

           ENDIF


        ENDIF


   CASE UPPER(vVecGet) == 'S'   // SAY COMO VALOR DE VARIABLE

        IF nSayPri= .T.
           nSayPri= .F.
        ELSE
           H := H + nEspFil
        ENDIF

        nAncVar := ( LEN(vVecVar)  + ( LEN(vVecVar) * 0.375 ) )

        IF VALTYPE(&(vVecVar)) == "C"

           @ H, nColGet GET oSayHash VAR &(vVecVar) PIXEL UPDATE ;
                            SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
                            OF  oCajDia1 ;
                            READONLY COLORS CLR_BLUE,CLR_WHITE;
                            PICTURE vVecPic

        ELSE
           @ H, nColGet GET oSayHash VAR &(vVecVar) PIXEL UPDATE ;
                            SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
                            OF  oCajDia1 ;
                            RIGHT ;
                            READONLY COLORS CLR_BLUE,CLR_WHITE;
                            PICTURE vVecPic



        ENDIF

   CASE UPPER(vVecGet) == 'C'   // COMBO

        IF nGetPri == .T.
           nGetPri := .F.
        ELSE
           H := H + nEspFil
        ENDIF

        cAliTab1 := vVecDbc[2]
        cIteSel1 := vVecDbc[3]
        cLisIte1 := vVecDbc[4]

        @ H, nColGet DBCOMBO oGetHash VAR &(vVecVar) ;
               OF oCajDia1 ;
               PIXEL                         ;
               SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
               ALIAS     ( cAliTab1 )        ;
               ITEMFIELD ( cIteSel1 )       ;
               LISTFIELD ( cLisIte1 ) ;
               ON CHANGE ( &(vVecVal)  )// .AND. RefreshVariable(oGet1) )



   CASE UPPER(vVecGet) == 'L'   // LISTBOX

   CASE UPPER(vVecGet) == 'B'   // COMBO BOX

        IF nGetPri == .T.
           nGetPri := .F.
        ELSE
           H := H + nEspFil
        ENDIF

        @ H, nColGet COMBOBOX oGetHash VAR &(vVecVar) ;
               OF oCajDia1                    ;
               PIXEL                         ;
               SIZE (GETTEXTWIDTH(0,REPLICATE("x",vVecAnc),oFonAct)*nFacFon)*nMulAju, 10*nMulAju;
               ITEMS vVecCom;
               VALID ( &(vVecVal) .AND. RefreshVariable(oGetHash) )


   CASE UPPER(vVecGet) == 'R' .OR. !EMPTY(vVecRad[2])   // RADIOBUTTOM


        IF nGetPri == .T.
           nGetPri := .F.
        ELSE
           H := H + nEspFil
        ENDIF

        nLonRad := 0
        FOR N := 2 TO LEN( vVecRad )
            IF !EMPTY(vVecRad[ N ] )
               ++nLonRad
            ENDIF
        NEXT N                                                                  //5.5

        H := H - Q
        /*
        @ H-2 ,nColGet  GROUP oGrpTot  TO H+15, nColGet + ( nLonRad * ( ( vVecAnc*nMulAju ) * 5.5 ) ) ;
                        PIXEL  PROMPT HB_OEMTOANSI( ALLTRIM(vVecRad[1]) )  OF  oCajDia1
        */
        @ H+4, nColGet+2 RADIO oRad VAR &(vVecVar)     ;
                         ITEMS ALLTRIM(vVecRad[2])  _3D ;
                         SIZE (GETTEXTWIDTH(0,REPLICATE("x",LEN(vVecRad[2])),oFonAct)*nFacFon)*nMulAju, 9*nMulAju ;
                         PIXEL  OF  oCajDia1

        nColRad := nColGet

        N := 3


        DO WHILE N <= LEN( vVecRad ) .AND. !EMPTY(vVecRad[N])

           nColRad += ( (vVecAnc*nMulAju ) *4.0) + Z    // 4.5


           @  H+7, nColRad RADIOITEM ALLTRIM(vVecRad[N]) RADIOMENU oRad  ;
                           OF  oCajDia1 ;
                           PIXEL ;
                           SIZE (GETTEXTWIDTH(0,REPLICATE("x",LEN(vVecRad[N])),oFonAct)* (nFacFon-nFacRad))*nMulAju , 6*nMulAju
           ++N


        ENDDO



        H += 4

ENDCASE


RETURN

//**************************************************************************************

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

FUNCTION CURSOR_Wcaptura( nFilArr, nColIzq, vVecOpc, vVecVar, vVecGet, vVecPic, ;
                   vVecVal, vVecWen, vVecMen, vVecAnc, cMenTit, nNroBot, ;
                   cActBot, fFunUsu, cUbiVen, lVlrVar, vVecCpo, cAliTab, ;
                   lAnexar, vVecDbc, vVecCha, vVecRad, vVecCom, vVecBot, ;
                   cFunInc, vVecCol, nAncAdi, vVecVer, cBotFor, oDlgPad, ;
                   lFocBot, vVecFol, cAjuFon, cTitAce, cTitSal )

   LOCAL oDlg
   LOCAL nFilSup := 8.7, nFilInf := 33.4
   LOCAL nTamVen, nTamDia := 22
   LOCAL nLinAdi := 0, nPixAdi := 0

   LOCAL nFacFon := 1
   LOCAL nI

   nAncAdi := IF( nAncAdi == NIL, 0, nAncAdi )

   DEFAULT cTitSal := "Salir"
   DEFAULT cTitAce := "Aceptar"
   DEFAULT vVecDbc := {}
   DEFAULT vVecCha := {}
   DEFAULT vVecRad := {}
   DEFAULT vVecCom := {}
   DEFAULT vVecBot := {}
   DEFAULT vVecCol := {}
   DEFAULT lVlrVar := .T.
   DEFAULT lAnexar := .F.
   DEFAULT lFocBot := .F.

   IF nAncAdi < 0
      nAncAdi := 0
   ENDIF

   IF LEN( vVecOpc ) == 0
      MsgAlert( "Error: Vector de opciones está vacío" )
      RETURN .F.
   ENDIF

   // Calcular tamaño de ventana
   FOR nI := 1 TO LEN( vVecOpc )
      IF vVecGet[nI] == "R"
         nPixAdi += 4
      ENDIF
   NEXT

   nLinAdi := ( nPixAdi / 12 )

   IF LEN( vVecOpc ) <= nTamDia
      nTamVen := ( ( LEN( vVecOpc ) + 3.5 + nLinAdi ) * 1.8 )
   ELSE
      nTamVen := ( ( nTamDia + 3.5 + nLinAdi ) * 1.8 )
   ENDIF

   IF cActBot != NIL
      S_lActCap := .F.
      nFilInf := nFilSup + nTamVen
   ENDIF

   DEFINE DIALOG oDlg TITLE cMenTit ;
      FROM nFilSup, 0 TO nFilInf, 90 * nFacFon + nAncAdi

   ACTIVATE DIALOG oDlg CENTER ;
      ON INIT CURSOR_InitDialogoWcaptura( oDlg, nFilArr, nColIzq, vVecOpc, ;
         vVecVar, vVecGet, vVecPic, vVecVal, vVecWen, vVecMen, vVecAnc, ;
         cMenTit, nNroBot, cActBot, fFunUsu, nFilSup, nFilInf, nTamDia, ;
         nFacFon, nAncAdi, vVecDbc, vVecCha, vVecRad, vVecCom, vVecCol, ;
         cAliTab, lAnexar, fFunUsu, vVecCpo, cTitAce, cTitSal ,lFocBot) ;
      VALID ( S_lActCap .OR. .T. )

   // Diálogo finalizado, liberar contexto superior
   PopCtx()

   oDlg:End()
   oDlg:Destroy()

RETURN S_lActCap

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

STATIC FUNCTION CURSOR_InitDialogoWcaptura( oDlg, nFilArr, nColIzq, vVecOpc, vVecVar, ;
                   vVecGet, vVecPic, vVecVal, vVecWen, vVecMen, vVecAnc, cMenTit, nNroBot, ;
                   cActBot, fFunUsu, nFilSup, nFilInf, nTamDia, nFacFon, nAncAdi, ;
                   vVecDbc, vVecCha, vVecRad, vVecCom, vVecCol, cAliTab, lAnexar, ;
                   cFunGrabar, vVecCpo, cTitAce, cTitSal,lFocBot )

   LOCAL oCajDia1, oGet
   LOCAL nColSay := 10, nEspFil := 0.1
   LOCAL nColGet, nSayMay, nGetMay, nLonSar
   LOCAL K := 15, L := 0, M := 0
   LOCAL nMulAju := 2
   LOCAL H := 1, J
   LOCAL nFilBot, nAncPan, nColDe1
   LOCAL lValVal := .F.
   LOCAL oFont
   LOCAL vVecAux := {}
   LOCAL nRowAlt := 0

   PRIVATE oBoton1, oBoton2

   DEFAULT cTitSal := "Salir"
   DEFAULT cTitAce := "Aceptar"

   // Nuevo contexto de controles para esta instancia de Wcaptura
   PushCtx( oDlg )

   // Fuente
   DEFINE FONT oFont NAME "Tahoma" SIZE 0, -12
   oDlg:SetFont( oFont )

   // Inicializar vVecWen si está vacío
   IF vVecWen == NIL .OR. LEN( vVecWen ) == 0
      vVecWen := Array( LEN( vVecOpc ) )
      FOR J := 1 TO LEN( vVecOpc )
         vVecWen[J] := ".T."
      NEXT
   ELSE
      FOR J := 1 TO LEN( vVecOpc )
         IF EMPTY( vVecWen[J] ) .OR. vVecWen[J] == NIL
            vVecWen[J] := ".T."
         ENDIF
      NEXT
   ENDIF

   // Inicializar vVecVal
   FOR J := 1 TO LEN( vVecOpc )
      IF EMPTY( vVecVal[J] ) .OR. vVecVal[J] == NIL
         vVecVal[J] := ".T."
      ENDIF
   NEXT

   // Ancho máximo del SAY
   nSayMay := LEN( vVecOpc[1] )
   FOR J := 1 TO LEN( vVecOpc )
      nLonSar := GetTextWidth( 0, vVecOpc[J], oFont:hFont )
      IF nLonSar > nSayMay
         nSayMay := nLonSar
      ENDIF
   NEXT

   // Ancho máximo del GET
   nGetMay := vVecAnc[1]
   FOR J := 1 TO LEN( vVecAnc )
      IF vVecAnc[J] > nGetMay
         nGetMay := vVecAnc[J]
      ENDIF
   NEXT

   nColGet := ( ( nSayMay + nColSay ) / 2 + 30 ) * nFacFon * nMulAju


  // Crear SAYs y GETs
   nRowAlt := 12 * nMulAju  // Altura por fila

   FOR J := 1 TO LEN( vVecOpc )

  M := 15 + ( J - 1 ) * nRowAlt

  // SAY (etiqueta)
  @ M, nColSay * nMulAju SAY vVecOpc[J] ;
     PIXEL SIZE ( nSayMay + 2 ) * nFacFon * nMulAju, 10 * nMulAju ;
     OF oDlg

  // GET o control según tipo
  CURSOR_BuildGet( oDlg, M, nColGet, oFont:hFont, nFacFon, ;
     vVecGet[J], vVecAnc[J], vVecVar[J], vVecPic[J], ;
     vVecWen[J], vVecVal[J], vVecDbc, vVecCom, vVecRad, vVecCol, J )

   NEXT J

   // Botones - por defecto mostrar Aceptar y Salir
   nAncPan := 350 * nMulAju
   nFilBot := ( LEN( vVecOpc ) + 1.5 + nEspFil ) * nRowAlt

   IF cActBot == "BOTONTERMINAR"
      nColDe1 := ( nAncPan - 140 * nMulAju ) / 2
      @ nFilBot, nColDe1 BUTTON oBoton2 PROMPT cTitSal ;
         SIZE 55 * nMulAju, 20 * nMulAju PIXEL OF oDlg ;
         ACTION ( S_lActCap := .F., oDlg:End() )
   ELSE
      @ nFilBot, nAncPan - 210 * nMulAju BUTTON oBoton1 PROMPT cTitAce ;
         SIZE 55 * nMulAju, 20 * nMulAju PIXEL OF oDlg ;
         ACTION ( ;
            lValVal := CURSOR_ValidaCampos( vVecVar, vVecVal, vVecGet ), ;
            IF( lValVal, ;
               IF( cFunGrabar != NIL .AND. cFunGrabar == "GRABARTABLA", ;
                  _GrabarTabla( vVecVar, vVecCpo, cAliTab, lAnexar, vVecAux ), ;
                  IF( cFunGrabar != NIL, &( cFunGrabar ), NIL ) ;
               ), ;
               NIL ;
            ), ;
            S_lActCap := lValVal, ;
            IF( lValVal, oDlg:End(), NIL ) ;
         )

  @ nFilBot, nAncPan - 140 * nMulAju BUTTON oBoton2 PROMPT cTitSal ;
     SIZE 55 * nMulAju, 20 * nMulAju PIXEL OF oDlg ;
     ACTION ( S_lActCap := .F., oDlg:End() )
   ENDIF

   IF lFocBot
      BEGIN SEQUENCE
         IF oBoton1 != NIL
            oBoton1:SetFocus()
         ENDIF
      RECOVER
      END SEQUENCE
   ENDIF

RETURN .T.

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

STATIC FUNCTION CURSOR_BuildGet( oDlg, nRow, nColGet, hFont, nFacFon, ;
   cTipo, nAnc, cVar, cPic, cWhen, cValid, vVecDbc, vVecCom, vVecRad, vVecCol, nIdx )

   LOCAL nMulAju := 2
   LOCAL nAncho
   LOCAL aItems
   LOCAL nI

   // Ancho del GET (GetTextWidth puede no existir en todas las versiones)
   BEGIN SEQUENCE
      nAncho := GetTextWidth( 0, REPLICATE( "x", nAnc ), hFont ) * nFacFon * nMulAju
   RECOVER
      nAncho := nAnc * 8 * nFacFon * nMulAju
   END SEQUENCE

   DO CASE

  CASE UPPER( cTipo ) == "G"   // GET normal

     IF VALTYPE( &( cVar ) ) == "D"
        @ nRow, nColGet DTPICKER oDtp VAR &( cVar ) ;
           SIZE 60 * nMulAju, 14 * nMulAju PIXEL OF oDlg ;
           WHEN &( cWhen ) ;
           VALID &( cValid )
        // Registrar control tipo GET asociado a este índice
        RegGetCtrl( nIdx, oDtp )
     ELSE
        @ nRow, nColGet GET oGet VAR &( cVar ) ;
           PIXEL SIZE nAncho, 14 * nMulAju ;
           OF oDlg ;
           PICTURE cPic ;
           WHEN &( cWhen ) ;
           VALID &( cValid )
        RegGetCtrl( nIdx, oGet )
     ENDIF

  CASE UPPER( cTipo ) == "S"   // SAY (solo lectura)

     @ nRow, nColGet GET oGet VAR &( cVar ) ;
        PIXEL SIZE nAncho, 14 * nMulAju ;
        OF oDlg ;
        PICTURE cPic ;
        READONLY
     // Registrar como SAY (aunque internamente sea un GET readonly)
     RegSayCtrl( nIdx, oGet )

  CASE UPPER( cTipo ) == "B"   // COMBOBOX

     IF vVecCom != NIL .AND. LEN( vVecCom ) >= nIdx
        aItems := vVecCom[nIdx]
        IF VALTYPE( aItems ) != "A"
           aItems := { aItems }
        ENDIF
        @ nRow, nColGet COMBOBOX oGet VAR &( cVar ) ;
           ITEMS aItems ;
           SIZE nAncho, 14 * nMulAju PIXEL OF oDlg ;
           VALID &( cValid )
        RegGetCtrl( nIdx, oGet )
     ENDIF

  CASE UPPER( cTipo ) == "C"   // DBCOMBO

     IF vVecDbc != NIL .AND. LEN( vVecDbc ) >= nIdx .AND. LEN( vVecDbc[nIdx] ) >= 4
        @ nRow, nColGet DBCOMBO oGet VAR &( cVar ) ;
           ALIAS vVecDbc[nIdx][2] ;
           ITEMFIELD vVecDbc[nIdx][3] ;
           LISTFIELD vVecDbc[nIdx][4] ;
           SIZE nAncho, 14 * nMulAju PIXEL OF oDlg ;
           VALID &( cValid )
        RegGetCtrl( nIdx, oGet )
     ENDIF

  CASE UPPER( cTipo ) == "R"   // RADIO - vVecRad[nIdx] := { "Label", "Opt1", "Opt2", ... }

     IF vVecRad != NIL .AND. LEN( vVecRad ) >= nIdx .AND. LEN( vVecRad[nIdx] ) >= 2
        aItems := {}
        FOR nI := 2 TO LEN( vVecRad[nIdx] )
           AAdd( aItems, vVecRad[nIdx][nI] )
        NEXT
        @ nRow, nColGet RADIO oRad VAR &( cVar ) ;
           ITEMS aItems ;
           SIZE nAncho, 12 * nMulAju PIXEL OF oDlg
        RegGetCtrl( nIdx, oRad )
     ENDIF

   ENDCASE

RETURN NIL

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

STATIC FUNCTION CURSOR_ValidaCampos( vVecVar, vVecVal, vVecGet )

   LOCAL lOk := .T.
   LOCAL J
   LOCAL cMensaje := ""

   FOR J := 1 TO LEN( vVecVar )
      IF vVecGet[J] != "S"  // No validar SAYs
         BEGIN SEQUENCE
            IF ! &( vVecVal[J] )
               lOk := .F.
               cMensaje += vVecVar[J] + " - Validación fallida" + CRLF
            ENDIF
         RECOVER
            lOk := .F.
            cMensaje += "Error en validación de " + vVecVar[J] + CRLF
         END SEQUENCE
      ENDIF
   NEXT

   IF ! lOk .AND. ! EMPTY( cMensaje )
      MsgAlert( cMensaje, "Validación" )
   ENDIF

RETURN lOk

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

//-----------------------------------------------------------------------------
// Manejo de pila de contextos de diálogo (para soportar múltiples instancias
// y llamadas recursivas de Wcaptura sin solapar controles)

STATIC FUNCTION PushCtx( oDlg )

   // Nuevo nivel en la pila
   AAdd( aDlgStack, oDlg )
   AAdd( aGetStack, {} )
   AAdd( aSayStack, {} )

RETURN Len( aDlgStack )   // índice actual (por si se necesita)

//-----------------------------------------------------------------------------
STATIC FUNCTION PopCtx()

   IF Len( aDlgStack ) > 0
      ASize( aDlgStack, Len( aDlgStack ) - 1 )
   ENDIF

   IF Len( aGetStack ) > 0
      ASize( aGetStack, Len( aGetStack ) - 1 )
   ENDIF

   IF Len( aSayStack ) > 0
      ASize( aSayStack, Len( aSayStack ) - 1 )
   ENDIF

RETURN NIL

//-----------------------------------------------------------------------------
// Registrar controles en el contexto actual

STATIC FUNCTION RegGetCtrl( nIdx, oCtrl )

   LOCAL nTop := Len( aGetStack )

   IF nTop == 0 .OR. nIdx <= 0
      RETURN NIL
   ENDIF

   IF Len( aGetStack[ nTop ] ) < nIdx
      ASize( aGetStack[ nTop ], nIdx )
   ENDIF

   aGetStack[ nTop ][ nIdx ] := oCtrl

RETURN NIL

//-----------------------------------------------------------------------------
STATIC FUNCTION RegSayCtrl( nIdx, oCtrl )

   LOCAL nTop := Len( aSayStack )

   IF nTop == 0 .OR. nIdx <= 0
      RETURN NIL
   ENDIF

   IF Len( aSayStack[ nTop ] ) < nIdx
      ASize( aSayStack[ nTop ], nIdx )
   ENDIF

   aSayStack[ nTop ][ nIdx ] := oCtrl

RETURN NIL

//-----------------------------------------------------------------------------
// Helpers para usar dentro de expresiones vVecVal (seguros ante recursión)

FUNCTION RefreshSay( nIdx )

   LOCAL nTop := Len( aSayStack )

   IF nTop > 0 .AND. nIdx > 0 .AND. nIdx <= Len( aSayStack[ nTop ] )
      IF aSayStack[ nTop ][ nIdx ] != NIL
         aSayStack[ nTop ][ nIdx ]:Refresh()
      ENDIF
   ENDIF

RETURN .T.

//-----------------------------------------------------------------------------
FUNCTION RefreshGet( nIdx )

   LOCAL nTop := Len( aGetStack )

   IF nTop > 0 .AND. nIdx > 0 .AND. nIdx <= Len( aGetStack[ nTop ] )
      IF aGetStack[ nTop ][ nIdx ] != NIL
         aGetStack[ nTop ][ nIdx ]:Refresh()
      ENDIF
   ENDIF

RETURN .T.

//********************

FUNCTION RefreshVariable( oCtrl )

   LOCAL nTop, nIdx

   // Solo esperamos objetos
   IF ValType( oCtrl ) != "O"
      RETURN .T.
   ENDIF

   // 1) Buscar en SAYs del contexto actual
   nTop := Len( aSayStack )
   IF nTop > 0
      FOR nIdx := 1 TO Len( aSayStack[ nTop ] )
         IF aSayStack[ nTop ][ nIdx ] == oCtrl
            RETURN RefreshSay( nIdx )
         ENDIF
      NEXT
   ENDIF

   // 2) Buscar en GETs del contexto actual
   nTop := Len( aGetStack )
   IF nTop > 0
      FOR nIdx := 1 TO Len( aGetStack[ nTop ] )
         IF aGetStack[ nTop ][ nIdx ] == oCtrl
            RETURN RefreshGet( nIdx )
         ENDIF
      NEXT
   ENDIF

   // 3) Si no está registrado en los stacks, refrescar directo (fallback)
   BEGIN SEQUENCE
      //oCtrl:Refresh()

  _RefreshVariable(oCtrl)

   RECOVER
   END SEQUENCE

RETURN .T.

//*****************************************

FUNCTION _RefreshVariable(oObjDes,cNomObj)

   TRY
       IF oObjDes <> NIL
          IF oObjDes <> nil .and. VALTYPE(oObjDes) == "O"
             oObjDes:Refresh()
          ENDIF
       ENDIF

CATCH
  RETURN .T.
END


RETURN .T.


function _GrabarTabla(...)

   // implementar

return
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usano IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Fri Feb 13, 2026 06:10 PM

Jonsson, An interesting approach.

While reading this, I started wondering:
What if we take it one step further and let it generate HTML directly?

As an experiment, I asked an AI to generate an example (see below).
Technically, this works without any issues — but the resulting generator-style source code quickly becomes hard to read and difficult to maintain.

And honestly, reality has changed.

Back then:
→ Generators saved a massive amount of time.
→ Boilerplate was tedious.
→ UI structure required significant effort.

Today:
→ AI can generate clean markup in seconds.
→ A complete screen can be created very quickly.
→ Adjustments are immediate.

As a result, the complexity shifts.

Maybe this is the new reality.

Just compare the options yourself and take a look at the generated source code.

Best regards,
Otto

Example 1: Generator-Based Approach

formular.php

<?php

function Wcaptura(array $config)
{
    $title  = $config['title'] ?? 'Formular';
    $fields = $config['fields'] ?? [];
    $errors = [];

// Verarbeitung bei POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    foreach ($fields as $field) {

        $name  = $field['name'];
        $value = $_POST[$name] ?? '';

        // Pflichtfeld?
        if (!empty($field['required']) && trim($value) === '') {
            $errors[$name] = $field['label'] . " darf nicht leer sein.";
        }

        // Optionale Validierungsfunktion
        if (isset($field['validate']) && is_callable($field['validate'])) {
            $result = $field['validate']($value);
            if ($result !== true) {
                $errors[$name] = $result;
            }
        }
    }

    if (empty($errors)) {
        return ['success' => true, 'data' => $_POST];
    }
}

// Ausgabe Formular
echo "<h2>{$title}</h2>";
echo "<form method='post'>";

foreach ($fields as $field) {

    $name     = $field['name'];
    $label    = $field['label'];
    $type     = $field['type'] ?? 'text';
    $value    = $_POST[$name] ?? '';
    $max      = $field['maxlength'] ?? '';
    $readonly = !empty($field['readonly']) ? 'readonly' : '';

    echo "<div style='margin-bottom:15px'>";
    echo "<label><strong>{$label}</strong></label><br>";

    switch ($type) {

        case 'text':
            echo "<input type='text'
                    name='{$name}'
                    value='" . htmlspecialchars($value) . "'
                    maxlength='{$max}'
                    {$readonly}>";
            break;

        case 'date':
            echo "<input type='date' name='{$name}' value='{$value}'>";
            break;

        case 'select':
            echo "<select name='{$name}'>";
            foreach ($field['options'] as $opt) {
                $selected = ($value == $opt) ? "selected" : "";
                echo "<option {$selected}>{$opt}</option>";
            }
            echo "</select>";
            break;

        case 'radio':
            foreach ($field['options'] as $opt) {
                $checked = ($value == $opt) ? "checked" : "";
                echo "<label>
                        <input type='radio' name='{$name}' value='{$opt}' {$checked}>
                        {$opt}
                      </label> ";
            }
            break;
    }

    if (isset($errors[$name])) {
        echo "<div style='color:red;margin-top:5px'>{$errors[$name]}</div>";
    }

    echo "</div>";
}

echo "<button type='submit'>Aceptar</button> ";
echo "<button type='reset'>Salir</button>";
echo "</form>";

return ['success' => false];
}

index.php

<?php

function Wcaptura(array $config)
{
    $title  = $config['title'] ?? 'Formular';
    $fields = $config['fields'] ?? [];
    $errors = [];

// Verarbeitung bei POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    foreach ($fields as $field) {

        $name  = $field['name'];
        $value = $_POST[$name] ?? '';

        // Pflichtfeld?
        if (!empty($field['required']) && trim($value) === '') {
            $errors[$name] = $field['label'] . " darf nicht leer sein.";
        }

        // Optionale Validierungsfunktion
        if (isset($field['validate']) && is_callable($field['validate'])) {
            $result = $field['validate']($value);
            if ($result !== true) {
                $errors[$name] = $result;
            }
        }
    }

    if (empty($errors)) {
        return ['success' => true, 'data' => $_POST];
    }
}

// Ausgabe Formular
echo "<h2>{$title}</h2>";
echo "<form method='post'>";

foreach ($fields as $field) {

    $name     = $field['name'];
    $label    = $field['label'];
    $type     = $field['type'] ?? 'text';
    $value    = $_POST[$name] ?? '';
    $max      = $field['maxlength'] ?? '';
    $readonly = !empty($field['readonly']) ? 'readonly' : '';

    echo "<div style='margin-bottom:15px'>";
    echo "<label><strong>{$label}</strong></label><br>";

    switch ($type) {

        case 'text':
            echo "<input type='text'
                    name='{$name}'
                    value='" . htmlspecialchars($value) . "'
                    maxlength='{$max}'
                    {$readonly}>";
            break;

        case 'date':
            echo "<input type='date' name='{$name}' value='{$value}'>";
            break;

        case 'select':
            echo "<select name='{$name}'>";
            foreach ($field['options'] as $opt) {
                $selected = ($value == $opt) ? "selected" : "";
                echo "<option {$selected}>{$opt}</option>";
            }
            echo "</select>";
            break;

        case 'radio':
            foreach ($field['options'] as $opt) {
                $checked = ($value == $opt) ? "checked" : "";
                echo "<label>
                        <input type='radio' name='{$name}' value='{$opt}' {$checked}>
                        {$opt}
                      </label> ";
            }
            break;
    }

    if (isset($errors[$name])) {
        echo "<div style='color:red;margin-top:5px'>{$errors[$name]}</div>";
    }

    echo "</div>";
}

echo "<button type='submit'>Aceptar</button> ";
echo "<button type='reset'>Salir</button>";
echo "</form>";

return ['success' => false];
}

Example 2: Direct AI-Generated Markup

<?php
$errors = [];
$success = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

$xCamCla = trim($_POST['xCamCla'] ?? '');
$cCamDes = trim($_POST['cCamDes'] ?? '');
$cCodDia = trim($_POST['cCodDia'] ?? '');

if ($xCamCla === '') {
    $errors['xCamCla'] = "Código ist erforderlich.";
}

if (empty($errors)) {
    $success = true;
    // Hier speichern
}
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Creación de Unidades de Medida</title>

<style>
body {
    margin: 0;
    background: #f2f2f7;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.wrapper {
    max-width: 420px;
    margin: 40px auto;
    padding: 20px;
}

.card {
    background: white;
    padding: 25px;
    border-radius: 18px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.05);
}

h1 {
    text-align: center;
    font-size: 20px;
    margin-bottom: 25px;
}

.field {
    margin-bottom: 18px;
}

label {
    display: block;
    font-size: 14px;
    color: #8e8e93;
    margin-bottom: 6px;
}

input {
    width: 100%;
    padding: 14px;
    border-radius: 14px;
    border: 1px solid #e5e5ea;
    background: #fafafa;
    font-size: 16px;
}

input:focus {
    outline: none;
    border-color: #007aff;
    box-shadow: 0 0 0 3px rgba(0,122,255,0.15);
    background: white;
}

.error {
    font-size: 13px;
    color: #ff3b30;
    margin-top: 5px;
}

button {
    width: 100%;
    padding: 14px;
    border-radius: 14px;
    border: none;
    font-size: 16px;
    background: #007aff;
    color: white;
    cursor: pointer;
}

button:hover {
    background: #0066dd;
}

.success {
    margin-top: 20px;
    padding: 12px;
    background: #e6f7ff;
    border-radius: 12px;
    text-align: center;
    color: #007aff;
}
</style>
</head>

<body>

<div class="wrapper">
    <div class="card">

    <h1>Creación de Unidades de Medida</h1>

    <form method="post">

        <div class="field">
            <label>Código</label>
            <input type="text" name="xCamCla" maxlength="12"
                   value="<?= htmlspecialchars($_POST['xCamCla'] ?? '') ?>">
            <?php if(isset($errors['xCamCla'])): ?>
                <div class="error"><?= $errors['xCamCla'] ?></div>
            <?php endif; ?>
        </div>

        <div class="field">
            <label>Descripción</label>
            <input type="text" name="cCamDes" maxlength="40"
                   value="<?= htmlspecialchars($_POST['cCamDes'] ?? '') ?>">
        </div>

        <div class="field">
            <label>Código DIAN</label>
            <input type="text" name="cCodDia" maxlength="10"
                   value="<?= htmlspecialchars($_POST['cCodDia'] ?? '') ?>">
        </div>

        <button type="submit">Aceptar</button>

    </form>

    <?php if($success): ?>
        <div class="success">
            Guardado correctamente ✓
        </div>
    <?php endif; ?>

</div>
</div>

</body>
</html>
Posts: 410
Joined: Sun Jan 31, 2010 03:30 PM
Re: Usano IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Fri Feb 13, 2026 06:58 PM

Otto.. buena tarde...

Te adelanto algo de ia generando codigo..

Los gestores o mantenimientos de tablas comunes y el mismo menu de mi APP FIVEWIN... las creo desde tablas con sus definiciones por tabla y dinamicamente se construye el browse-- los folder.. botonones ... formularios.,,, etc

Le pedi a gemini 3, que generara crud completo (frontEnd y backEnd), usuando estas tablas de definiciones y que el rest api o endPoint, lo hiciera con la respectiva tabla.... mi frontend es ANGULAR (template PRIMENG) Y el backend NODEJS (nestjs)... a hoy ya tengo solucionado, ingreso, validacion, jwt token, menu, permisos, crud basicos, integridad referencial (por logica / orm nodejs-prima), para base de datos sin integridad referencial (dbf migradas a sql), multitenencia (db segun cliente), gestion automatica de tablas fechadas, ...solo en 8 dias...

Y hoy empece a validar el codigo actual de fivewin, con el primer resultado, bastante bueno...

Saludos

Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Fri Feb 13, 2026 09:28 PM

8 days with AI sounds impressive.

But:

Login, JWT, and CRUD are standard building blocks. Angular and NestJS already provide established patterns. Prisma removes a significant amount of boilerplate and infrastructure work.

This is not an attack. It’s simply context.

The real test comes:

6 months later. Maintainability. Edge cases. Performance. Migration.

Best regards, Otto

Posts: 410
Joined: Sun Jan 31, 2010 03:30 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Sat Feb 14, 2026 03:24 PM

Otto.. Buen dia...

Si correcto tienes razon ...

Pero para ti que te gusta analizar y filosofar.. y de hecho creo que tambien has llegado a esta conclusion :

! ay algo mas costoso que quedar varado...a la mitad del camino... asistencia, calidad tecnológica, etc ! ?

Ahora veamos la implementacion web para mi motor de generacion de formularios dinamicos :

// defino mi formulario dinamico
initialConfig: DynamicFormConfig = {
        title: 'Formulario de Prueba',
        submitLabel: 'Guardar cambios',
        cancelLabel: 'Cancelar',
        fields: [
            {
                key: 'nombre',
                label: 'Nombre Completo',
                type: 'text',
                width: 6,
                validations: { required: true, minLength: 3 }
            },
            {
                key: 'email',
                label: 'Correo Electrónico',
                type: 'text',
                width: 6,
                validations: { required: true, email: true }
            },
            {
                key: 'tipo',
                label: 'Tipo de Usuario',
                type: 'select',
                width: 4,
                options: [
                    { label: 'Administrador', value: 'ADMIN' },
                    { label: 'Usuario', value: 'USER' },
                    { label: 'Invitado', value: 'GUEST' }
                ]
            },
            {
                key: 'activo',
                label: 'Estado',
                type: 'radio',
                width: 8,
                options: [
                    { label: 'Activo', value: true },
                    { label: 'Inactivo', value: false }
                ]
            },
            {
                key: 'fecha',
                label: 'Fecha de Registro',
                type: 'date',
                width: 6
            },
            {
                key: 'newsletter',
                label: 'Suscribirse al Newsletter (Switch)',
                type: 'switch',
                width: 6
            },
            {
                key: 'ciudad',
                label: 'Ciudad (Tipo "C" - Alias de Select)',
                type: 'C',
                width: 6,
                options: [
                    { label: 'Bogotá', value: 'BOG' },
                    { label: 'Medellín', value: 'MED' },
                    { label: 'Cali', value: 'CLO' }
                ]
            },
            {
                key: 'intereses',
                label: 'Intereses (Tipo "L" - Personalizado)',
                type: 'L',
                width: 12,
                tooltip: 'Seleccione sus áreas de interés principal',
                style: { 'width': '100%', 'border': '2px solid var(--primary-color)', 'border-radius': '8px' },
                options: [
                    { label: 'Tecnología', value: 'TEC' },
                    { label: 'Finanzas', value: 'FIN' },
                    { label: 'Deportes', value: 'DEP' },
                    { label: 'Arte', value: 'ART' }
                ]
            }
        ]
    };

 // ejecuto mi formulario dinamico
    ejemploFormularioTest() {
        this.jsonConfig = JSON.stringify(this.initialConfig, null, 2);
        this.applyConfig();

    // Subscribe to global form state to demonstrate the "Traffic Light"
    this.formStateService.result$.subscribe(result => {
        console.log('Global Form State:', result);
        if (result.success) {
            this.messageService.add({ severity: 'success', summary: 'Estado Global: ÉXITO', detail: 'El usuario aceptó el formulario.' });
        } else {
            this.messageService.add({ severity: 'warn', summary: 'Estado Global: CANCELADO', detail: 'El usuario canceló el formulario.' });
        }
    });
}
Posts: 410
Joined: Sun Jan 31, 2010 03:30 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Sat Feb 14, 2026 03:34 PM

Siguiente tarea....

las definiciones de cada formulario leerla de mi tabla actual xharbour - fivewin : E:\SERVIDOR_DESARROLLO\FORMULARIOS_DINAMICOS.DBF (.DAT)

y en el frontEnd... BOTON : CARGAR_DEFINICIONES() .... DATA_FORMULARIO_DINAMICO( SQL FROM .DBF).. solo cada vez que diseñe un nuevo formulario....

Listo ya puedo usar mis 200... formularios dinamicos... creado ahora de forma dinamica en cada solicitud o servicio, desde mi motor_generador_formularios_dinamicos("formulario_1", "Crear log")

Tiempo estimado : PROMPT.. PLANEACION ...EJECUTAR... PROBAR ... REALIMNENTAR : 1 HORA

Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Sat Feb 14, 2026 06:00 PM

Jsonsson, When I read this — without knowing more context — it reminds me somewhat of classic dBase-style generators.

But as we’ve already discussed, systems, development teams, and problem domains are structured very differently.

For many scenarios, such an engine can absolutely make sense.

What I’m less certain about is whether it can produce truly ergonomic, mobile-optimized data entry screens without further refinement — especially in more complex process-driven contexts.

In the end, it largely depends on whether the primary focus is on structural standardization or on process optimization.

Best regards, Otto

Posts: 1445
Joined: Mon Oct 10, 2005 02:38 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Sun Feb 15, 2026 07:52 AM
Otto wrote:

6 months later.
Maintainability.
Edge cases.
Performance.
Migration.

Maintainability -->> AI
Edge cases -->> AI
Performance -->> AI
Migration -->> AI

Al que te cambia los neumáticos de las ruedas del coche dile que no haga con palancas, sin usar esa herramienta/máquina actual que tienen ahora los garajes. Depende de su edad posiblemente no sabrá hacerlo en la práctica (en teoría si, lo habrá leído).

La AI ha venido para quedarse, tu y yo NUNCA seremos usuarios nativos de AI, los que tienen 15 años lo serán (si no lo son ya).
Tu y yo queremos leer el código y entenderlo, ellos ni lo intentaran.
Ellos tienen unas ventajas/desventajas y nosotros las nuestras.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Sun Feb 15, 2026 08:37 AM

Carlos,

if we take customer management as a concrete example — where an iPhone is typically used for quick lookup, brief updates, or focused interactions — how would you structure the initial screen?

From your practical experience: do you think AI would naturally generate a process-driven interface adapted to real customer workflows, or would it tend to default to standardized CRUD-style forms?

I’m genuinely interested in how you see this in real-world usage.

Best regards, Otto

Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Mon Feb 16, 2026 07:37 PM

Build fast, responsive sites with Bootstrap

regars !!!
CCC.

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Mon Feb 16, 2026 07:55 PM

In a real iPhone product, you want: full control over colors full control over spacing full control over interaction no cascade battles If you use Bootstrap and constantly override it, then: You pay for 200 KB of CSS and write another 150 KB against it. That’s economically inefficient.

Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Mon Feb 16, 2026 08:19 PM

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Mon Feb 16, 2026 09:15 PM

My friend, Yes, Bootstrap works on iPhone and is technically mobile-first in terms of responsive layout.

But there is a difference between:

• responsive web design and • building a workflow-driven mobile product

Bootstrap ensures layout compatibility. It does not define interaction architecture.

For a real iPhone product used as a daily operational tool, the questions are:

• How fast is the interaction? • How minimal is the UI? • How controlled is the styling? • How easy is long-term maintenance?

And ultimately, the decision depends on your level of ambition.

If your goal is a responsive website, Bootstrap is perfectly fine.

If your goal is a focused, process-driven mobile tool with long-term maintainability and full control, the foundation matters much more.

Best regards, Otto

Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: Usando IA o AI, para depurar o desarrollar (x)harbour + fivewin ....!!! ?
Posted: Mon Feb 16, 2026 09:19 PM

saludos Otto !!!

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "

Continue the discussion