FoxPress – Abril 2006

 

MultiIdioma

http://www.fpress.com/

 

Por Francisco San Pablo                             idioma.zip
 

¿Cómo hacer una aplicación Multiidioma? La respuesta es aparentemente sencilla, en vez de usar los caption de los objetos, con cadenas monoidiomáticas, puedes hacer que  guarden un valor numérico y apunten a una tabla con las cadenas especificadas para los diversos idiomas.

 

   El planteamiento es correcto pero ver ‘en diseño’ esas pantallas  sería bastante depresivo pues serían una colección de números sin aparente sentido. Además al estar diseñando tendrías que estar constantemente guardando en la tabla de cadenas las diversas cadenas y sus equivalencias. Te exigiría una disciplina verdaderamente germánica.

 

   Una alternativa, que es la que aquí propongo es crearnos una tabla con los name de los objetos e invocarla en el INIT de los formulario y si se encuentra la cadena especificada para el idioma deseado entonces se da el ‘cambiazo’. Si no se encuentra se mantiene la cadena que se ha puesto en el diseñador.

 

   Es un sistema bastante cómodo pues la aplicación que ya tienes acabada y funcionando le puedes poner en el .INIT del Form la llamada al método que luego te voy a escribir y tu aplicación ‘monolingüe’ pasa a ser una aplicación multilingue sin odiosos y costosos cambios. Además permite que tu aplicación siga entregándose y funcionando mientras acabas la traducción de todos los textos pues cuando no existe un texto alternativo para el idioma deseado te toma el de por defecto.

 

   Bien, pues aquí está el código que como no es demasiado extenso te lo pongo todo.

 

   Primero, te trascribo el método o función que se da una vuelta por todos los objetos del formulario viendo si el name coincide con el name guardado en la tabla de idiomas SYSIDIOM. Si se encuentra y estamos en el idioma especificado entonces se procede a cambiar el caption del objeto.

 

*---- CAMBIAIDIOMA ---- *

*

LPARAMETERS loObjTratar, lcNombreObj

 

LOCAL lnNumObj, lnCont, lcExpBusqueda, lcAuxExp, lcAuxClase, ;

      lnCont2, lnNumAux

 

IF NOT USED("SYSIDIOM")

  SELECT 0

  USE SYSIDIOM

  SET ORDER TO TAG CLAVE

ELSE

  SELECT SYSIDIOM

ENDIF

 

*- Clase a la que pertenece el objeto de objeto

lcAuxClase = UPPER(loObjTratar.baseClass)

 

*- Expresión de búsqueda general, se cambia luego si es necesario

lcExpBus = PADR( ALLTRIM(lcNombreObj) + "." + ;

                loObjTratar.name, 50 ) + gcIdioma

 

lcExpBusqueda = PADR( ALLTRIM(SYS(1272,loobjtratar)), 50 ) + gcIdioma

 

DO CASE

 

  CASE lcAuxClase = "FORM"

 

    *- Expresión de búsqueda general, se cambia luego si es necesario

    lcExpBusqueda = PADR( "screen." + loObjTratar.name, 50 ) + gcIdioma

       

    *- Cambia el título si es un form

    IF SEEK( lcExpBusqueda, "SYSIDIOM")

      lcAuxExp = ALLTRIM( SYSIDIOM.descrip )

      loObjTratar.caption = lcAuxExp

    ENDIF

 

    lnNumObj = loObjTratar.ControlCount

 

    FOR lnCont = 1 TO lnNumObj

      THIS.mcambiaidioma(loObjTratar.Controls(lnCont), loObjTratar.name)

    ENDFOR

 

  CASE lcAuxClase = "CONTAINER"

 

    lnNumObj = loObjTratar.ControlCount

 

    FOR lnCont = 1 TO lnNumObj

      THIS.mcambiaidioma(loObjTratar.Controls(lnCont), loObjTratar.name)

    ENDFOR

 

  CASE lcAuxClase = "OPTIONGROUP" OR lcAuxClase = "COMMANDGROUP"

   

    *- Número de botones

    lnNumAux = loObjTratar.ButtonCount

   

    FOR lnCont2 = 1 TO lnNumAux

      lcExpBusqueda = PADR(ALLTRIM(lcNombreObj) + "." + ;

                           loObjTratar.name + "." + ;

                           loObjTratar.Buttons(lnCont2).name, 50) + ;

                      gcIdioma

 

      IF SEEK( lcExpBusqueda, "SYSIDIOM")

        lcAuxExp = ALLTRIM( SYSIDIOM.descrip )

        loObjTratar.Buttons(lnCont2).caption = lcAuxExp

      ENDIF

    ENDFOR

 

  CASE lcAuxClase = "PAGEFRAME"

   

    *- Número de pestañas

    lnNumAux = loObjTratar.pageCount

   

    FOR lnCont2 = 1 TO lnNumAux

      lcExpBusqueda = PADR(ALLTRIM(lcNombreObj) + "." + ;

                           loObjTratar.name + "." + ;

                           loObjTratar.pages(lnCont2).name, 50) + ;

                      gcIdioma

 

      IF SEEK( lcExpBusqueda, "SYSIDIOM")

        lcAuxExp = ALLTRIM( SYSIDIOM.descrip )

        loObjTratar.pages(lnCont2).caption = lcAuxExp

      ENDIF

    ENDFOR

 

  CASE lcAuxClase = "GRID"

   

    lnCont2 = 1

   

    DO WHILE .T.

 

      *- Continua mientras hay columnas que tratar

      IF TYPE('loObjTratar.columns(lnCont2)') <> "O"

        EXIT

      ENDIF

   

      *- Procesa los controles que hay dentro de una columna

      xx = loObjTratar.columns(lnCont2).ControlCount

   

      FOR lnx = 1 TO xx

        THIS.mcambiaidioma(loObjTratar.columns(lnCont2), lcNombreObj)

      ENDFOR

       

      lnCont2 = lnCont2 + 1

    ENDDO

 

  CASE lcAuxClase = "COLUMN"

   

    lnCont2 = 1

   

    DO WHILE .T.

 

      *- Continua mientras hay controles que tratar

      IF TYPE('loObjTratar.controls(lnCont2)') <> "O"

        EXIT

      ENDIF

   

      THIS.mcambiaidioma(loObjTratar.controls(lnCont2), lcNombreObj)

      lnCont2 = lnCont2 + 1

 

    ENDDO

 

  CASE lcAuxClase = "LABEL" OR ;

       lcAuxClase = "COMMANDBUTTON" OR ;

       lcAuxClase = "CHECKBOX" OR ;

       lcAuxClase = "HEADER"

 

    IF SEEK( lcExpBusqueda, "SYSIDIOM")

      lcAuxExp = ALLTRIM( SYSIDIOM.descrip )

      loObjTratar.caption = lcAuxExp

    ENDIF

 

ENDCASE

 

El código anterior, debe ser invocado desde el INIT del formulario. Al llegar a ese método ya existen todos los objetos pero todavía no se visualizan y es el momento conveniente para cambiarlos. Si tienes una clase que gobierna todos los formularios es el sitio oportuno para ponerla. Si no la tienes deberías usar un código parecdio al que ahora te pongo para invocar la función o método que realiza un inventario de todos los objetos del formulario y realiza los cambios oportunos:

 

 

*

*  CAMBIAMOS IDIOMA

*

*- Expresión de búsqueda

 

lcExpBusqueda = PADR(THISFORM.name, 50 ) + gcIdioma

 

IF NOT USED("SYSIDIOM")

  SELECT 0

  USE SYSIDIOM

  SET ORDER TO TAG CLAVE

ELSE

  SELECT SYSIDIOM

ENDIF

 

*- Cambia el título principal de la ventana

IF SEEK( lcExpBusqueda, "SYSIDIOM")

  lcAuxExp = ALLTRIM( SYSIDIOM.descrip )

  THISFORM.caption = lcAuxExp

ENDIF

 

lnNumObj = THISFORM.ControlCount

 

FOR lnCont = 1 TO lnNumObj

  oAPP.mcambiaidioma(THISFORM.Controls(lnCont), THISFORM.name)

ENDFOR

 

Unicamente reseñar que los campos de la tabla SYSIDIOMA son:

 

OBJETO C(30), Idioma C(3), Descrip C(30)

 

Rellenada de la siguiente forma

 

FrmMain.lblFile.Caption        CAS                                                  Archivo

FrmMain.lblFile.Caption        ENG                                                  File

FrmMain.Caption                 ENG                                                  Help

FrmMain.lblFile.Caption        SPA                                                  Ayuda

 
 

 

 

FoxPress – Abril de 2006

© 2006 FoxPress. All rights reserved