IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

[TUTO]Application multilingue "dynamique" et "automatique"


Sujet :

C++Builder

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    83
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 83
    Par d�faut [TUTO]Application multilingue "dynamique" et "automatique"
    Comment cr�er une application multilingue

    D'apr�s le sondage, j'ai vu que la plupart voulait un tuto sur �a. Programmeur depuis des nombreuses ann�es,
    je voudrais partager mes connaissances sur ma fa�on de traduire mes applications.

    1�) Ce qu'il nous faut

    - Borland C++ builder 2005/2006 ou autre.

    2�) Construction des fichiers de langues

    La premi�re �tape consiste � cr�er notre propre fonction qui permettra de traduire l'application. La m�thode consiste
    � chercher parmis tous les composants de la "form", les composants qui sont inscrit dans notre fichier de langue.


    Cr��ons une simple application o� on va placer 2 boutons, 2 labels...

    Nous allons maintenant cr�er un fichier de langue par exemple : fr.lng

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    [Form1_Form]
    Form1=titre en français
     
     
    [Form1_Label]
    Label1=Label en français
    Label2=Label2 en français
     
    [Form1_Button]
    Button1=Français
    Button2=Anglais
    On va sauvegarder ce fichier dans le m�me r�pertoire que notre application.

    Ensuite on va cr�er un deuxi�me fichier qu'on va nommer : en.lng

    voici son contenu (identique au fr mais traduit)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    [Form1_Form]
    Form1=title in english
     
     
    [Form1_Label]
    Label1=Label in english
    Label2=Label2 in english
     
    [Form1_Button]
    Button1=French
    Button2=English

    Dans ce code, retenons 4 choses :

    [Form1_Form] : Form1 sera le nom de la Form de mon application que je veux traduire
    [Form1_Form] : FOrm est le nom g�n�ral que je donne pour traduire le titre Form1->Caption
    [Form1_Label] : Label, Button ou d'autres seront des mots pour d�tecter si les composants sont des TLabels, TButtons etc..
    Label1, Label2, Button1 ,... sont les noms de mes composants de la Form "Form1"


    3�) COnstruction de l'application

    Nous allons maintenant cr�er une fonction ChargerLangue o� on lui passera plusieurs param�tres : le nom de la Form, le nom de fichier de langue


    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
     
    void __fastcall TForm::ChargerLangue(TForm *f, AnsiString filename)
    {
      if (FileExists(filename)) // vérifier si le fichier de langue existe
      {
          TIniFile *Ini=new TIniFile (filename);; // 'jouvre le fichier comme si c'était un fichier .ini
            for (int i = 0; i < f->ComponentCount; i++) // je parcours tous les composants de la Form
            {
     
                    if (f->Components[i]->Name!="") // tant que je suis sur un composant
                    {
     
                      if (Ini->ReadString (f->Name+"_Label",AnsiString(f->Components[i]->Name),"***")!="***")
                      {
     
                        ((TLabel *)f->Components[i])->Caption = Ini->ReadString (f->Name+"_Label",AnsiString(f->Components[i]->Name),((TLabel *)f->Components[i])->Caption);
                      }
                      else
                      if (Ini->ReadString (f->Name+"_Button",AnsiString(f->Components[i]->Name),"***")!="***")
                      {
     
                          ((TButton *)f->Components[i])->Caption = Ini->ReadString (f->Name+"_Button",AnsiString(f->Components[i]->Name),((TButton *)f->Components[i])->Caption );
     
                      }
     
                    }
     
            }
     
            if (Ini->ReadString (f->Name+"_Form",AnsiString(f->Name),"***")!="***")
            {
     
              f->Caption = Ini->ReadString (f->Name+"_Form",AnsiString(f->Name),f->Caption);
            }
     
     
     
     
        delete Ini;
      }
     
    }
    N'oublions pas de placer dans le .cpp la ligne :
    et dans le .h la d�claration de notre fonction :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
     void __fastcall ChargerLangue(TForm *f, AnsiString filename);

    maintenant allez dans l'ev�nement OnClick du Button1
    Ensuite on appelle la fonction ChargerLangue

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
     ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"fr.lng");
    M�me chose pour Onclick du Button2 mais cette fois-ci pour en.lng
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"en.lng");

    Maintenant on va choisir la langue par d�faut de l'application : (ou par vous donner un exemple, �a peut �tre int�ressant pour choisir
    la langue choisie lors de la derni�re utilisation)
    Pour cela, on clique sur l'ev�nement OnCreate de la Form1. Et on �crit :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
     ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"fr.lng");


    Compilez et ex�cutez !

    4�) Avantages et inconv�nients

    Les avantages sont nombreux :
    - Pas besoin de red�marrer l'application pour la traduire .. traduction rapide et instantan�e
    - Modification du fichier langue sans avoir � modifier le code source. (il suffit de mettre tous les composants � scanner dans le code chargerlangue)
    - Possibilit� de cr�er un menu en cr��ant des sous-menus de fa�on dynamique (il suffit de parcourir le r�pertoire et d�tecter les langues)
    - etc...

    Inconv�nients :
    - et bien, je n'en ai pas encore vu.


    5�) code source


    unit1.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    //---------------------------------------------------------------------------
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    #include "IniFiles.hpp"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
     
     
    void __fastcall TForm1::ChargerLangue(TForm *f, AnsiString filename)
    {
      if (FileExists(filename)) // vérifier si le fichier de langue existe
      {
     
        TIniFile *Ini=new TIniFile (filename);; // 'jouvre le fichier comme si c'était un fichier .ini
            for (int i = 0; i < f->ComponentCount; i++) // je parcours tous les composants de la Form
            {
     
                    if (f->Components[i]->Name!="") // tant que je suis sur un composant
                    {
     
                      if (Ini->ReadString (f->Name+"_Label",AnsiString(f->Components[i]->Name),"***")!="***")
                      {
     
                        ((TLabel *)f->Components[i])->Caption = Ini->ReadString (f->Name+"_Label",AnsiString(f->Components[i]->Name),((TLabel *)f->Components[i])->Caption);
                      }
                      else
                      if (Ini->ReadString (f->Name+"_Button",AnsiString(f->Components[i]->Name),"***")!="***")
                      {
     
                          ((TButton *)f->Components[i])->Caption = Ini->ReadString (f->Name+"_Button",AnsiString(f->Components[i]->Name),((TButton *)f->Components[i])->Caption );
     
                      }
     
                    }
     
            }
     
            if (Ini->ReadString (f->Name+"_Form",AnsiString(f->Name),"***")!="***")
            {
     
              f->Caption = Ini->ReadString (f->Name+"_Form",AnsiString(f->Name),f->Caption);
            }
     
     
     
     
        delete Ini;
      }
     
    }
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"fr.lng");
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
      ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"en.lng");
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
      ChargerLangue(Form1,ExtractFilePath(Application->ExeName)+"fr.lng");
    }
    //---------------------------------------------------------------------------

    Unit1.h

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    //---------------------------------------------------------------------------
     
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
      TLabel *Label1;
      TLabel *Label2;
      TButton *Button1;
      TButton *Button2;
      void __fastcall Button1Click(TObject *Sender);
      void __fastcall Button2Click(TObject *Sender);
      void __fastcall FormCreate(TObject *Sender);
    private:	// User declarations
    public:		// User declarations
      __fastcall TForm1(TComponent* Owner);
      void __fastcall ChargerLangue(TForm *f, AnsiString filename);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif



    6�) remarques
    Il est possible de "TOUT" traduire de fa�on dynamique et automatique. pour cela, il suffit de maitriser le composant � traduire.

  2. #2
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    D�tails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par d�faut
    Merci de partager tes connaissances.
    Citation Envoy� par echap2000
    Inconv�nients :
    - et bien, je n'en ai pas encore vu.
    • N'importe qui peut �crire ce qu'il veux dans l'application, ce n'est pas pratique pour les applications commerciales.
    • On a besoin de distribuer plusieurs fichiers en plus du fichier ex�cutable.

    Je comprends que c'est deux probl�mes ne touche pas tout les gens, mais dans mon cas c'est un probl�me. C'est pourquoi j'utilise des fichier ressource (.rc). Ensuite je compresse mon fichier ex�cutable.

  3. #3
    Membre �clair� Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par d�faut
    Moi j'ai fait la m�me chose que toi mais avec un fichier XML

  4. #4
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    51
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 51
    Par d�faut
    Merci pour le tuto !

    Crayon tu pourrais donner un p'tit exemple de ta fa�on de faire stp ?
    Histoire de comparer

  5. #5
    Membre �m�rite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    F�vrier 2006
    Messages
    916
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : F�vrier 2006
    Messages : 916
    Par d�faut
    Salut,
    Perso j'ai opt� pour une solution un peu similaire sauf que je suis dans un fichier texte.

    Pour rem�dier aux probl�mes d�crit par Crayon, ce fichier est plac� en ressource de l'exe, ce fichier devient alors invisible par l'utilisateur puiqu'il se trouve dans l'exe. Toutefois, il reste la possibilit� de l'extraire de l'exe pour le modifier et le remettre.

    Pour garder un maximum d'assurance, c'est un double qui est modifi� et l'original reste bien en ressource.

    M�thode � ajouter aux autres propos�s pour la FAQ, messieurs les mod�rateurs.

    Au passage, encore merci � eux pour le travail qu'ils effectuent ici pour que tout le monde puisse s'y retrouver.

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    83
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 83
    Par d�faut
    N'importe qui peut �crire ce qu'il veux dans l'application, ce n'est pas pratique pour les applications commerciales.
    On a besoin de distribuer plusieurs fichiers en plus du fichier ex�cutable.
    N'importe qui peut �crire.. mais il suffit de ne pas traduire certains FORM et certains composants. (tant que dans la fonction chargerlangue il n'y a pas tous les composants, et tant que la Form qui doit �tre traduite n'appellera pas la fonction). Mais si tu ne veux pas que le fichier de traduction soit externe, dans ce cas, il suffit de l'importer comme tu dis..Et puis la traduction d'une application payante peut rester externe. pourquoi c'est si important de l'avoir en interne?

    Pour la distribution des fichiers en plus de l'ex�cutable... oui c'est normal si tu regardes de ce point de vue.

  7. #7
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    D�tails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par d�faut
    Citation Envoy� par echap2000
    N'importe qui peut �crire.. mais il suffit de ne pas traduire certains FORM et certains composants. (tant que dans la fonction chargerlangue il n'y a pas tous les composants, et tant que la Form qui doit �tre traduite n'appellera pas la fonction). Mais si tu ne veux pas que le fichier de traduction soit externe, dans ce cas, il suffit de l'importer comme tu dis..Et puis la traduction d'une application payante peut rester externe. pourquoi c'est si important de l'avoir en interne?
    C'est important de l'avoir � l'interne pour �tre certain que le produit ne soit pas alt�rer par autrui. Habituellement, lorsque l'on traduit une application on ne fais pas d'exception, donc tout est traduit. Le copyright deviens tout droit r�server, on ne veux que quelqu'un change le nom de la compagnie � cet endroit. Je sais, peut-�tre que mon exemple est mauvais Le but est surtout de garder le contr�le sur l'application. Par contre pour un freeware se point deviens un avantage car n'importe qui peut faire la traduction du logiciel et en faire b�n�ficier plus de gens.

    Au lieu d'utiliser une structure comme celle-ci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Form1_Form]
    Form1=titre en français
     
    [Form1_Label]
    Label1=Label en français
    Label2=Label2 en français
     
    [Form1_Button]
    Button1=Français
    Button2=Anglais
    J'utilise le champ tag des composants pour y mettre un num�ro qui correspond � la ressource. C'est de cette fa�on que VB fonctionne lorsque que l'on cr�e un projet multi-langue. Si le tag n'est pas disponible y a toujours le caption ou autre...

    En passant echap2000, je ne critique pas ton travail je veux seulement mentionner d'autre fa�on de travailler. Chacun � des restrictions qui lui son propre pour le d�veloppement d'un logiciel X.

  8. #8
    Membre �m�rite
    Avatar de Interruption13h
    Inscrit en
    Ao�t 2005
    Messages
    603
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2005
    Messages : 603
    Par d�faut
    Avant tout merci pour ce partage
    je voulais juste dire que je croi qu'il existe un outils int�gr� dans C++Builder (V6 dans mon cas) pour la traduction des application :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
    Borland’s suite of Translation Tools facilitate software localization and
     simultaneous development of applications for different locales. The
     Translation Tools are integrated with the IDE, but can also be used
     externally. 
     
    The Translation Tools suite is made up of the following tools:
     
    The Resource DLL wizard generates resource DLLs for the languages you
     select.
        The Translation Manager provides a grid for viewing and editing forms
     and resource strings. After modifying your translations, you can update all
     of your application’s resource DLLs. The External Translation Manager
     (ETM) is the external version of the Translation Manager, which you can
     set up and use from outside the IDE. The ETM has the same functionality
     as the Translation Manager with some additional toolbars and menus. It
     also includes some of the functionality of the Resource DLL wizard.
     
    The Translation Repository provides a central database for translations that
     can be shared across projects and by different developers.
    L'executable s'appel "etm60.exe" qui se trouve dans le m�me dossier que "bcb.exe"
    Je signal que je l'ai jamais utilis�

    A+

  9. #9
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    D�tails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par d�faut
    Dans BCB 2007 il y a etm.exe External Translation Manager

    Moi non plus je ne l'ai jamais utilis�

  10. #10
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2004
    Messages
    83
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : F�vrier 2004
    Messages : 83
    Par d�faut
    En passant echap2000, je ne critique pas ton travail je veux seulement mentionner d'autre fa�on de travailler. Chacun � des restrictions qui lui son propre pour le d�veloppement d'un logiciel X.
    Pas du tout pas du tout. je suis ouvert � tout ta remarque est importante pour les applications "copyright�es".

    Je vais bient�t poster un autre tuto sur ma classe MySQL.. o� on pourra facilement jongler avec Query, fetch_row etc.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo