RobOtter
Joined: 30 Jan 2005 Posts: 125 Location: Darmstadt, Germany
|
Posted: Tue Apr 18, 2006 3:47 pm Post subject: A step further to internationalize your programs |
|
|
Since I want my programs to be multi-lingual, I wanted to externalize all string resources to an INI file.
This is my first half-an-hour-hack. Of course many things can be done better and there are several items to add, but maybe this can be a starter for some of you.
In detail, I would like to add code to support hotkeys in menus (there is a topic about that but I canīt find it atm) and also take care of plurals like PhiLho pointed out in http://www.autohotkey.com/forum/topic8841.html
Nevertheless, here comes the source:
| Code: | #NoEnv
; Global variables
language := "en" ; Default
langFilePrefix := "./language_"
langFileSuffix := ".ini"
messageArraySize := 0
errorArraySize := 0
labelArraySize := 0
; -----------------------------------------------------------------------------
/*
Main program starts here
*/
langFile := langFilePrefix . language . langFileSuffix
Gosub, ReadLanguage
fmessage := StringF(message_1, "Two", 12, 7, 3)
MsgBox, , My message, %fmessage%
Loop, %errorArraySize%
{
tmpErrorMsg := error_%A_Index%
allErrors = %allErrors%%tmpErrorMsg%`n
}
MsgBox, , Errors, %allErrors%
Loop, %labelArraySize%
{
tmpLabelMsg := label_%A_Index%
allLabels = %allLabels%%tmpLabelMsg%`n
}
MsgBox, , Labels, %allLabels%
/*
Main program ends here
*/
; -----------------------------------------------------------------------------
/*
Reads the language file and creates the following arrays according to the
content of the language file.
- message_
- error_
- label_
The numbering of the parameters in the sections need to be strictly subsequent.
If there is no direct successor to a parameter like msg_3, the reading loop
will quit reading the section
The array index will start with 1, NOT with 0 !
*/
ReadLanguage:
{
; Read the Messages section
Loop {
IniRead, tmpMsg, %langFile%, Messages, msg_%A_Index%
If (tmpMsg <> "ERROR")
{
message_%A_Index% := tmpMsg
}
Else
{
messageArraySize := A_Index - 1
break
}
}
; Read the Errors section
Loop {
IniRead, tmpErr, %langFile%, Errors, err_%A_Index%
If (tmpErr <> "ERROR")
{
error_%A_Index% := tmpErr
}
Else
{
errorArraySize := A_Index - 1
break
}
}
; Read the Labels section
Loop {
IniRead, tmpLbl, %langFile%, Labels, lbl_%A_Index%
If (tmpLbl <> "ERROR")
{
label_%A_Index% := tmpLbl
}
Else
{
labelArraySize := A_Index - 1
break
}
}
}
Return
/*
Poor manīs string format:
If the given string contains variables like @@1, @@2, ... @@9, the function
replaces them all with the given values.
Note that the first value must be specified, all following are optional
*/
StringF(ByRef sourceStr, val_1, val_2 = "", val_3 = "", val_4 = "", val_5 = "", val_6 = "", val_7 = "", val_8 = "", val_9 = "")
{
StringReplace, resultStr, sourceStr, @@1, %val_1%, All
If (val_2 <> "")
StringReplace, resultStr, resultStr, @@2, %val_2%, All
If (val_3 <> "")
StringReplace, resultStr, resultStr, @@3, %val_3%, All
If (val_4 <> "")
StringReplace, resultStr, resultStr, @@4, %val_4%, All
If (val_5 <> "")
StringReplace, resultStr, resultStr, @@5, %val_5%, All
If (val_6 <> "")
StringReplace, resultStr, resultStr, @@6, %val_6%, All
If (val_7 <> "")
StringReplace, resultStr, resultStr, @@7, %val_7%, All
If (val_8 <> "")
StringReplace, resultStr, resultStr, @@8, %val_8%, All
If (val_9 <> "")
StringReplace, resultStr, resultStr, @@9, %val_9%, All
Return resultStr
}
|
Save this as file language_en.ini in the same directory:
| Code: | [Messages]
msg_1 = @@1 months ago, after drinking @@2 beer I saw @@3 white mice and @@4 pink elephants
[Errors]
err_1 = 1st Error
err_3 = This error message will never be read since there is no err_2 parameter
[Labels]
lbl_1 = 1st Label
lbl_2 = 2nd Label
|
|
|