Inicio > Ejemplos, Multiidioma, XE3 > Programas multiidioma con Delphi

Programas multiidioma con Delphi

jueves, 25 de octubre de 2012 Dejar un comentario Ir a comentarios

flags-all-countries_6130Ya he hablado en otras ocasiones de cómo generar un aplicación multiidioma en Delphi y de paquetes tanto comerciales, como los componentes siComponents, como de código abierto como GNU GetText. En esta entrada hablaba de ambos y explicaba cómo acometer este proceso.

Aplicación multiidioma con GNU GetText

Hace tiempo había revisado el sistema de internacionalizar aplicaciones de Delphi (en este caso en la versión 6) y no me pareció muy intuitivo, tal vez también por falta de algo de documentación. Por lo que he visto en las versiones nuevas, pocas cosas han variado en el proceso y en las herramientas que trae el IDE.

En este caso me he visto obligado por las circunstancias a utilizarlo, y aunque a priori me ha resultado un poco “confuso”, como en su momento, una vez puesto en marcha, el sistema la verdad es que no es complejo y funciona de forma bastante sencilla. Se echa en falta que determinados aspectos sean un poco más potentes, como el editor de traducciones o el repositorio y la forma en que funcionan. Estos dos elementos realizan su función pero son bastante básicos en comparación con otros paquetes que hay en el mercado.

El sistema de traducción de Delphi, se basa en añadir todos los recursos traducidos a una DLL; Una para cada idioma que necesitamos añadir a nuestra aplicación.


EL PROYECTO

Imagen44Para ver el proceso completo de internacionalización crearemos un proyecto sencillo, con dos formularios y veremos que es relativamente rápido montar toda la estructura para que funcione en varios idiomas.

Algunas etiquetas, un memo con algunos strings, unos botones y un segundo formulario para comprobar un ejemplo con más de uno y un TComboBox que nos permitirá modificar el idioma en tiempo de ejecución.

Una vez que tenemos nuestro proyecto funcionando, comencemos el proceso para añadirle dos nuevos idiomas, en este caso el catalán y el inglés, al que ya tiene por defecto (español o castellano).


INTERNACIONALIZACIÓN

Para ello lo primero que debemos hacer es añadir los 2 nuevos idiomas desde el menú de Project.

en la imagen inferior podéis ver las pantallas del asistente, aunque no tiene ninguna complicación y lo que hacemos con él es añadir los idiomas (tantos como necesitemos) a la aplicación.

internacionalizacion

Una vez finalizado el asistente, veremos que el IDE ha generado dos proyectos más (en nuestro caso) correspondientes a los idiomas que hemos seleccionado.

Imagen45

Podemos probar a compilar y grabar todos los proyectos.

Lo siguiente es comenzar a traducir las cadenas para poder utilizar múltiples idiomas en la aplicación. El editor de cadenas es similar a muchas otros aplicaciones que hay para esta función. Se trata de una pantalla que nos muestra las cadenas actuales y donde debemos introducir las cadena introducidas.

Para acceder al “Translation Manager” podemos hacerlo desde el menú en: “Project / Languages / Update resource DLLs”.

Imagen47

En esta pantalla vemos a la izquierda la estructura del proyecto y los diferentes formularios que lo componen. A la derecha la zona que nos permite traducir las diferentes cadenas. Hay columnas que identifican el elemento (ID), la que contiene las cadenas en el lenguaje original de la aplicación y la que contendrá las cadenas traducidas, en este caso con el título de “Inglés (estados Unidos)”.

He marcado en rojo una cadena que ya aparece traducida automáticamente (&Cerrar – &Close).  Este es debido a que esta cadena ya está traducida en el repositorio.


EL REPOSITORIO

El “Transation Repository” o “Repositorio” es como un diccionario de traducciones que podemos ir ampliando a medida que traducimos aplicaciones. De esta forma, podemos reutilizar las cadenas que ya hemos traducido anteriormente (en la misma aplicación o en otras). En el ejemplo que estamos viendo, mi repositorio ya tiene incluida la traducción desde el Español (internacional) al Inglés (Estados unidos) de la palabra &Cerrar. Por eso al acceder a las traducciones, esta palabra ya aparece traducida.

Imagen48El repositorio nos permite acelerar la traducción de términos. Además posee opciones para importar y exportar traducciones, con lo que podemos compartirlos o incluso utilizar herramientas de traducción automáticas externas e importar las traducciones a él.

Una vez que las cadenas están traducidas para los formularios podemos añadirlas al repositorio desde el “Translation Manager” , para tenerlas disponibles más adelante.


EJECUCIÓN

Una vez traducidas y añadidas al repositorio todas las cadenas de los diferentes idiomas, compilamos los proyectos, tanto el original, como los de los diferentes idiomas.

Para probar la ejecución, podemos seleccionar desde el menú de “Project” cual es el idioma que queremos por defecto. Si probamos con alguno de los 2 idiomas y ejecutamos, veremos que efectivamente la aplicación, como era de esperar.

Por último, nos quedaría ver cómo modificar el idioma durante la ejecución de la aplicación. Es bastante simple y para ello hay una sección en la ayuda del propio Delphi a la que podéis acceder; Dentro de la «internacionalización de aplicaciones» hay un tema concreto llamado «Dynamic switching of resource DLLs». Allí se puede leer que basta con añadir la unit Reinit en el uses, y utilizar una línea como la siguiente para cambiar el idioma.

// Cargar los recursos y releer los forms
if (LoadNewResourceModule(lang) < > 0) then begin
  ReinitializeForms;
end;

Comentar que si en alguna versión de Delphi, no encontráis la unit ReInit, podéis buscar dentro del directorio de Demos.

Al final el código que hay más arriba va a ser el único que vamos a necesitar en la aplicación.

Para apoyar la entrada, además del código de ejemplo, he añadido en este caso un vídeo.

 

[youtube dTIo5Oh-wmw]

Como siempre podéis descargar el código del ejemplo desde este link.

<DESCARGAR CÓDIGO FUENTE>

Espero que os haya sido útil y hasta la próxima.

Vota este post
  1. Jose Ángel
    viernes, 26 de octubre de 2012 a las 09:36 | #1

    Hola, muy interesante el artículo, estoy probando el XE3 y veo que lleva un componente Lang que no me ha funcionado como yo esperaba, ¿Que valoración te merece este componente? Comparado con el método que expones en el artículo.

    Un saludo.

  2. Neftalí
    viernes, 26 de octubre de 2012 a las 09:51 | #2

    @Jose Ángel
    Hola Jose Ángel.
    ¿Me puedes dar más detalles sobre este componente? Así tal como me lo describes no se a qué componente te refieres.

    Un saludo.

  3. Jose Ángel
    viernes, 26 de octubre de 2012 a las 10:00 | #3

    Hola, con el XE3 viene algún ejemplo de su uso, es el TLang

    http://docwiki.embarcadero.com/Libraries/XE2/en/FMX.Types.TLang

    Pero a mí no me traduce todo de forma correcta, creo que los controles deben tener el Autotranslate a true, pero ya te digo que sólo he hecho unas pruebas.

  4. Neftalí
    viernes, 26 de octubre de 2012 a las 11:29 | #4

    @Jose Ángel
    Hola Jose Ángel.
    Ahora ya se a qué componente te refieres; Estaba pensando en la VCL y no en FireMonkey. Este componente que trae FM es bastante sencillo y te facilita el trabajo, como muchos otros de volcar a ficheros de texto las cadenas traducidas de un formulario (un fichero por idioma).
    Una vez cambias de idioma en ejecución, el componente modifica las cadenas visibles en el form por las del fichero correspondiente al idioma.
    He revisado el ejemplo y a mi sí me funciona, aunque como te digo es bastante básico.

    En este caso no se si podrás utilizar un sistema como este, bastante más potente (http://neftali.clubdelphi.com/?p=688)

    Un saludo.

  5. MAXIUM
    lunes, 29 de octubre de 2012 a las 04:10 | #5

    Neftalí, me perdí con tus instrucciones

    [IMG]http://i49.tinypic.com/55il8x.png[/IMG]

  6. Neftalí
    lunes, 29 de octubre de 2012 a las 13:31 | #6

    @MAXIUM

    Hola Maxium.
    ¿En qué punto? ¿En qué lugar del video te has perdido?

  7. MAXIUM
    martes, 30 de octubre de 2012 a las 04:48 | #7

    Saludos Neftali.

    En tu ejemplo no hay forma de que vuelva al español una vez cambiado al ingles.

    Lo otro, es que al agregar o eliminar algún componente posterior a editar los idiomas y a pesar de actualizar, no resulta. Tengo que cerrar y volver a abrir Delphi.

  8. Neftalí
    martes, 30 de octubre de 2012 a las 10:12 | #8

    @MAXIUM

    «En tu ejemplo no hay forma de que vuelva al español una vez cambiado al ingles.»
    ¿Pero te refieres a en diseño o a ejecución?.
    Revisa que las DLL’s estén en el mismo directorio del EXE (en ejecución) y en diseño se hace utilizando el menú.

    En lo segundo que comentas no me he fijado y diría que no me ha pasado. ¿Tal vez algun problema de instalación?

  9. MAXIUM
    miércoles, 31 de octubre de 2012 a las 13:55 | #9

    ¿Pero te refieres a en diseño o a ejecución?.

    Mmmm… en ambos casos… pero es una cosa de lógica de código. Al reiniciar el formulario en ingles, queda seleccionado el español como primera opción, como no se detecta cambio al seleccionar español que ya esta seleccionado, sigue quedando todo en ingles… Habrá de usar un .ini o uso del registro.

    ¿Donde se ubica dicha DLL?, la aplicación la arranco sin ella a la vista y funciona de todos modos.

  10. Neftalí
    miércoles, 31 de octubre de 2012 a las 14:02 | #10

    @MAXIUM
    Hola Maxium.
    Creo que ya te entiendo; Lo primero tal vez sea un defecto del ejemplo. Como tú dices la selección se deberá guardar en otro lugar.
    Las DLL’s (que son los ficheros de idioma .ENU, .CAT,…), deben estar en el mismo directorio de la aplicación. Si no están, la aplicación no da error, pero simplemente no tendrás acceso a traducir; Cuando intentes la traducción no hará nada.

    Un saludo.

  11. dec
    viernes, 16 de noviembre de 2012 a las 13:25 | #11

    Hola,

    Otro conjunto de componentes que podéis probar para internacionalizar y localizar vuestras aplicaciones hechas con Delphi es el «Paquete I18n» de Delphi Area. Se trata de un conjunto de componentes que, no solamente hacen sencilla la tarea mencionada, pero, tiene en cuenta muchas cuestiones que no son tenidas en cuenta, generalmente: calendarios, fechas, diálogos, etc. Por lo menos no dejéis de echarle un vistazo. Yo mismo uso estos componentes en dos de mis proyectos con excelentes resultados.

  12. Neftalí
    viernes, 16 de noviembre de 2012 a las 14:00 | #12

    @dec

    Apuntado queda David. Gracias por el aviso.

    Un saludo.

  13. cabezasariel
    jueves, 5 de diciembre de 2013 a las 19:37 | #13

    hola: en primer lugar muy buen post, yo trate de hacer lo que dices en el ejemplo tengo delphixe2 y componentes devexpres y todo bien pero a la hora de dar f9 me sale el siguiente error resource TcxImageResourceForm not found, y no me deja seguir, has chocado con este error alguna vez, ojala puedas ayudarme

  14. Neftalí
    viernes, 6 de diciembre de 2013 a las 16:30 | #14

    @cabezasariel
    Hola.
    Ese recurso es de las DevExpress, así que el problema está en los componentes. Revisa que la instalación sea correcta o dirígete a la página de los componentes para encontrar información sobre ese error o que te faciliten ayuda sobre cómo resolverlo.
    Tal vez no tengas la versión correcta o te falte alguna actualización.
    Un saludo.

  15. cabezasariel
    lunes, 9 de diciembre de 2013 a las 15:28 | #15

    hola, tambien me pasa con el fast report que viene con el delphixe2, me sale un error de recursos, el de los devpexpress lo solucione poniendo en comentario la linea en la unit del devexpress que me estaba lanzando el error, era una inicializacion, pero el problema con el fast report es que me da el error pero al no tener los fuentes no hay forma de arreglar, existira alguna otra solucion? saludos

  16. Neftalí
    lunes, 9 de diciembre de 2013 a las 16:58 | #16

    @cabezasariel
    Sólo se me ocurren dos formas de arreglarlo.
    (1) Si tienes el fichero, puedes añadir el directorio al path de búsqueda de forma que te lo encuentre a la hora de compilar.
    (2) Tal y como has hecho tú, puedes comentar esa línea del código fuente, pero en ese caso, aunque te compile, es posible que el componente no funcione del todo al 100% pues esos recursos serán necesarios en algún momento.

    Si no tienes ese fichero y no posees el código para modificarlo, no veo solución para corregir el problema. De todas formas, en cualquier caso deberías dirigirte a los fabricantes de los componentes para que te ofrezcan una solución «satisfactoria» (me refiero a no tener que comentar líneas de los fuentes).

    Un saludo.

  17. Arturo
    jueves, 17 de enero de 2019 a las 16:15 | #17

    Neftali, Hola.
    Disculpa que te moleste pero quisiera hacerte una consulta. Tengo una aplicación hecha en Delphi XE7, con base de datos SQLite, funciona todo bien, pero cuando pongo una imagen dentro de un TText o un button y ejecuto la aplicación en el movil se cuelga la aplicacion justo cuando visualizo le Boton o el TText quito las imagenes y funciona normal.
    Se tiene que configurar algo?, extesiones bmp, jgp. png y no las acepta en android.

  18. viernes, 18 de enero de 2019 a las 12:59 | #18

    @Arturo

    Hola Arturo.
    No debería haber problema con las imágenes. Puedes utilizar PNG, JPG y/o BMP sin problemas.

  19. José A.
    viernes, 7 de mayo de 2021 a las 21:17 | #19

    Hola.
    He estado buscando como trabajar con varios idiomas y me he encontrado con tu explicación. Me ha servido de mucho.
    Por otro lado me pasa como en el video y como han comentado más arriba, que una vez cambiado a otro idioma no puedo volver al español. No es por lógica del ejemplo, lo he probado ‘a pelo’ cambiando en una línea y volviendo a cambiar en la siguiente y en esta la función LoadNewResourceModule() devuelve 0. Sabes si hay alguna solución?
    Gracias por todo

  20. lunes, 10 de mayo de 2021 a las 08:27 | #20

    Hola José.
    Personalmente no recomiendo trabajar con los componentes estandard de Delphi para traducciones (aunque haya hecho este artículo para mostrar como funcionan), porque no son cómodos y nada intuitivos (incluso en algunas versiones dan bastantes errores).
    Hay otros que he explicado en otros artículos que creo que funcionan mejor.
    Dicho esto, revisa que tengas las DLLs en el lugar correcto y que los recursos se cargan correctamente.

    Otra opción es añadir como idioma extra el Español Internacional, de forma que te cre una nueva DLL llamada (PInternacional.ESN). De esa forma fuerzas a que la carge cada vez que cambias el idioma.

    Proyecto con DLLs de multiidioma

    De esta forma, cada vez que cambias el idioma fuerzas a que se cargue de nuevo la DLL (inluyendo la del español).

    ejemplo

  21. José A.
    martes, 11 de mayo de 2021 a las 21:07 | #21

    @Germán Estévez
    Gracias por tu respuesta. Precisamente me he encontrado con problemas de que algunas caption de los títulos de columna de dbgrid no aparecen para traducir. Sólo cambiando el contenido en el inspector de objetos aparece para traducir (Nombre lo cambié a Participante p.e.)
    Ahora estoy mirando IniLang2 0.9.03 (no sé si hay otra mas reciente). Qué te parece? Necesito algo sencillo.
    Buenas noches y Gracias

  22. miércoles, 12 de mayo de 2021 a las 08:35 | #22

    @José A.
    Hola José.
    Revisa DkLang, en su día lo miré y también hay una entrada en el blog que puedes revisar:
    https://neftali.clubdelphi.com/internacionalizar-aplicaciones-con-dklang/

    Haz alguna prueba con las últimas versiones a ver si funciona correctamente y te funciona bien.

    Un saludo.

  1. Sin trackbacks aún.