I have just got back from a week in China - watching your own programme
become totally unitelligible when it is running in a foreign language
really makes you realise how difficult it must be having to use 'english'
versions of software.
I tried to get something on 'Internationalizing', but all I could find was
the chapter in the VB manual, and an announcement of a forthcoming
Microsoft Press book.
Anyway, for what it is worth, this is what we did..
Official Microsoft documentation talks of using the resource file to allow
other language support, but we decided to use a separate external text file
for each language. This allows maintenance of the language to be done in
the 'foreign' country, without having to recompile.
I was really surprised about how easy it was.
In each forms Load event is...
The basic routine is (lots cut out)...
Public Sub LoadCaptions(vForm as Form)
Dim Lv_Control as Control
vForm.Caption = LanguageText(vForm.Tag)
For Each lv_Control In vForm.Controls
.Caption = LanguageText(.Tag)
#If Win32 Then
.ToolTipText = ToolTipTextText(.Tag)
'Tab controls need a fiddle because
'only the Control has a tag
'li_t is offset
.TabCaption(li_t) = LanguageText(.Tag + li_t)
LanguageText() and ToolTipText() are public functions that return the text
corresponding to the Sequence number saved in the Control.Tag
The Text and Sequence numbers from the language file are loaded into a
The language file in english (ready to be translated), but also needed for
the 'English' version, was produced automatically with a small programme
that loops through each form using the VBP file.
The programme has 2 functions...
We also had a list of common words (&Ok, &Close, Cancel etc) that are
shared across all forms.
Writes an incrementing sequence number (jumping in blocks of 1000 for
each Form) into each controls' .Tag (got to be careful here - it actually
copied from *.FRM to *.FR1 files...)
- Writes the .Caption (in english) and the Sequence number to a text file
I found out that menus can have a Tag!
When you change language, labels, buttons, tabs etc refresh immediately,
but the menus usually need an exit/restart.
The convention for Chinese menus appears to be XXXXXX (&O) - ie the hot
key is added after the chinese script, in european characters.
All MsgBox() messages had to be searched for manually and put in the
We had to do some compromises to allow for different grammatical structure
- sometimes the wording has to be a bit clumsy in english - but many times
we ended up expressing things more clearly in english.
We had to do a 'fix' for Chinese.
(I have no idea why Chinese works in VB4 - I thought VB4 was 1 byte = 1
We use the API calls...
li_HeightUsed = DrawText(hdc, ls_Text, Len(ls_Text), lr_rect, i_Align)
li_ret = TextOut(hdc, x, y, ls_Text, Len(ls_Text))
Both calls print ok with 'european' 8 bit characters, and are ok when
printing from the chinese language file but on a 'european' PC (they print
the characters from 128-255)
but about 1/3 of the rightmost characters were masked out on a Chinese PC.
DrawText and TextOut seemed to be confused about the actual length of the
But we found that if the Len() was * 2 it was ok.
So we have a function...
Public Function MyLen(as_Text as string)
'returns length of string, but doubled if chinese
If Asc(as_text)<0 Then
MyLen = 2 * Len(as_Text)
MyLen = Len(as_Text)
and the calls become..
li_ret = TextOut(hdc, x, y, ls_Text, MyLen(ls_Text))
The function works because the strings in Chinese are 2 bytes per character
(on an 'english' PC it prints as characters 128-255), but Asc(Text) on a
Chinese PC returns a large negative number ! You can only test on a real
'Chinese' Windows machine - a problem to debug.
Whether we get the same problem in VB6, or it's all fixed with LenB() etc,
I am yet to find out.
(The reason for VB4 is that there is a glut of extremely cheap, highly
reliable P90 Toshiba notebooks running W3.1, ideal for field use with this