Isolating Localizable Resources

Glossary

It is easy to identify source code that isn't properly set up for localization. The most extreme cases are populated with hard-coded strings, constants, and characters. Files containing hard-coded localizable elements are a nightmare to deal with. Translators cannot simply translate the source code files, especially if the code is continually evolving. Many translators are not programmers and might delete important details, such as closing quotes or semicolons, or translate programming keywords as well as strings. Then developers must take time to clean up these files so that they will compile correctly.

Separating all localizable items into one or more files makes localization much easier to manage. The following major program elements require localization:

  • Certain algorithms
  • Messages
  • Constants
  • Prompts
  • Dialogs
  • Sounds
  • Macro languages
  • Status bars
  • Menus
  • Toolbars

One approach would be to create a complex process to strip out all localizable items from source files and reincorporate them once they have been translated. That way, you could declare strings in the same area as the code that uses them. However, designing and implementing such a scheme hardly seems worth the effort when better localization methods are available. An alternative approach would be to place all strings and constants in header files, but then you would have to recompile any source files that included translated headers. By far the simplest and most straightforward method of dealing with localizable resources for Windows-based applications is to put everything in one or more Windows resource files. As Chapter 4 describes in more detail, Win32 resource files are easy to edit, and they eliminate the need for recompiling source code.

In addition to elements of the user interface, you might need to customize some algorithms based on language or locale. If your application will support multilingual documents, you'll need to carry code that gives the correct results for a number of languages. Avoid using #ifdef statements around code to handle special cases based on language or locale. (See the next section, "Eliminating Compile Dependencies," for more advice on using #ifdefs.) They aren't worth the cost of recompiling your main executable. Whenever possible, write generic code to support cultural conventions using the NLSAPI. (See Chapter 5.) You can separate language-sensitive or locale-sensitive features that require large code differences—such as spell-checkers or grammar-checkers—into DLLs. (See Figure 2-6.)

Figure 2-6 A localized executable consists of compiled source code plus a localized user interface. Customized code can be isolated in a DLL.

The sample directory structure in Figure 2-7 illustrates how all localizable files, whether they contain code or user interface elements, can be placed in a single directory. Translators need access only to the directory containing the nativelanguage files and the localized files for which they are responsible. A multilingual build process can incorporate resource files from the appropriate language directory and place resulting files in the appropriate language's build directory.

Figure 2-7 Sample directory structure. All files that need to be customized based on language are in the resources directory Developers update files in the native directory and use batch files to propagate the changes to other language directories.