Solved

Internationalisation in VB

Posted on 1998-09-23
14
157 Views
Last Modified: 2010-04-30
I need to Internationalise my VB app, I would use a resource file a string tables per LCID but:

Each Customer will need their own string table due to differing names of fields (i.e. some use Branch, others use depot, other location, etc) It seems that you can only have one string table per language per resource file, so this would be impossible. We have lots on English customers so a resource file per customer and recompiling for each is implausible.

We would need to change language on the fly, when dialling in to fix problems or during on site product set up, and as we have found to our cost switch Locales around is not a good idea.

Also some customers have a German LCID but use our product in English, why?, I don't know either.

So what I need is a way to have one string table per customer set from a registry key or database field.
Any tools or ways we can do this?
0
Comment
Question by:yerffoeg
  • 6
  • 5
  • 3
14 Comments
 
LVL 14

Expert Comment

by:waty
ID: 1436204
You have several possibilities :
  - Add all language in the same ressource file but with different ID. Ex : for English, begin to ID 0, for French begin to ID 5000
      ID 0 => Print      ID 5000 => Imprimer
      ID 1 => Window     ID 5001 => Fenêtre
Use a global variable to set the actual language. Parse all the windows, text using a function wich make the translation. I use the following function in all my applications (see below)

  - Use a database : Have a table per language, or all language in one table and one field per language.



' *** Here is the code for traduction. The comments are in french.

Option Explicit

' *** Langue
Global gnLangue   As Long

Sub TraductForm(TheForm As Form)
   ' *** Traduction d'une fenêtre ***
   ' *** On utilise l'ID qui est identifié par le @ ***
   
   On Error GoTo ERROR_TraductForm
   
   Dim nI   As Integer
   
   ' *** On commence par traduire le caption de la fenêtre ***
   TheForm.Caption = Traduction(CStr(TheForm.Caption))
   
   For nI = 0 To TheForm.Controls.Count - 1
      ' *** La traduction dépend du type du contrôle ***
   
      If TypeOf TheForm.Controls(nI) Is Label Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      ElseIf TypeOf TheForm.Controls(nI) Is Menu Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      ElseIf TypeOf TheForm.Controls(nI) Is CommandButton Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      ElseIf TypeOf TheForm.Controls(nI) Is Frame Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      ElseIf TypeOf TheForm.Controls(nI) Is CheckBox Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      ElseIf TypeOf TheForm.Controls(nI) Is OptionButton Then
         TheForm.Controls(nI).Caption = Traduction(CStr(TheForm.Controls(nI).Caption))
      End If
   Next
   
   Exit Sub
   
ERROR_TraductForm:
   Exit Sub
   
End Sub

Function Traduction(szText As String) As String
   ' *** Traduction d'un texte en recherchant l'ID dans le string ***
   
   Dim szTemp     As String
   Dim szID       As String
   Dim nPos       As Integer
   Dim nReturn    As Integer

   On Error GoTo FIND_DLL

   szTemp = ""

   ' *** On recherche le caractère séparateur ***
   nPos = InStr(szText, "@")
   
   If (nPos = 1) Then
      nPos = 1
   End If
   
   ' *** On quitte, pas de traduction ***
   If (nPos = 0) Then
      Traduction = szText
      Exit Function
   End If

   szID = Right(szText, Len(szText) - (nPos))
   
   ' *** On quitte, pas de traduction ***
   If (IsNumeric(szID) = False) Then
      Traduction = szText
      Exit Function
   End If

   If (gbModifyIterfaceText = False) Then
      szTemp = Trim(LoadResString(gnLangue + CLng(szID)))
   Else
      szTemp = Trim(colUserText("ID" & CStr(gnLangue + CLng(szID))))
   End If
   
   ' *** On quitte, pas de traduction ***
   If (szTemp = "") Then
      Traduction = left(szText, nPos - 1)
      Exit Function
   End If

   Traduction = szTemp

   Exit Function

FIND_DLL:
   szTemp = ""
   Resume Next

End Function




Public Sub SetLanguageEnglish()
   ' *** set the english traduction
   
   gnLangue = 0

End Sub

Public Sub SetLanguageFrench()
   ' *** set the french traduction
   
   gnLangue = 1000

End Sub

Public Sub SetLanguageSpanish()
   ' *** set the Spanish traduction
   
   gnLangue = 2000

End Sub

Public Sub SetLanguageGerman()
   ' *** set the german traduction
   
   gnLangue = 3000

End Sub

Public Sub SetLanguageDutch()
   ' *** set the Dutch traduction
   
   gnLangue = 4000

End Sub

Public Sub SetLanguageItalian()
   ' *** set the Italian traduction
   
   gnLangue = 5000

End Sub


0
 
LVL 1

Author Comment

by:yerffoeg
ID: 1436205
It doesn't allow for easy standardisation throughout the code, you end up with large resource files (which will be loaded into memory).
I believe the Microsoft MSDN Document Q188659
Answers our question perfectly keeps the size of the application installation down to a minimum, and the size of resource file loaded into memory.
0
 
LVL 14

Expert Comment

by:waty
ID: 1436206
I use my way, it is very easy to maintain, and it is very quick. So good work.
0
 
LVL 1

Author Comment

by:yerffoeg
ID: 1436207
Does anyone know how I can cancel this question as the MSDN Doc mentioned above suggests the use of satellite DLL's, which seem to fit our needs perfectly.

Or does someone have to answer it?
0
 
LVL 1

Author Comment

by:yerffoeg
ID: 1436208
Does anyone know how I can cancel this question as the MSDN Doc mentioned above suggests the use of satellite DLL's, which seem to fit our needs perfectly.

Or does someone have to answer it?
0
 
LVL 14

Expert Comment

by:waty
ID: 1436209
Someone have to answer this.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1436210
Answered :-)
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 1

Author Comment

by:yerffoeg
ID: 1436211
What is going on, should I just say Mirkwood has answered it and be done with it, I'd prefer to give Waty the points as he did give me an answer, but it's not like he needs them.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1436212
It was just a joke. Nobody answered the question so I did.
I can give you another solution though.
Use the functions below. Put the resources in a seperate library.
With loadlibrary load the correct resource library and close the handle of the library after you don't need it anymore.
With LoadResource you can load the resource of the determined library.

Declare Function LoadResource Lib "kernel32" Alias "LoadResource" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long

Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long



0
 
LVL 14

Expert Comment

by:waty
ID: 1436213
If you want, I can accept the answer.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1436214
That's ok to. Just reject my answer. Waty answers it and accept his answer.
0
 
LVL 1

Author Comment

by:yerffoeg
ID: 1436215
Rejected for Waty, Sorry I'm a bit confused I'm just getting the used to the way this works.
0
 
LVL 14

Accepted Solution

by:
waty earned 100 total points
ID: 1436216
Thanks to all.

yerffoeg, what is the solution Microsoft gave you?
0
 
LVL 1

Author Comment

by:yerffoeg
ID: 1436217
If you want to know the full idea read the article Q188659 on MSDN, basically it involves creating an Activex DLL which contains the resource file and a couple of functions to read/write the resouce string. Then you can compile a DLL for every customer/language, just be changing the resource file. The id number can obviously stay the same throughout. Then all you need is a simply way to tell the program which DLL to use, in a regkey or the like. I like it better as a solution it just seems neater, a better for our needs than yours, especially if you have alot of customers. I given you a B because I'm sure your method would suit some people more than the method I found. Anyway thanks for your response, hears a ton.

Dave.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now