Why another article about multilingual applications?

Well, about a year ago, I needed my application to support multiple languages. I thought it would be very easy to find out how to do this. There are a lot of articles that explain how to do this, but none of them fit my needs.

What can I find here?

What I really needed were simple .h and .cpp files which are able to load a language DLL and extract the strings I need. None of the articles I found provided this. At this point, I decided to write my own classes which could do the task I wanted them to do. I am a little active on some forums, and I see this question keeps coming back of how to implement multiple languages to an application. What I see is that it is really hard to understand how it works, the first time. So I decided to write a little article and add my language files to CodeProject.

I tried to implement the files so that they are really easy to use. Let's explain how the class works.

Use string tables

Some people are still hard-coding the strings of their application in their code. This isn't the best solution on earth. So use string tables, because this is needed if you want to add multiple language support to your application.

Add files to project

First of all, you have to add the files Language.cpp and Language.h to your project. Now you are almost ready adding multilingual support to your application. The class I developed is a so-called singleton class. This means that you don't have to create the class every time. You only have to load and release the language at startup, and you can use the class everywhere.

How to load a language

Now, you are ready to load your first language. Normally, you load language at the startup of your application. Here is some example code that will try to load the system's default language:

It was pretty easy to load a language, wasn't it? Keep in mind that the Init function is not really needed. If you don't call this function, the defaults "lng" and "english" are used. But this is not all, you also have to load the strings.

How to load strings

You have loaded a language, but you also want to load strings. For example, you have a dialog with a nice static control. This is how you load the language:

The language object will see if the user has loaded a valid DLL. If so, the string will be loaded from the DLL, if not, the default string table will be used. Still easy isn't it? That is all you have to do in your application.

How to create the language DLLs

There are a few easy steps to take:

Create project.

First, you have to create a project for your DLL. Start Visual Studio, and choose File -> New.... Then select Win32 Dynamic-Link Library. Give your project a new name and click OK. You now have seen a wizard, select a DLL that exports some symbols. The default files for the DLL are now created.

Copy string table from original project.

Now the default files are created, close the current (language DLL) project. Open your real application in the IDE now and open the string table. Use CTRL + A to select all items and then copy them. Close project again.

Add string table to language project.

Open your language project again. Select File -> New... and select resource script. Give the resource script a name and click OK. Now you can add resources to your project. Right click on the resource file and select Insert..., then select String table. Now copy the string table of your application to the language DLL (just use CTRL + V). As you will see, all values are now in the language DLL. You can start translating all the sentences now. If you are ready, you can compile the project. The DLL is now ready to use!

There are a lot of languages automatically supported by the language class. Of course, you can edit these settings yourself in Language.cpp (see InitLanguages function). A list of languages supported and the name of the DLL which is expected is given below:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

I am Geert van Horrik, and I have studied Computer Science in the Netherlands.

I love to write software using .NET (especially the combination of WPF and C#). I am also the lead developer of Catel, an open-source application development framework for WPF, Silverlight, WP7 and WinRT with the focus on MVVM.

I have my own company since January 1st 2007, called CatenaLogic. This company develops commercial and non-commercial software.

Will your application support japanese stirngs. If so How to create a japnese string dll.
When I tried the approach described, When I coping and pasting the stirngs I am getting ????? in stringtable in the japanese dll project .

although your code looks very smart and I'm convinced it works in most cases, I bet there are some (or a lot of?) cases you just oversaw or didn't even think on them.

I had the same problem quite a long time ago and did a research on the web on existing tools. I was afraid, most of them where quite expensive and disgned for translators to use, not for developers. Finally, I found some usable tools and decided to use Inlocate (formerly known as RapidTranslation). I'm using it since version 3.5 and I'm really satisfied (ok, version 4 was ... awful, but the current version is great again!)

It offers all the features you mentioned and even some more, like runtime switching for exmple, which might be interesting for some guys.

Although it's a professional tool, they offer (at least, they did with version 3.5) a "developers program", meaning that share- and freeware developers could receive a free version. Don't know, if this offer is still available...

Great, your code works fine. But I have one big problem: I cannot copy the source string table of my application to the new language library project. It seems the clipboard function does not support that. How did you solved that problem ?

I work with VC++ 6 under XP Prof. Ok, last chance is to type in the entries by hands. but what should I do if applications string table is very huge ?

I have a small doubt regarding Globalization/Localization. Hope you can help me out.
I have a web form application where i need to provide more than 50 different localized resource supports. Apart from this, my application supports rich use of stored data (Sql Server Database) and obviously have few list of Listing controls (Repeater , Grid etc).

My requirement comes like this,

a) I need to provide full localized language support in all data which is displaying in each and every page. Regardless of, the name of controls, content of controls etc. To be concise, which ever text that i am displaying through page, need to be localized based on user selected language.

b) Each and every setup needs to contain all supported languages. So user can switch and view content of site in different language.

I stuck in,

1) I am not sure how to localize stored data in database.
2) How will I give or from where i generate localized information for all supported language.

This article covers the translation of strings in an application. What you need, is much more. You want different screens for every language.

This simple means you have to copy the complete resource dll to make it local. Microsoft has some greate articles about it.

About the database. I should not translate items in a database. The database is the document. The application around the document can change to the user data, but I think the document should stay the same. Because what if a language is added after a few months? In that case, your database does not contain valid data anymore.

Sorry, but I would not recommend your article for anyone in need to incorporate multilingual support in his/her application.

First of all, strings are not the only thing to take care of. You must take care about calendar, time, currency, float number format in strings, national preferences in colors, control size and captions, etc.

Part of multilingual support should reside in an app itself (use Unicode, local aware date/time functions, etc.)

The other part - GUI layout, colors, etc, - should be in a resource dll.

All this is described in great details on MSDN under title 'Localization'.

How to change menu, icons, toolbars etc. this way e.g. in MDI application ? Don't forget, that not all icons and pictures have the same meening in different countries. I use multiple dlls as well, but with all resources and I change them by calling LoadLibrary and AfxSetResourceHandle.

Hello Geert. Let me to make some considerations. Often who executes the translation is not a programmer. Above all when the application is much vertical one and therefore make use of terms or expressions many techniques. To the subject that it will execute the translation is necessary to transmit a list of the terms to translate. The same one will give back an other list in which, to flank of the terms in the native language they are indicates the same ones translated.

If it could Be used rows external as dictionary of the terms the suguenti advantages could be obtained:

1) the translator could verify in real Time the result of its translation
2) would not be necessary to predispose to the inside of the application of numerous string tables.
3) In every moment he could be added new rows of dictionary without having to take part in the application.

I have realized one solution of this type. Let me know if are intrested int.

This is indeed a good approach. What is possible is add the values to a XML file. However, sometimes you don't want the users to be able to edit the text.

I received a mail last week about another approach: using an access database.

I am interested in your approach too. If it is ok, I can add it to this article (of course with references to you). Then the user can choose between 3 different types of translating applications:
1) Dll's
2) XML (dictionary files)
3) Access database

I want the class to support all of these solutions, which will make it very useful. However, it must be done without using MFC, so I have to check how I can communicate with an access database without using MFC.

One problem with translating resources (mostly strings) from one language to another is the length of the displayed string. You most times have to resize the dialogs, forms, static texts, etc. to fit the translated text.
One small example of what I am saying, is say you have a dialog/form with a button that has the following text "Save As...", and you want to translate it to the greek text "Αποθήκευση ως...". You cannot only change the text but also stretch and possibly rearrange the button to fit the additional 6 characters. Without this it would result to parts of the string been hidden or overlap other controls on the dialog/form.
These kind of problems can be solved easily only using dlls. I suppose other ways are more difficult to implement or require more work for both the programmers and the translators.

For simple translations, you can use text files or xml files or things like that. But when you are going to translate to so many different applications, you need to change the size of the text boxes as well.

Therefore, I am going to implement some functions that can load toolbars and dialogs. However, I have to check if this is not coming too close to existing functions because then it would be a waste of time.