PowerBASIC Forums
  PowerBASIC Console Compiler
  Multi Language Programming

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   Multi Language Programming
Aldo Cavini
Member
posted October 02, 2003 01:01 AM     Click Here to See the Profile for Aldo Cavini     Edit/Delete Message   Reply w/Quote
I now start writing a PB/CC program which must work (at least) in three languages (english, italian and spanish). The program is for an exibition, hence I liked to change the language setting by a runtime click on a menu (Console Tools, etc.).

Some time ago I "invented" a method to do this, where all the strings to be printed are first read into an array; the array index is a literal that matches a programming name to the effective string. This worked as follows:

  • Use an Excel sheet to manage all the languages I need: one row for each string, one column for each language, plus a column more to declare the literal name for each string.
  • Use a macro to output the Excel data to N+1 files: one with the literals to be included into the main program, the other N files with the individual language strings.
  • Include in the main program a function to read from the needed language file, and then reprint all the data to the active windows.
Questions. Is there a better/easyest method? Is it better to use UNICODE? Any comment?

Thanks in advance.

Aldo

------------------

[This message has been edited by Aldo Cavini (edited October 02, 2003).]

IP: Logged

Michael Mattias
Member
posted October 02, 2003 03:15 AM     Click Here to See the Profile for Michael Mattias     Edit/Delete Message   Reply w/Quote
One Resource-only DLL with STRINGTABLE for each supported language.

Load DLL for current language.

When you need character string, call LoadString. (You could just change your current function to be a 'wrapper' for LoadString).

You could still use Excel/other spread sheet for maintenance purposes. But instead of Literal to ID the string, use a symbol with a value like..


ID Idvalue English Italian Spanish French
ID_HELLO 101 Hello Yo Hola Bonjour
ID_GOODBYE 102 Goodbye Ciao Hasta La vista Adieu
...

When you need to create resource for particular language, I'm sure you could either create Excel macro/VB script or PB/other program to create a 'stringtable.h' file you could #include in your resource script.

Eliminates need for an extra file.

It's a thought.

MCM


IP: Logged

Don Schullian
Member
posted October 02, 2003 07:02 AM     Click Here to See the Profile for Don Schullian     Edit/Delete Message   Reply w/Quote
Hi Aldo,

Since you're using 3 Latin based languages you shouldn't have too much trouble (Greek & English drove me to tears) but whatever you do needs testing on both Win9x, 2k, and XP early on. I ran into massive trouble when using PBcc and had to switch to PBwin.

I've come up with a solution that allows me quick access to the different languages and I can even 'swap' languages in the middle of the program.

I've got an .inc file that is loaded into the code at compile time and is read into the program at run time. It looks like this:


%ERR_070 = 64070 ' Permission denied
%ERR_024 = 64024 ' Device Time-Out
%ERR_057 = 64057 ' Device I/O error
%ERR_001 = 64001 ' Function failure - PLEASE TRY AGAIN
'---------------------------------------
%ERR_005 = 64005 ' Illegal function call
%ERR_007 = 64007 ' Out of memory
%ERR_009 = 64009 ' Subscript / Pointer out of range
%ERR_051 = 64051 ' Internal error
%ERR_052 = 64052 ' Bad file name or number

There are 3 functions that go along with it...


'
'----------------------------------------------------------------------------------------
'
FUNCTION fStr ALIAS "fStr" ( BYVAL RefNo AS LONG , _
OPT BYVAL Str AS STRING ) EXPORT AS STRING

DIM I AS LOCAL LONG
DIM Txt AS LOCAL STRING
DIM X AS LOCAL LONG

FOR I = 1 TO 0 STEP -1
X = fBinarySearch_Long(g_StrRef(),RefNo)
IF X < 0 THEN EXIT FUNCTION
IF ASC(g_Str(X)) <> 35 THEN EXIT FOR
RefNo = VAL(MID$(g_Str(X),2))
IF RefNo = 0 THEN EXIT FOR
NEXT

IF LEN(Str) = 0 THEN
FUNCTION = g_Str(X)
ELSE
Txt = g_Str(X)
REPLACE "@@" WITH Str IN Txt
FUNCTION = Txt
END IF

END FUNCTION
'
'----------------------------------------------------------------------------------------
'
FUNCTION fHlp ALIAS "fHlp" ( BYVAL RefNo AS LONG , _
OPT BYVAL Str AS STRING ) EXPORT AS STRING

DIM I AS LOCAL LONG
DIM Txt AS LOCAL STRING
DIM X AS LOCAL LONG

FOR I = 1 TO 0 STEP -1
X = fBinarySearch_Long(g_HlpRef(),RefNo)
IF X < 0 THEN EXIT FUNCTION
IF ASC(g_Hlp(X)) <> 35 THEN EXIT FOR
RefNo = VAL(MID$(g_Hlp(X),2))
NEXT

IF LEN(Str) = 0 THEN
FUNCTION = g_Hlp(X)
ELSE
Txt = g_Hlp(X)
REPLACE "@@" WITH Str IN Txt
FUNCTION = Txt
END IF

END FUNCTION
'
'----------------------------------------------------------------------------------------
'
FUNCTION fLoadPrompts () AS LONG

DIM FileNo AS LOCAL LONG
DIM FileSpec AS LOCAL STRING
DIM L AS LOCAL STRING
DIM Last AS LOCAL LONG
DIM LastT AS LOCAL LONG
DIM LastH AS LOCAL LONG
DIM P AS LOCAL LONG
DIM V AS LOCAL LONG

FileSpec = fGetIni(g_INIfile,"Data","Language","English")
FileSpec = g_ProgPath & FileSpec & ".inc"

IF LEN(DIR$(FileSpec)) = 0 THEN
FUNCTION = 53 ' File not found
EXIT FUNCTION
END IF

V = FREEFILE
TRY
OPEN FileSpec FOR INPUT AS V
FILESCAN V, RECORDS TO Last
REDIM g_Str (Last) AS GLOBAL STRING
REDIM g_StrRef(Last) AS GLOBAL LONG
REDIM g_Hlp (Last) AS GLOBAL STRING
REDIM g_HlpRef(Last) AS GLOBAL LONG
DIM Txt (Last) AS LOCAL STRING
LINE INPUT# V, Txt()
CLOSE V
CATCH
FUNCTION = ERRCLEAR
EXIT FUNCTION
END TRY

LastT = -1
LastH = -1

WHILE Last > 0
DECR Last
Txt(Last) = TRIM$(Txt(Last)) : IF ASC(Txt(Last)) <> 37 THEN ITERATE ' NOT AN %
V = VAL(PARSE$(Txt(Last),ANY "'=",2)) : IF V = 0 THEN ITERATE
P = INSTR(Txt(Last),"'") : IF P = 0 THEN ITERATE
L = LTRIM$(MID$(Txt(Last),P+1))
REPLACE "\t" WITH $TAB IN L
REPLACE "\c" WITH $CRLF IN L
REPLACE "\s" WITH $SPC IN L
REPLACE "\q" WITH $DQ IN L
REPLACE "\0" WITH $NUL IN L
IF LEFT$(Txt(Last),5) <> "%Hlp_" THEN
INCR LastT
g_Str(LastT) = L
g_StrRef(LastT) = V
ELSE
INCR LastH
g_Hlp(LastH) = L
g_HlpRef(LastH) = V
END IF
WEND

IF LastT > -1 THEN
REDIM PRESERVE g_Str (LastT)
REDIM PRESERVE g_StrRef(LastT)
ARRAY SORT g_StrRef(), TAGARRAY g_Str()
ELSE
REDIM g_Str(0)
REDIM g_StrRef(0)
END IF

IF LastH > -1 THEN
REDIM PRESERVE g_Hlp (LastH)
REDIM PRESERVE g_HlpRef(LastH)
ARRAY SORT g_HlpRef(), TAGARRAY g_Hlp()
ELSE
REDIM g_Hlp(0)
REDIM g_HlpRef(0)
END IF

END FUNCTION

In the code, to put a prompt or string onto the screen it looks something like this:

PRINT fStr(%ERR_070)

This all is an oversimplification of course and I'll gladly discuss it further if you wish.

BTW, when you're all done the .inc file can be easlily placed into a reference file.

------------------
C'ya
Don
d83@DASoftVSS.com

IP: Logged

Aldo Cavini
Member
posted October 02, 2003 07:28 AM     Click Here to See the Profile for Aldo Cavini     Edit/Delete Message   Reply w/Quote
Michael, Don,

thanks for the replies. Must admit both methods are good, hence I now have the problem to decide which one to use...

About UNICODEs, I think it's better to use them, since Italian has accents, and Spanish has some no-standard ASCII chars. I think (correct me if I'm wrong) if I fill a file with UNICODE strings, of course they are created based on my Pc ANSI table, hence my dev Pc should correctly both write and read them. On the user Pc, there will be only an UNICODE to ANSI translation, possibly based on another ANSI table; but the result should be as good as possible to that computer. Am I wrong?

------------------

[This message has been edited by Aldo Cavini (edited October 02, 2003).]

IP: Logged

All times are EasternTime (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | PowerBASIC BASIC Compilers

Copyright © 1999-2005 PowerBASIC, Inc. All Rights Reserved.


Ultimate Bulletin Board 5.45c