Falla creacion de controles diámicos dentro de un diálogo

Post Reply
User avatar
gsabattino
Posts: 100
Joined: Fri Oct 14, 2005 12:03 am
Location: Valencia, Venezuela

Falla creacion de controles diámicos dentro de un diálogo

Post by gsabattino »

Saludos a Todos...

Estoy migrando a FW+xH una aplicación de Laboratorio que esta hecha con FoxPro 2.6 (viejito solo texto)...
El primer problema que se me presentó fue que el autor de la aplicación en Fox utilizó indices IDX a los cuales no pude acceder con xHarbour, pero con la ayuda de algo de documentación que aun se consigue me enteré que FP2.6 también puede manejar indices CDX compatibles con xHarbour, y luego de dedicarle algún tiempo retocando programas hice la migración de IDX a CDX y tengo ambas aplicaciones conviviendo sin problemas a nivel de DBF's...

Ahora se me presenta otro problemita, y es que para tomar los datos de los resultados de los análisis el autor de la aplicación en Fox utilizó una DBF para generar las pantallas (leyendas y get's incluidos) ... cosa que en un principio lo vi como algo absurdo, pero luego de involucrarme mas con la actividad de laboratorio le encontré el sentido al método... son muchas pantallas... de haberse ido por el método convencional tendría que haber hecho no menos de 80 módulos los cuales resolvió solo con uno apoyado en la DBF... Y no solo eso, sino que añadir un examen mas a la aplicación es cuestión de solo añadir los records necesarios a la DBF y listo...

Porque digo que se me presenta el problemita???... pues se trata de migrar una aplicación en Texto a Gráfico... Ya he dibujado 10 diálogos y me falta un montón... Cada diálogo que dibujo tengo que hacer su respectiva asociación a nivel de Prg... Entonces se me ocurrió la idea... Porque no aplicar la misma técnica de tener una DBF y dibujar los controles dinamicamente??? Y es aquí donde se me trancó la cosa... Los controles say's y get's (que es por donde estoy comenzando) que trato de dibujar en forma dinámica dentro del dialogo entran en conflicto con los controles estáticos...

A continuación parte de lo que estoy intentando...

Code: Select all

  ConfResult->( DBSeek( RenglFact->Examen ) )
  do while ( .not. ConfResult->( EOF() ) ) .and. ( ConfResult->Examen=RenglFact->Examen )
    cControl  :=alltrim( ConfResult->Control )
    do case
      case cControl='WTITLE'
        // Este funciona perfecto... claro... actúa sobre un control estático
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():ReDefine( 501, bSay, oResult:oDlg, '',,,, oControl:oFontSS9 )

      case cControl='WSAY'
        // Este no funciona...
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():New( ConfResult->Row, ConfResult->Col, bSay, oResult:oDlg, '',;
                                        oControl:oFontSS9, ( ConfResult->Align=='C' ), ( ConfResult->Align=='R' ),,,,,;
                                        ConfResult->Width, 12 )

        /*
Copiado solo para referencia de los parámetros que debo pasar.
METHOD New( nRow, nCol, bText, oWnd, cPicture, oFont,;
            lCentered, lRight, lBorder, lPixels, nClrText, nClrBack,;
            nWidth, nHeight, lDesign, lUpdate, lShaded, lBox, lRaised ) CLASS TSay
        */
    endcase
    ConfResult->( DBSkip() )
  enddo
se produce este error...
Application
===========
Path and name: D:\Sistemas\CVF\Lab32.EXE (32 bits)
Size: 1,522,176 bytes
Time from start: 0 hours 0 mins 4 secs
Error ocurred at: 31/08/2007, 09:18:08
Error description: Error FiveWin/2 Duplicated Id: No: 111

Stack Calls
===========
Called from TDIALOG:DEFCONTROL(326)
Called from TSAY:NEW(127)
Called from GENERICO1P(58)
Called from (b)RESULTADOS(85)
Called from (b)RESULTADOS(170)
Called from TCONTROL:LDBLCLICK(1692)
Called from TWBROWSE:LDBLCLICK(1583)
Called from TWINDOW:HANDLEEVENT(0)
Called from TWBROWSE:HANDLEEVENT(1267)
Called from _FWH(3001)
Called from DIALOGBOX(0)
Called from TDIALOG:ACTIVATE(254)
Called from RESULTADOS(212)
Called from (b)MAINBUTTBAR(290)
Called from TBTNBMP:CLICK(311)
Called from TBTNBMP:LBUTTONUP(479)
Called from TWINDOW:HANDLEEVENT(0)
Called from TBTNBMP:HANDLEEVENT(1267)
Called from _FWH(3001)
Called from WINRUN(0)
Called from TWINDOW:ACTIVATE(860)
Called from MAIN(163)


Ciertamente el control 111 existe en el diálogo y corresponde a un combobox dibujado estáticamente.
A continuación el código del diálogo en el RC.

Code: Select all

Resultados_TomaDatos DIALOG 10, 20, 510, 280
STYLE DS_MODALFRAME | 0x4L | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dlg_Edit"
FONT 6, "MS Sans Serif"
{
 GROUPBOX "", 5001, 1, 24, 508, 256, BS_GROUPBOX
 COMBOBOX 111, 50, 34, 120, 140, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 COMBOBOX 112, 231, 34, 120, 140, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 CONTROL 0, 201, "EDIT", ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP, 473, 34, 30, 12
 RTEXT "Temperatura (\xBAC) _:", -1, 405, 36, 64, 8
 RTEXT "Tecnica _:", -1, 188, 36, 40, 8
 RTEXT "Muestra _:", -1, 6, 36, 40, 8
 CTEXT "Titulo", 501, 145, 56, 220, 10
}
Lo que no termino de entender es porque si estoy intentando crear un objeto Say por el método New() el mismo intenta montarse sobre el combobox???

O es que no se pueden combinar controles dinámicos y estáticos en un diálogo???

O es que los diálogos solo funcionan con controles estáticos???

O es que debo ir pensando seriamente en la posibilidad de buscarme otro oficio???

1GB de Gracias de antemano por los comentarios...

Giancarlo J. Sabattino S.
Valencia, Venezuela
User avatar
karinha
Posts: 4882
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Post by karinha »

Error FiveWin/2 Duplicated Id: No: 111

CREA UN LOOPING PARA INCREMENTAR LOS ID´S.

ID := 101

ID := ID + 1

Y asi se va...

Regards, saludos.
João Santos - São Paulo - Brasil
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

La clase TControl usa un dato de clase:
CLASSDATA nInitID INIT 100

Auméntala para que no entre en conflicto con los IDs del recurso: <oCualquierControl>:nInitID := 800

solo es necesario que lo modifiques una vez
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
gsabattino
Posts: 100
Joined: Fri Oct 14, 2005 12:03 am
Location: Valencia, Venezuela

Post by gsabattino »

Antonio, no me funciono tu sugerencia...

* Modifique la clase en la linea donde me indicastes y ::GetNewId() devuelve valores relacionados con la modificación.
* Modifique la clase Say para que ::New() admitiera como un ultimo parámetro el identificador y colocando por defecto la llamada a ::GetNewId()... DEFAULT nId :=::GetNewId() y luego asignarlo a la variable de instancia ::nId
* Probé cambiando directamente en el código a ::nId luego de haber declarado el control.

En todos _ el error que se produce es por que no existe el Id, y lo curioso es que justo antes de la activación de diálogo coloqué una parada que me mostrara los Id's de todos los controles del diálogo, y la cantidad de controles como la Id de cada uno corresponde con lo que se le ha asignado bien por recurso (que ya vienen pre-definidos), bien por asignación automática (llamada a ::GetNewId()), o por asignación manual modificando el método New de la clase.

Application
===========
Path and name: D:\Sistemas\CEVALFES\Lab32.EXE (32 bits)
Size: 1,525,760 bytes
Time from start: 0 hours 0 mins 7 secs
Error ocurred at: 02/09/2007, 09:35:59
Error description: Error FiveWin/1 Non defined Id: No: 201

Stack Calls
===========
Called from TCONTROL:INITIATE(364)
Called from TGET:INITIATE(355)
Called from __OBJSENDMSG(0)
Called from OSEND(220)
Called from ASEND(171)
Called from TDIALOG:INITIATE(588)
Called from TDIALOG:HANDLEEVENT(766)
Called from CREATEDLG(0)
Called from TDIALOG:ACTIVATE(283)
Called from TPAGES:DEFAULT(146)
Called from (b)TPAGES(27)
Called from TPAGES:INITIATE(0)
Called from __OBJSENDMSG(0)
Called from OSEND(220)
Called from ASEND(171)
Called from TDIALOG:INITIATE(588)
Called from TDIALOG:HANDLEEVENT(766)
Called from DIALOGBOX(0)
Called from TDIALOG:ACTIVATE(254)
Called from TESTHIPOOSMOTICO(38)
Called from (b)RESULTADOS(85)
Called from (b)RESULTADOS(170)
Called from TCONTROL:LDBLCLICK(1692)
Called from TWBROWSE:LDBLCLICK(1583)
Called from TWINDOW:HANDLEEVENT(0)
Called from TWBROWSE:HANDLEEVENT(1287)
Called from _FWH(3001)
Called from DIALOGBOX(0)
Called from TDIALOG:ACTIVATE(254)
Called from RESULTADOS(212)
Called from (b)MAINBUTTBAR(290)
Called from TBTNBMP:CLICK(311)
Called from TBTNBMP:LBUTTONUP(479)
Called from TWINDOW:HANDLEEVENT(0)
Called from TBTNBMP:HANDLEEVENT(1287)
Called from _FWH(3001)
Called from WINRUN(0)
Called from TWINDOW:ACTIVATE(860)
Called from MAIN(163)

En el primer post olvide colocar que estoy utilizando FW2.4 con xH0.993 por si acaso eso tiene algo que ver.

Por lo pronto he seguido dibujando pantallas a nivel de recursos...

Gracias de antemano por los comentarios,

Giancarlo J. Sabattino S.
Valencia, Venezuela.
FiveWiDi
Posts: 910
Joined: Mon Oct 10, 2005 2:38 pm

Re: Falla creacion de controles diámicos dentro de un diálog

Post by FiveWiDi »

[quote="gsabattino"]Saludos a Todos...

Code: Select all

  ConfResult->( DBSeek( RenglFact->Examen ) )
  do while ( .not. ConfResult->( EOF() ) ) .and. ( ConfResult->Examen=RenglFact->Examen )
    cControl  :=alltrim( ConfResult->Control )
    do case
      case cControl='WTITLE'
        // Este funciona perfecto... claro... actúa sobre un control estático
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():ReDefine( 501, bSay, oResult:oDlg, '',,,, oControl:oFontSS9 )

      case cControl='WSAY'
        // Este no funciona...
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():New( ConfResult->Row, ConfResult->Col, bSay, oResult:oDlg, '',;
                                        oControl:oFontSS9, ( ConfResult->Align=='C' ), ( ConfResult->Align=='R' ),,,,,;
                                        ConfResult->Width, 12 )

    endcase
    ConfResult->( DBSkip() )
  enddo
Ya que le metes mano, porque no nombras casa variable segun su tipo (notación úngara le llaman creo)? Para mi oSay sería un objeto no un array, ahora bien aoSay si sería para mi una array de objetos Say.

Que se supone que valor debe retornar:
_cItem :=strtrim( nItem, 2 )
entiendo que sería una cadena de 2 y 'n' decimales (creo que _SET_DECIMALS() o algo así definiría 'n').
yo preferiría _cItem :=strtrim( nItem, 2, 0 )

Si _cItem será una cadena y oSay una array, entonces oSay[ &_cItem ] debería reventar no?

Bueno y todo esto con todo mi respeto, yo he sufrido mis propias barbarides en cuanto a código despues de años de modificaciones.
Saludos
Carlos G.
FiveWiDi
Posts: 910
Joined: Mon Oct 10, 2005 2:38 pm

Re: Falla creacion de controles diámicos dentro de un diálog

Post by FiveWiDi »

[quote="gsabattino"]Saludos a Todos...

Code: Select all

  ConfResult->( DBSeek( RenglFact->Examen ) )
  do while ( .not. ConfResult->( EOF() ) ) .and. ( ConfResult->Examen=RenglFact->Examen )
    cControl  :=alltrim( ConfResult->Control )
    do case
      case cControl='WTITLE'
        // Este funciona perfecto... claro... actúa sobre un control estático
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():ReDefine( 501, bSay, oResult:oDlg, '',,,, oControl:oFontSS9 )

      case cControl='WSAY'
        // Este no funciona...
        aAdd( oSay, NIL )
        nItem     :=len( oSay )
        _cItem    :=strtrim( nItem, 2 )
        bSay      :={ ||  alltrim( ConfResult->Leyenda ) }
        oSay[ &_cItem ]   :=TSay():New( ConfResult->Row, ConfResult->Col, bSay, oResult:oDlg, '',;
                                        oControl:oFontSS9, ( ConfResult->Align=='C' ), ( ConfResult->Align=='R' ),,,,,;
                                        ConfResult->Width, 12 )

        /*
Copiado solo para referencia de los parámetros que debo pasar.
METHOD New( nRow, nCol, bText, oWnd, cPicture, oFont,;
            lCentered, lRight, lBorder, lPixels, nClrText, nClrBack,;
            nWidth, nHeight, lDesign, lUpdate, lShaded, lBox, lRaised ) CLASS TSay
        */
    endcase
    ConfResult->( DBSkip() )
  enddo
No será
oSay[ nItem ] := ...
en vez de
oSay[ &_cItem ] := ...

Saludos
Carlos G.
User avatar
gsabattino
Posts: 100
Joined: Fri Oct 14, 2005 12:03 am
Location: Valencia, Venezuela

Post by gsabattino »

El problema de crear controles dinámicamente en un diálogo ha quedado resuelto...

El asunto está que no se pueden crear controles en forma dinámica si el diálogo viene como un recurso en lugar de crearse por programa...
O sea... para poder crear controles a punta de código el diálogo también tiene que haberse creado a punta de código...
Sería interesante que Antonio nos comentara algo acerca del porqué esa limitación...


Saludos a todos...

Giancarlo J. Sabattno S.
Valencia, Venezuela
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Giancarlo,

No existe tal limitación. Aquí tienes un ejemplo funcionando correctamente:

test.prg

Code: Select all

#include "FiveWin.ch"

function Main()

   local oDlg

   DEFINE DIALOG oDlg RESOURCE "test"

   REDEFINE BUTTON ID 120 OF oDlg ACTION MsgInfo( "resource" )

   ACTIVATE DIALOG oDlg ;
      ON INIT AddControl( oDlg )

return nil

function AddControl( oDlg )

   @ 5, 3 BUTTON "source" OF oDlg ACTION MsgInfo( "source" ) SIZE 72, 23
   
return nil   
test.rc

Code: Select all

test DIALOG 70, 67, 194, 119
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Test"
FONT 8, "MS Sans Serif"
{
 DEFPUSHBUTTON "resources", 120, 11, 25, 50, 14
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
gsabattino
Posts: 100
Joined: Fri Oct 14, 2005 12:03 am
Location: Valencia, Venezuela

Post by gsabattino »

Antonio, es probable que la versión de FW que estoy utilizando sea la que me este dando problemas (FW2.4+xH0.993)...
El ejemplo que colocastes no funciona... igual revienta dando el mensaje
Error FiveWin/1 Non defined Id: No: 801

Por lo pronto ya sustituí en el programa la declaración del diálogo desde recursos por su creación desde código y con una prueba con 1 combobox, 1 group, 3 says y 2 gets, todos con parámetros tomados desde una DBF, está funcionando como esperaba...

1GB de Gracias


Giancarlo J. Sabattino S.
Valencia, Venezuela.
Post Reply