[Tuto] Programme multilingue sous windows
Publié : mer. 21/mars/2007 19:20
Voila mon premier vrai tuto pour la comunauté! Ca s'adresse à ceux à l'aise avec l'api win32 pour la plupart des explications à venir mais comme je donne du code tout fait n'importe qui peut venir piocher ici.
Pour commencer, je vais énumérer quelques solutions et voir les avantages de chacune:
L'inconvénient de tout intégrer à l'exécutable est que celui-ci pèse plus lourd mais le double avatange des ressources et de prendre moins de place que du code+datasection et que windows ne mappe les ressources en mémoire que si celles-ci sont utilisées.
Maintenant le dernier problème (en fait y'en a encore d'autres =) qui se pose à nous est que puisqu'on utilise l'api win32 on va obtenir des identifiants systèmes et pas des objets utilisables avec les fonctions natives de purebasic. Comme chui un mec sympa j'ai fait deux fonctions pour obtenir une Image PB à partir d'une ressource icon/cursor/bitmap et un Menu/PopupMenu PB à partir d'une ressource menu.
Puisqu'on prépare le terrain autant le faire jusqu'au bout : le but de ce tuto est de proposer une solution pour programme multilingue, mais cette solution doit inclure la possibilité de changer de langue. J'ai opté pour gérer les langues de façon automatique, et j'ai volontairement décidé de ne pas gérer les sous-langues. Comme les langues sont gérées de façon automatique, voila de quoi changer la langue du programme.
Les plus attentifs auront remarqué une constante, la fameuse langue par défaut. Comme toutes les langues ne sont pas définies dans PB voila une petite liste :
A suivre : les ressources, on fait comment ? ^_^
Dri
Pour commencer, je vais énumérer quelques solutions et voir les avantages de chacune:
- Directement dans le code
directement intégré à l'exécutable (limite les risques de perte)
pas évident de s'y retrouver
code source lourd
modifier nécessite de recompiler le tout - Dans des fichiers ini/pref
facile de modifier/ajouter une langue
il faut que tous les fichiers soit synchronisés/maintenus - Dans des ressources
directement intégré à l'exécutable
langue par défaut gérée automatiquement
uniquement disponible sous windows
modifier nécessite de recompiler le tout (même pas vrai =)
et d'autres que je ne citerais pas ici - Dans des ressources externes (fichiers dll)
facile de modifier/ajouter une langue
uniquement disponible sous windows
il faut que tous les fichiers soit synchronisés/maintenus
L'inconvénient de tout intégrer à l'exécutable est que celui-ci pèse plus lourd mais le double avatange des ressources et de prendre moins de place que du code+datasection et que windows ne mappe les ressources en mémoire que si celles-ci sont utilisées.
Maintenant le dernier problème (en fait y'en a encore d'autres =) qui se pose à nous est que puisqu'on utilise l'api win32 on va obtenir des identifiants systèmes et pas des objets utilisables avec les fonctions natives de purebasic. Comme chui un mec sympa j'ai fait deux fonctions pour obtenir une Image PB à partir d'une ressource icon/cursor/bitmap et un Menu/PopupMenu PB à partir d'une ressource menu.
Code : Tout sélectionner
Structure PB_MenuStructure
MenuID.l
WindowID.l
EndStructure
Procedure.l HackImage(Image.l, ImageID.l)
Protected *ImageID.Long, Index.l
Protected ic.IconInfo, bm.Bitmap
If ImageID And Not GetIconInfo_(ImageID, ic)
ic\hbmColor = ImageID
EndIf
If GetObject_(ic\hbmColor, SizeOf(Bitmap), bm)
Index = CreateImage(Image, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
If Image <> #PB_Any : Index = Image : EndIf
*ImageID = IsImage(Index)
EndIf
If *ImageID
DeleteObject_(*ImageID\l)
*ImageID\l = ImageID
If Image = #PB_Any
ImageID = Index
EndIf
Else
If GetIconInfo_(ImageID, ic)
If ic\fIcon
DestroyIcon_(ImageID)
Else
DestroyCursor_(ImageID)
EndIf
Else
DeleteObject_(ImageID)
EndIf
ImageID = #Null
EndIf
ProcedureReturn ImageID
EndProcedure
Procedure.l HackMenu(Menu.l, MenuID.l, WindowID.l = #Null)
Protected Index.l, *Menu.PB_MenuStructure
If MenuID
Index = CreatePopupMenu(Menu)
If Menu <> #PB_Any : Index = Menu : EndIf
*Menu = IsMenu(Menu)
EndIf
If *Menu
SetMenu_(WindowID, MenuID)
DestroyMenu_(*Menu\MenuID)
*Menu\MenuID = MenuID
*Menu\WindowID = WindowID
If Menu = #PB_Any
MenuID = Index
EndIf
Else
DestroyMenu_(MenuID)
MenuID = #Null
EndIf
ProcedureReturn MenuID
EndProcedure
Code : Tout sélectionner
Global ProgramLocale.l = #LANG_NEUTRAL
ProcedureDLL.l GetProgramLocale()
ProcedureReturn ProgramLocale
EndProcedure
ProcedureDLL.l SetProgramLocale(Locale.l)
Swap ProgramLocale, Locale
ProcedureReturn Locale
EndProcedure
Code : Tout sélectionner
Enumeration
#LANG_NEUTRAL
#LANG_ARABIC
#LANG_BULGARIAN
#LANG_CATALAN
#LANG_CHINESE
#LANG_CZECH
#LANG_DANISH
#LANG_GERMAN
#LANG_GREEK
#LANG_ENGLISH
#LANG_SPANISH
#LANG_FINNISH
#LANG_FRENCH
#LANG_HEBREW
#LANG_HUNGARIAN
#LANG_ICELANDIC
#LANG_ITALIAN
#LANG_JAPANESE
#LANG_KOREAN
#LANG_DUTCH
#LANG_NORWEGIAN
#LANG_POLISH
#LANG_PORTUGUESE
#LANG_ROMANIAN = 24
#LANG_RUSSIAN
#LANG_CROATIAN
#LANG_SERBIAN = 26
#LANG_SLOVAK
#LANG_ALBANIAN
#LANG_SWEDISH
#LANG_THAI
#LANG_TURKISH
#LANG_URDU
#LANG_INDONESIAN
#LANG_UKRAINIAN
#LANG_BELARUSIAN
#LANG_SLOVENIAN
#LANG_ESTONIAN
#LANG_LATVIAN
#LANG_LITHUANIAN
#LANG_FARSI = 41
#LANG_VIETNAMESE
#LANG_ARMENIAN
#LANG_AZERI
#LANG_BASQUE
#LANG_MACEDONIAN = 47
#LANG_AFRIKAANS = 54
#LANG_GEORGIAN
#LANG_FAEROESE
#LANG_HINDI
#LANG_MALAY = 62
#LANG_KAZAK
#LANG_SWAHILI = 65
#LANG_UZBEK = 67
#LANG_TATAR
#LANG_BENGALI
#LANG_PUNJABI
#LANG_GUJARATI
#LANG_ORIYA
#LANG_TAMIL
#LANG_TELUGU
#LANG_KANNADA
#LANG_MALAYALAM
#LANG_ASSAMESE
#LANG_MARATHI
#LANG_SANSKRIT
#LANG_KONKANI = 87
#LANG_MANIPURI
#LANG_SINDHI
#LANG_KASHMIRI
#LANG_NEPALI
EndEnumeration
Dri