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
On va sauvegarder ce fichier dans le m�me r�pertoire que notre application.
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
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
N'oublions pas de placer dans le .cpp la ligne :
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; } }
et dans le .h la d�claration de notre fonction :
Code : S�lectionner tout - Visualiser dans une fen�tre � part #include "IniFiles.hpp"
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
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)+"fr.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.
Partager