Language Overview
Return to Introduction  Previous page  Next page
VO provides multilingual support through the use of the LoadResString() function. LoadResString() looks up a special resource called a string table and returns a string that matches the supplied identifier. A string table entity starts with the word RESOURCE followed by the name of the entity and then the word STRINGTABLE. For example:

RESOURCE VOPP_Language STRINGTABLE
    BEGIN
        100,"My Application"
    END

Between the BEGIN and END in the string table are lines of identifer and string pairs. LoadRestring() can search the string table for a given identifier, e.g.:

cText := LoadResString("Default application",100,hModule)

In this example LoadResString() looks for the identifier 100 in the string table that belongs to the EXE/DLL whose handle is hModule (see the WinAPI function GetModuleHandle() for more information about EXE/DLL handles). If the identifier is not found then LoadResString() will return "Default application".

LoadResString() also supports the use of a string as the last parameter, instead of the handle hModule - in which case the string should be the name of the EXE/DLL.

Rather than use the literal number as the string identifier it is better to use a DEFINE that gives you some hint to the use of the string. So our string table above could also be written as:

RESOURCE VOPP_Language STRINGTABLE
    BEGIN
        ID_APPTITLE,"My Application"
    END

and we need to include a DEFINE:

DEFINE ID_APPTITLE := 100

This would then mean the application code could be written as this:

cText := LoadResString("Default application",ID_APPTITLE,hModule)

By using LoadResString() in your code, and controlling which EXE/DLL it looks at, you can determine what language your application displays.

Following this design you need to create a DLL for each language you want your application to support. In each DLL you have a string table, using the same identifiers but containing a different translation for each one. For example you might have English text in APP-EN.DLL and French text in APP-FR.DLL. In the English APP-EN.DLL the string table could look like this:

RESOURCE VOPP_Language STRINGTABLE
    BEGIN
        ID_OPEN,"Open"
    END

And in the French APP-FR.DLL the string table could look like this:

RESOURCE VOPP_Language STRINGTABLE
    BEGIN
        ID_OPEN,"Ouvert"
    END

The corresponding application code to use these DLLs might look like this:

cLangDLL := "APP-FR.DLL"  // or could be APP-EN.DLL
hModule := LoadLibrary(cLangDLL)

cOpen := LoadResString("Open",ID_OPEN,hModule)

Normally the language DLL would be loaded once, at the start of the application, so you could use a GLOBAL or an instance variable of your app/window to hold on to the handle value.

Note that the identifier constant ID_OPEN is used in each DLL and the application itself, so it would be best to put the DEFINEs for the language constants into a library that is shared by DLLs and application.

Each time you want to use a string in your application you should use LoadResString() in your code instead of the literal string. And each time you use LoadResString() you should go to each of your language DLLs and to the language DEFINE library to make sure they are updated with the appropriate values. The VOPP Language Assistant lets you make these updates without having to open any of the language DLLs or the DEFINE library.

There is one more special situation to note regarding the way VO makes use of LoadResString. Any text that is entered in to the Window and Menu editors for entries like caption or description are automatically turned into strings when the editor is closed and the class and Init() code is generated. Unfortunately this means that if you type LoadResString(...) into the caption field it will be changed into the literal string "LoadResString(...)" when the code is generated. The work around for this problem is not intuitive - you need to type the < character instead of LoadResString( and the > character in place of the ). So, in the Window and Menu editors, to get VO to generate:

LoadResString("Open",ID_OPEN,hModule) 

you need to type:

<'Open',ID_OPEN,hModule>


© Piko Computing Consultants, 1998-2002