MDI

User avatar
Daniel Garcia-Gil
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita
Contact:

Re: MDI

Post by Daniel Garcia-Gil »

Saludos David

esto es algo sencillo no te compliques con un codigo dificil de depurar despues (mi humilde punto de vista)...

estas cometiendo un par de errores importantes

1.- Estas usando esta variable estatica nWnd que a medida que abres dialogos se incrementa y cada vez que pulsas un boton estas ejecutando la accion contenida en el ultimo valor de nWnd, por eso siempre ves que se actiualiza el ultimo dialogo, para que lo veas con claridad puedes ubicar esto en el boton "VER" MsgInfo( aObjVar( oDlg, nWnd ):cTitle )

2.- Cada dialogo abierto funcionaria como un area de trabajo independiente, debes seleccionar alias usas en cada uno, para eso debes usar bGotFocus()

te expongo un ejemplo tratando de seguir un poco tu estilo, es sencillo de comprender, no hay muchas complicaciones con arrays ni defines, trabaja con variables locales

Code: Select all


#include "FiveWin.ch"

static oWndPrinc
static nWnd 


**********************************************************************************************************************
function Main()
**********************************************************************************************************************

   DEFINE WINDOW oWndPrinc Title "Ventanas" MDI MENU MenuPrin()
   ACTIVATE WINDOW oWndPrinc MAXIMIZED

return nil

**********************************************************************************************************************
function MenuPrin()
**********************************************************************************************************************

   local oMenu

   MENU oMenu

   MENUITEM "&Ventanas" 
       MENU
          MENUITEM "&Ventanas" ACTION ( ManArt() )
       ENDMENU 
   ENDMENU

return oMenu

**********************************************************************************************************************
function ManArt()
**********************************************************************************************************************
local cAlias, oDlgs
local oCli, aObj := Array( 5 )

   if nWnd = nil
      nWnd := 1
   else
      // Hacer control ventanas máximas.
      nWnd ++ 
   endif

   cAlias := NewAlias( "Clients.dbf" )

   DbUseArea( .T.,, "Clients.dbf", cAlias, .t., .f. )
   DATABASE oCli
   oCli:Load()
   oCli:bBOF = { || MsgInfo( "Primer Registro" ) }
   oCli:bEOF = { || MsgInfo( "Último Registro" ) }
   

   DEFINE DIALOG oDlgs TITLE "Diáologo: " + Str( nWnd ) FROM 0,0 TO 20,40 OF oWndPrinc
   
   oDlgs:bGotFocus := {||  DBSELECTAREA( cAlias ) }
   
   @ 1, 1 SAY aObj[ 1 ] PROMPT oCli:Name OF oDlgs UPDATE

   @ 2, 1 SAY aObj[ 2 ] PROMPT oCli:Adress OF oDlgs UPDATE

   @ 5, 1 BUTTON aObj[ 3 ] PROMPT "Anterior" OF oDlgs;
                 ACTION ( oCli:Skip( -1 ) , If( oCli:BoF(), MsgBeep(),), oDlgs:Update() )

   @ 6, 1 BUTTON aObj[ 4 ] PROMPT "Siguiente" OF oDlgs;
                 ACTION ( oCli:Skip(),;
                 Iif( oCli:EoF(), oCli:Skip( -1 ),), oDlgs:Update() )
                 
   @ 7, 1 BUTTON aObj[ 5 ] PROMPT "Ver" OF oDlgs;
                 ACTION ( MsgInfo( "Alias: " + cAlias + CRLF +;
                                   "Valor nWnd: " + Str( nWnd ) ) )

   ACTIVATE DIALOG oDlgs NOWAIT CENTERED;
      ON INIT ( aObj[ 4 ]:SetFocus(), oDlgs:Move( 0, 0 ) );
      VALID ( ( oCli )->( DbCloseArea() ), .t. )

return nil

**********************************************************************************************************************
function NewAlias( cNomDbf )
**********************************************************************************************************************
  static nNum := 0
  local cAlias := ""

  nNum++
  cAlias := SubStr( cFileNoExt( cFileName( cNomDbf ) ), 1, 4 ) + LTRIM( STR( nNum ) )
return ( cAlias )
 
 
our best documentation is the source code
Isla de Margarita Venezuela.
danielgarciagil@gmail.com
http://tdolphin.blogspot.com/
https://www.dropbox.com/referrals/NTI5N ... rc=global9
User avatar
sysctrl2
Posts: 833
Joined: Mon Feb 05, 2007 7:15 pm
Contact:

Re: MDI

Post by sysctrl2 »

no es recomendable usas variables locales en ventanas MDI,

tampoco, en lo particular no me gustan los alias,,

Code: Select all

FUNCTION UseClientes()

   IF _buscaAlias( 'CLIENTES' )
      dbselectArea( 'CLIENTES' )
   else
      use( _ruta() + 'CLIENTES.dbf') new SHARED
   ENDIF

return alias()
Cesar Cortes Cruz
SysCtrl Software
Mexico

' Sin +- FWH es mejor "
triumvirato
Posts: 199
Joined: Tue Apr 22, 2008 9:54 am
Location: Valladolid, Spain.

Re: MDI

Post by triumvirato »

Daniel,

Muchas gracias por tu ejemplo y ayuda. Quería comentarte varias cosas al respecto:
Daniel Garcia-Gil wrote: 1.- Estas usando esta variable estatica nWnd que a medida que abres dialogos se incrementa y cada vez que pulsas un boton estas ejecutando la accion contenida en el ultimo valor de nWnd, por eso siempre ves que se actiualiza el ultimo dialogo, para que lo veas con claridad puedes ubicar esto en el boton "VER" MsgInfo( aObjVar( oDlg, nWnd ):cTitle )
Correcto, el problema que me he encontrado es nWnd, que va cambiando su valor durante la ejecución del programa, por eso buscaba una manera de calcular el "índice" de la ventana activa y actualizarlo al seleccionar dicha ventana con un bGotFocus(), pero sigo siendo incapaz de dar con ello.
Daniel Garcia-Gil wrote: 2.- Cada dialogo abierto funcionaria como un area de trabajo independiente, debes seleccionar alias usas en cada uno, para eso debes usar bGotFocus()

te expongo un ejemplo tratando de seguir un poco tu estilo, es sencillo de comprender, no hay muchas complicaciones con arrays ni defines, trabaja con variables locales
Entiendo esta parte también perfectamente, lo único que yo lo hacía con digamos "mi sistema", al generar un alias nuevo y luego hacer referencia a él con nWnd.

El problema ahora mismo es la gran duda que tengo sobre cómo se ha de programar correctamente un entorno MDI. Los ejemplos, consejos y algún manualillo que he encontrado, refieren todos a hacerlo de esa manera y desaconsejan, como comenta el compañero sysctrl2 el uso de variables locales, si bien yo entiendo que su uso debe ser el más general para el encapsulado de funciones. Contradictorio como puedes ver y sin una luz muy clara al respecto.
Desde luego que llevas bastante razón en que esta manera de codificar es bastante enrevesada para su depuración...

Muchas gracias!
Post Reply