Programmes Multi-Langues

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Oui, c'est sûr que ça peut marcher, mais uniquement pour les gadgets dont le texte peut être modifié par la commande SetGadgetText().

Mais pour les en-têtes de colonnes des ListIconGadget, les titres de menus, etc... :wink:

Il n'ont pas de constantes!!!

Chris :)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai écrit un utilitaire pas terminé il y a plusieurs mois avec plusieurs langues.
Comme je suis chauvin, j'ai utilisé des dataspour le français et des fichiers textes pour les autres langues.
J'utilise plusieurs tableaux pour stocker les infos.
Un pour les menus, un pour les toolbar, un pour la listicon etc
Donc au début je lit le fichier de pref et si je ne le trouve pas je lis les datas pour le français et je remplis tous les tableaux

j'ai du m'inspirer de l'éditeur PB.
Ca donne le code suivant

Code : Tout sélectionner

Procedure UseFrenchLanguage()
  
  Restore French_FileMenu
  For i.b = 0 To #Nb_ItemFileMenu - 1
    Read FileMenu(i)
  Next
  
  ; Restore French_ToolBar
  For i.b = 0 To #Nb_ItemToolbar - 1
    Read FileToolbar(i)
  Next
  
  ; Restore French_ToolTipsForToolBar
  For i.b = 0 To #Nb_ToolTipsForToolBar - 1
    Read ToolTipsForToolBar(i)
  Next
  
  ; Restore French_OptionMenu
  For i = 0 To #Nb_ItemOptionMenu - 1
    Read OptionMenu(i)
  Next i
  
  ; Restore French_HelpMenu
  For i = 0 To #Nb_ItemHelpMenu - 1
    Read HelpMenu(i)
  Next i
  
  ; Restore French_HelpMenu
  For i = 0 To #Nb_ListIconGadgetColumns - 1
    Read ListIconGadgetColumnsName(i)
  Next i
  
  For i = 0 To #Nb_ListCompressedeFileColumns - 1
    Read ListCompressedeFileColumnsName(i)
  Next i
  
EndProcedure

Code : Tout sélectionner

Procedure.l UseOtherLanguage()
  
  LanguageFile.s = Pref\InstallPath + "Language\" + "TextLang"
  
  If (((Pref\CurrentLanguage >= #English) And (Pref\CurrentLanguage <= #Spanish))) And (ReadFile(#FileTextLanguage, LanguageFile + Str(Pref\CurrentLanguage)))
    ReadTextLanguageFile()
    CloseFile(#FileTextLanguage)
  Else
    Pref\CurrentLanguage = #French
    UseFrenchLanguage()
  EndIf
  
EndProcedure

Code : Tout sélectionner

Procedure ReadTextLanguage()
  
  If Pref\CurrentLanguage
    UseOtherLanguage()
  Else
    UseFrenchLanguage()
  EndIf
  
EndProcedure

Code : Tout sélectionner

Procedure ReadTextLanguageFile()
  
  For i.b = 0 To #Nb_ItemFileMenu - 1
    FileMenu(i) = ReadString()
  Next
  
  For i = 0 To #Nb_ItemToolbar - 1
    FileToolbar(i) = ReadString()
  Next
  
  For i = 0 To #Nb_ToolTipsForToolBar - 1
    ToolTipsForToolBar(i) = ReadString()
  Next
  
  For i = 0 To #Nb_ItemOptionMenu - 1
    OptionMenu(i) = ReadString()
  Next i
  
  For i = 0 To #Nb_ItemHelpMenu - 1
    HelpMenu(i) = ReadString()
  Next i
  
  For i = 0 To #Nb_ListIconGadgetColumns - 1
    ListIconGadgetColumnsName(i) = ReadString()
  Next i
  
  For i = 0 To #Nb_ListCompressedeFileColumns - 1
    ListCompressedeFileColumnsName(i) = ReadString()
  Next i

EndProcedure
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Bon! En partant de mon précédent exemple, j'ai fait un fichier *.pbi qui va permettre de soulager un peu la prog. Il suffira de l'inclure dans le code du programme principal par la commande IncludeFile "SetLang.pbi"

J'ai refais un exemple, HYPER COMMENTE.

J'ai testé ce fichier avec mon exemple précédent, et avec un autre, ça fonctionne sans problème.

Code du fichier *.pbi

Code : Tout sélectionner

;- Variables Globales
Global AppPath.s, Nb.b

;- Procédures
;{  =============== Précisions concernant cette procédure ===============
;
;   Cette procédure retrouve le chemin de l'application, y ajoute le nom du
;   dossier à rechercher pour créer un nouveau chemin, puis  charge la
;   LinkedList() avec le nom des dossiers qu'elle à trouvée. Ces dossiers
;   doivent porter le nom de la langue qu'ils contiennent, car c'est ce
;   nom qui s'affichera dans le menu. Par exemple, Français, English, etc...
;   La procédure retourne #True si elle a trouvé un ou des dossiers, #False
;   dans le cas contraire. Cela permet, dans le cas ou #False serait retourné,
;   de charger la langue par défaut à partir des datas contenus en fin de code.
;   La variable AppPath.s, contient le chemin de l'application. Elle est
;   accessible depuis le reste du programme, car déclarée comme étant globale.
;}
Procedure GetFolders(FolderName.s)
  NewList Menu.s()
  If Right(FolderName,1)<>"\" : FolderName + "\" : EndIf; <- Formatage du nom du dossier

  AppPath = Space(#MAX_PATH); <-- Recherche du chemin de l'application
  GetCurrentDirectory_(#MAX_PATH,@AppPath)
  If Right(AppPath,1)<>"\" : AppPath + "\" : EndIf; <-- Mise en forme
  AppPath + FolderName; <-- et ajout du mon de dossier pour former le chemin

  If ExamineDirectory(0,AppPath,"*.*") = 0; <-- Examin de répertoire
    ProcedureReturn #False
  Else
    Repeat
      Type = NextDirectoryEntry()
      If  Type = 2
        Nom.s = DirectoryEntryName()
        If  Nom <> "." And Nom <> ".."
          AddElement(Menu())
          Menu() = Nom; <-- Ajout des noms de dossier dans la liste
        EndIf
      EndIf
    Until Type = 0
  EndIf
  ProcedureReturn #True
EndProcedure

;{  =============== Précisions concernant cette procédure ===============
;   Cette procédure lit le fichier contenu dans un des dossiers préalablement
;   retrouvé par GetFolders()
;   Fichier.s, est le chemin complet transmis à l'appel de la procédure. Il est
;   composé de AppPath.s + Nom du dossier + Nom du fichier de langue.
;   Le fichier doit être au format *.catalog, utilisé pour PureBasic
;}
Procedure ReadCatalog(Fichier.s)
  If ReadFile(0, Fichier)
    If ReadString() = "Catalog";    <-- Si la première ligne est différente
      Repeat;                           de Catalog, alors, le fichier n'est pas valide
        ReadString() : Nb + 1;      <-- On parcourt une fois le fichier pour connaitre
      Until Eof(0);                     le nombre de lignes
      FileSeek(0);                  <-- puis on remet le pointeur au début
      ReadString();                 <-- et on déplace d'une ligne pour pointer sur
      ;                                 le premier texte

;       Nb = Val(ReadString())
      Dim Language$(Nb);            <-- On dimensionne, ensuite, le tableau
      For k=0 To Nb
        Language$(k) = ReadString();<-- et on le remplit
      Next
    EndIf
    CloseFile(0)
  EndIf
EndProcedure

;{  =============== Précisions concernant cette procédure ===============
;   Cette procédure permet d'afficher la langue par défaut, à partir des datas
;   placées en fin de code. Elle remplace la lecture des fichiers, pour le cas
;   ou ceux-ci n'existeraient pas.
;   Il faudra penser à ajouter une ligne contenant "-1", à la fin des datas pour
;   éviter le message "No More Datas", et le plantage.
;}
Procedure DefaultLanguage()
  Restore BaseLanguage
  Repeat
    Read tmp$ : Nb +1
  Until tmp$ = "-1"
  Nb -1
  Dim Language$(Nb)

  Restore BaseLanguage
  For k =0 To Nb
    Read Language$(k)
  Next
EndProcedure
Code du nouvel exemple:

Code : Tout sélectionner

IncludeFile "SetLang.pbi"

;- Constantes Window
Enumeration
  #Win_0
EndEnumeration

;- Constantes Menus
;/ Barre de menus
Enumeration
  #MenuBar_0
EndEnumeration

;/ Elements des menus
Enumeration
  #M_Open
  #M_Close
  #M_New
  #M_Save
  #M_SaveAs
  #M_Quit
  #M_Cut
  #M_Paste
  #M_Copy
  #M_Undo
  #M_Redo
  #M_Language
EndEnumeration

;- Constantes Gadgets
Enumeration
  #Editor_0
  #Btn_0
EndEnumeration

;- Variables globales
Global hWnd.l

;- Variables locales
Titre$ = "\Test.catalog";                 <--- Titre des fichiers de langue
DefType.b quit
;- Procedures

;/ Ouverture de la fenêtre
Procedure Open_Win_0()
  
  ;{  ==================== Commentaire ====================
  ;   Ouverture de la fenêtre
  ;   Explication concernant l'ouverture de la fenêtre:
  ;   Le code concernant la création des menus est supprimé, et placé dans la
  ;   procédure "UpdateGadget()" par copier/coller
  ;}   Les valeurs contenues dans "Language$()" n'ont, en principe, pas à être changées
  
  If OpenWindow(#Win_0, 216, 0, 348, 300,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , Language$(16))
    hWnd = WindowID()
    If CreateGadgetList(WindowID())
      EditorGadget(#Editor_0, 0, 0, 235, 280)
      ButtonGadget(#Btn_0, 240, 5, 105, 25, Language$(15))
    EndIf
  EndIf
  ProcedureReturn hWnd
EndProcedure

;/ Mise à jour des gadgets
Procedure UpdateGadget()
  
  ;{  ==================== Commentaire ====================
  ;   On commence par appeler "FreeMenu()" pour les utilisations ultérieures
  ;   Le plus simple, est de créer un menu uniquement pour le changement de langue,
  ;   en créant son titre dans la barre de menu, et en le laissant vide. Mais il est
  ;   aussi possible de créer une entrée au milieu d'un menu, en procédant à une
  ;}  modification. C'est ce que j'ai fait ici.
  
  SetWindowText_(hWnd, Language$(16))
  FreeMenu(#MenuBar_0)
  If CreateMenu(#MenuBar_0, hWnd);{ <--     Toute cette partie vient de la procédure
    MenuTitle(Language$(0));                d'ouverture de la fenêtre, jusqu'à "Endif"
    MenuItem(#M_Open, Language$(1))
    MenuItem(#M_Close, Language$(2))
    MenuItem(#M_New, Language$(3))
    MenuItem(#M_Save, Language$(4))
    MenuItem(#M_SaveAs, Language$(5))
    MenuBar()
    MenuItem(#M_Quit, Language$(6))
    MenuTitle(Language$(7))
    MenuItem(#M_Cut, Language$(8))
    MenuItem(#M_Paste, Language$(9))
    MenuItem(#M_Copy, Language$(10))
    MenuBar()
    MenuItem(#M_Undo, Language$(11))
    MenuItem(#M_Redo, Language$(12))
    MenuTitle(Language$(13))
    
    ;MenuItem(#M_Language, Language$(14)) <--- Entrée de menu modifiée
    
    OpenSubMenu(Language$(14));           <--- Remplacée par OpenSubMenu()
    For i = 0 To CountList(Menu())-1;     <--- Je compte, ensuite, le nombre
      SelectElement(Menu(),i);                 de champs dans la liste, et je
      MenuItem(i + 500,Menu());                crée les sous-menus à partir des
    Next;                                      noms qui s'y trouvent. Je donne 500
    CloseSubMenu();                            comme index au premier sous-menu
  EndIf;}
  SetGadgetText(#Btn_0,Language$(15))
  
  ;{   ==================== Commentaire ====================
  ;   Pratiquement tous les gadgets peuvent être modifiés par un SetGadgeText() sauf
  ;   les LisIconGadget(), et peut-être d'autres que je n'ai pas répertorié, pour lesquels
  ;   il faut passer par un SendMessage_()
  ;   Pour les ListIconGadget(), voici le code:
  ;
  ;   Titre.LV_COLUMN                     <--- A mettre au début de la procédure
  ;
  ;   Titre\mask    = #LVCF_TEXT
  ;   Titre\pszText = @Language$(index du texte dans la liste)
  ;}   SendMessage_(Handle du LisIconGadget,#LVM_SETCOLUMN,0,@Titre)
  
EndProcedure

; Recherche des fichiers de langue, et ouverture de la fenêtre
If GetFolders("Lang") = #True
  
  ;{  ==================== Commentaire ====================
  ;   On commence par appeler GetFolders() pour trouver tous les dossiers de langue.
  ;   Si la fonction renvoie #False, on prends les datas comme référence.
  ;   Dans le cas contraire, on crée le chemin en chaînant le chemin de l'application,
  ;   l'entrée du menu par défaut, ici, 0, et le titre du fichier à ouvrir.
  ;}  On appelle, ensuite, la procédure  qui va lire le fichier, et le mettre dans la liste.
  
  SelectElement(Menu(), 0)
  Path.s = AppPath + Menu() + Titre$
  ReadCatalog(Path)
Else
  DefaultLanguage()
EndIf

hWnd = Open_Win_0();                      <---  On ouvre, ensuite, la fenêtre
UpdateGadget();                                 et après, seulement, on appelle
;                                               UpdateGadget.

;- Boucle principale

Repeat
  Select WaitWindowEvent()
    
    Case #PB_EventMenu
      
      ;{  ==================== Commentaire ====================
      ;   On teste pour savoir si le menu sélectionné est celui qui permet de
      ;}  changer de langue. Si on ne le fait pas, ça plante le programme
      
      If EventMenuID() >= 500
        ResetList(Menu())
        SelectElement(Menu(), EventMenuID() -500)
        Path.s = AppPath + Menu()+"\Test.catalog"
        ReadCatalog(Path)
        UpdateGadget()
      EndIf
      
      Select EventMenuID()
        Case #M_Quit
          quit = 1
      EndSelect
      
    Case #PB_EventGadget
      Select EventGadgetID()
        Case #Btn_0
          quit = 1
      EndSelect
      
    Case #PB_EventCloseWindow;{
      quit = 1
  EndSelect
  
Until quit = 1

End
DataSection

;- Datas par défaut

BaseLanguage:;{
Data$ "Fichiers"
Data$ "Ouvrir"
Data$ "Fermer"
Data$ "Nouveau"
Data$ "Sauver"
Data$ "Sauver sous"
Data$ "Quitter"
Data$ "Edition"
Data$ "Couper"
Data$ "Coller"
Data$ "Copier"
Data$ "Annuler"
Data$ "Refaire"
Data$ "Options"
Data$ "Changer la langue"
Data$ "Bouton"
Data$ "Test"
Data$ "-1";            <--- Mettre "-1" à la fin des datas, pour permettre à la fonction
EndDataSection;             contenue dans le fichier Include de s'arrêter
;}
Traduction en français

Code : Tout sélectionner

Catalog
Fichiers
Ouvrir
Fermer
Nouveau
Sauver
Sauver sous
Quitter
Edition
Couper
Coller
Copier
Annuler
Refaire
Options
Changer la langue
Bouton
Nouveau test
Traduction en anglais

Code : Tout sélectionner

Catalog
Files
Open
Close
New
Save
Save As
Quit
Edit
Cut
Paste
Copy
Undo
Redo
Options
Change Language
Button
New test
Chris :)
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Denis a écrit :J'utilise plusieurs tableaux pour stocker les infos.
Un pour les menus, un pour les toolbar, un pour la listicon etc
Donc au début je lit le fichier de pref et si je ne le trouve pas je lis les datas pour le français et je remplis tous les tableaux
je vais m'inspirer de ça aussi , plusieurs tableaux c'est plus pratique pour les modifs , je viens de m'en apercevoir avec sokoban , c'est le bazard pour ajouter un truc !!

Sinon j'ai une autre solution , je laisse tout en français ,et si ça les intéresse vraiment les "english" , ben ils font comme moi , ils sortent le dico :)
Dernière modification par comtois le mar. 23/mars/2004 18:28, modifié 1 fois.
T€r$@k€n
Messages : 42
Inscription : ven. 23/janv./2004 18:49

Message par T€r$@k€n »

Google --> outils linguistique .
Image
_______________________________________
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Sinon j'ai une autre solution , je laisse tout en français ,et si ça les intéresse vraiment les "english" , ben ils font comme moi , il sorte le dico
:wink: :!: :mrgreen:
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Je viens d'avoir un idée, si tu remplace tout les textes du programme par des variables chaîne de caractère. Pour faire un changement de langue tu change les textes dans chacune des variables et tu lance un rafraîchissement de la fenètre.

UpdateWindow_(WindowID())

J'ai pas de code pour faire des tests.

A+
Guimauve
Répondre