Chapter 18: Developing International Applications

To move into the world market, you must design your Visual FoxPro applications so that they're as effective internationally as domestically. This chapter describes how to use the international features of Visual FoxPro to produce applications for selected locales.

This chapter discusses:

Planning an International Application

Preparing an international application usually involves three steps: creating data, writing code, and designing a user interface. Before you take these steps, however, you need to consider the following questions:

The following sections address these questions and pose others you need to consider before you prepare your application.

Tip   You can reduce the cost of developing an international application and bring it to market more quickly by designing it as an international application initially rather than modifying it for international use later on.

Preparing the International Data

To create international data for an application, you can enter it manually, import it from other applications, or append it to existing files and memo fields. For details about importing and appending data, see Chapter 9, Importing and Exporting Data, in the User’s Guide.

What Data Is Acceptable?

To decide what data is acceptable, first consider the locales in which the application will be used. The locales will determine the cultural content of the data as well as the languages in which the data is prepared.

In addition, the languages will affect the code page with which the data is prepared. A code page is a character set that a computer uses to display data properly, often to handle international characters. International characters include characters that have diacritical marks. Diacritical marks are placed over, under, or through letters to indicate sound changes from the unmarked form. The most common diacritical marks are the grave accent (` as in à), acute accent (´ as in á), circumflex (^ as in â), tilde (~ as in ã ), umlaut (¨ as in ä ), ring (° as in å), and slash (/ as in ø), all used in conjunction with vowels.

Ordinarily, data is automatically marked with the appropriate code page when you work with it. However, if you manually assign a code page to a table, or if you otherwise cause the code page to change, users might not recognize some or all of the data displayed. For details about code pages, see Working with Code Pages later in this chapter.

Some languages, such as Chinese, Korean, and Japanese, use DBCS (double-byte character sets) to represent their data. If your application might run in these environments, you might need to use special string-handling functions and collation sequences for the application to work properly. For details about working in DBCS environments, see Working with Double-Byte Character Sets later in this chapter.

How Do You Write Code?

An application consists of a user interface component and an application component. The user interface component contains graphics, text strings, and settings related to various locales, such as dates, currencies, numeric values, and separators. The application component contains the code that is run for all locales, including code that processes the strings and graphics used in the user interface.

The components of an application

When designing your application, keep the application and user interface components separate, because independent components make the application easier to localize and maintain. For example, with separate components, you don’t have to browse the source code to localize interface elements. For more information about writing code, see Creating or Modifying Programs, later in this chapter.

How Do You Design a User Interface?

The menus, forms, controls, toolbars, and bitmaps used in the user interface must serve the locales for which you’re designing the application. For example, if you design the application for users in Germany and France, dialog boxes must be large enough to display instructions properly when the instructions are localized in German and French. In addition, the images used in icons and bitmaps must be culturally correct so that they're understood in the target locales. For more information about designing user interfaces, see Designing the Interface, later in this chapter.

Testing the Application

To test an international application, you need to check the country or region and language dependencies of the locale for which the application is designed. Testing involves checking the application’s data and user interface to ensure that they conform to the locale’s standards for date and time, numeric values, currency, list separators, and measurements.

Designing the Interface

Because text tends to increase when you localize an application, be careful when designing the following user interface components:

Creating Application Messages

When you create messages in your application, English text strings are usually shorter than equivalent text strings in other languages. The following table shows the additional average growth for strings, based on their initial length.

English length (in characters) Additional growth for localized strings
1 to 4 100%
5 to 10 80%
11 to 20 60%
21 to 30 40%
31 to 50 20%
over 50 10%

Designing Menus and Forms

As with messages, menus and forms can grow when the application is localized. For instance, consider the following forms, which are part of an Automated Teller Machine sample application. The first figure shows the English form, and the second figure shows the Spanish equivalent. You can see that extra space was allocated for text to increase in the form.

Tip   If you allow room for text to increase in an interface, localizers need less time to resize controls and to redesign the interface.

Text needs more room when localized.

In menus and forms, avoid crowding status bars. Also, avoid abbreviations, because they might not exist in other languages.

Using Icons and Bitmaps

Used properly, icons and bitmaps can be an important part of a user interface. However, the meaning of icons and bitmaps can be more ambiguous than the meaning of words. Therefore, consider the following guidelines when using icons and bitmaps:

If you’re not sure whether an icon or bitmap is appropriate, consult someone in the locale for which you’re designing the application.

Entering International Data

An important aspect of developing international applications is knowing how to enter data into your application. Data can come into your application in two ways:

The following sections discuss these two methods.

Entering International Characters

You can enter international characters into Visual FoxPro using your keyboard. The exact method you use depends on the language you're working with. In single-byte character environments, you can enter the characters directly, or by pressing a combination of keys on the keyboard. On the other hand, DBCS environments often provide an Input Method Editor (IME), which is an application you can use to enter characters.

Entering Characters Using the Keyboard

With an international keyboard, you can display international characters by simply pressing the keys dedicated to those characters. If your keyboard doesn’t have keys for international characters, you can enter such characters by using the character map provided with Windows or by pressing the ALT key in conjunction with keys on the numeric keypad.

The easiest way to enter an international character is to copy it from the character map. In Windows 95, the character map is available from the Accessories menu.

Alternatively, you can enter an international character by pressing ALT combined with a four-digit number beginning with zero that you enter from the numeric keypad.

Note   You cannot enter international characters in FoxFont. For example, if you open the Command window, switch to FoxFont, and then press a dedicated key, the result isn’t the character on the key. For best results, avoid FoxFont in international applications.

To create an international character

For instance, to type ö (ANSI code 246), press NUM LOCK on the numeric keypad, and then press ALT+0246. Be sure to use a standard Windows font — not FoxFont or FoxPrint.

Troubleshooting   If characters don’t transport correctly, see if you’re using FoxFont. For example, FoxFont is the default for user-defined windows created with DEFINE WINDOW (if the FONT clause is omitted). Be sure to use the FONT clause to specify a font other than the standard Windows font when creating user-defined windows so that international characters display correctly.

Entering Characters Using an IME

If you're working in an IME environment, you can use an Input Method Editor to enter characters into Visual FoxPro. The IME is an application provided with your environment that allows you to type characters on the keyboard to display a selection of international characters and then choose the specific character you want. For example, an IME for Chinese might allow you to enter a Pinyin representation of a Chinese word and then display a list of characters that match the representation. When you select the character you want, the IME pastes it into Visual FoxPro.

You can control when Visual FoxPro displays an IME by setting the IMEMode property or calling the IMESTATUS( ) function. If you turn the IME window on, Visual FoxPro automatically displays the IME when you're editing in a system window such as the Browse or Edit windows. If you turn the IME window off, you can invoke the IME by pressing the appropriate keys on your keyboard.

Appending and Copying International Data

If you're importing or copying data from delimited files using the APPEND FROM or COPY TO commands, you can specify what character is being used in the file to separate fields. For example, it's common in many European countries to use a semicolon (;) as a field delimiter, whereas the common delimiters in the United States are comma (,), tab, or space.

To import or copy files and specify a delimiter, add the DELIMITED WITH CHARACTER clause to the APPEND FROM or COPY TO commands:

COPY TO mytxt.txt DELIMITED WITH _ WITH CHARACTER ";"

Working with Code Pages

Data stored in Visual FoxPro is often tagged with a code page, which is a table of characters and corresponding numbers in memory that Windows uses to display data properly. For example, if you enter the letter C in a .dbf file, the letter is stored on your hard disk as the number 67. When you open the file, Visual FoxPro determines its code page, inspects the code page to find the character corresponding to the number 67, and then displays the character (C) on your monitor.

Code pages correspond roughly to different alphabets. For example, Windows supplies code pages for English, German, Scandinavian languages, and so on. By using a different code pages, applications can properly display characters from these different alphabets.

Understanding Code Pages in Visual FoxPro

Visual FoxPro displays data using one code page. By default, this is the current code page used by Windows. However, you can override the Windows code page by specifying an alternative code page in your configuration file (you must specify a valid code page).

Tables in Visual FoxPro are tagged with the code page that was in use when the table was created. When you use the table, Visual FoxPro checks the code page for the table against the current code page. If they match, Visual FoxPro displays the data as is. If there is no code page for the table (for example, the table was created in an earlier version of FoxPro), Visual FoxPro prompts you for a code page and then marks the file with it.

If the table code page does not match the system code page, Visual FoxPro attempts to translate characters from the table code page into the current one. For example, if you're using Visual FoxPro and the current system code page is the English code page, the character ü is represented by ANSI value 252. If the code page for the table represents the ü character as ANSI value 219, Visual FoxPro translates all instances of ANSI value 219 into ANSI 252 so that they display properly.

Code page translation doesn't work perfectly in all instances, because code pages usually contain characters that are not represented one-for-one in other code pages. For example, you cannot map data that contains the MS-DOS® line-drawing characters into Windows, because the Windows code pages don't contain line-drawing characters. Similarly, you cannot translate data created in the Russian code page into an English code page, because there isn't a one-to-one correspondence between the alphabets for these languages. Finally, Visual FoxPro might not contain a character translation map for a particular code page. In that case, the data is displayed with no code page translation. (Visual FoxPro does not display an error to indicate that no code page translation is occurring.) Any of these situations can cause some characters to display improperly.

If you want to create an application for a specific locale, you can avoid code page translation problems by creating the application’s components using the code page designed for that locale and environment. For example, to create an application for use in Russia, you should use code page 1251, 866, or 10007 for users in the Windows, MS-DOS, or Macintosh environments, respectively.For a complete list, see Code Pages Supported By Visual FoxPro later in this chapter.

If you need to enter some characters not represented by keys on your keyboard, you can enter these characters using ALT in conjunction with keys on the numeric keypad. However, remember that the same key combination in different environments often displays different results. For example, if you enter ALT+0182 with code page 1252 in Visual FoxPro, you see a paragraph symbol. In contrast, if you enter ALT+0182 with code page 437 in FoxPro for MS-DOS, you see a graphic character with a double vertical line meeting a single horizontal line.

Although Visual FoxPro supports many code pages, only a few are used often. With Visual FoxPro for Windows, for example, English-speaking users typically use code page 1252, while in Visual FoxPro for Macintosh, English-speaking users typically use code page 10000. However, in FoxPro for MS-DOS, English-speaking users typically use code page 437.

When working with code pages, be sure to test that the user interface and data display correctly by using the code page designed for a particular locale. If you see unexpected characters on the screen, check the underlying code page.

Specifying the Code Page of a .dbf Files

When you create .dbf files, Visual FoxPro automatically gives them code page marks so that you can tell which code pages they use. However, if you use .dbf files from previous versions of FoxPro, they might not have code page marks.

You can determine whether a .dbf file has a code page mark by using the CPDBF( ) function after opening the file or by having Visual FoxPro check when you open the file.

To check for code page marks automatically

  1. From the Tools menu, choose Options.

  2. Select the Data tab.

  3. Set the Prompt for code page check box, if it's not already set.

    To save this setting for future sessions of Visual FoxPro, choose Set as Default.

    Tip   Instead of setting the Prompt for code page check box, you can use the SET CPDIALOG command to check for code pages.

If a file doesn’t have a code page mark, you must add a mark, as described in the following section.

Adding Code Page Marks

If you use a .dbf file from a previous version of FoxPro, the file might not have a code page mark; without such a mark, the file might not display properly. If automatic code page checking is enabled, when you open the file you can tell if it has a code page mark. If it doesn’t have one, you can add one.

To manually add a code page mark to a .dbf file

  1. Ensure automatic code page checking is in effect (see the previous procedure).

  2. Open the file.

    If the file doesn’t have a code page mark, the Code Page dialog box appears.

    The Code Page dialog box

  3. Choose the appropriate code page.

  4. View the file to see if you assigned the proper code page.

    If you can’t see some of the data, or if you can’t recognize some of it, the code page is not correct.

  5. If the code page is incorrect, remove the code page mark by using the CPZERO program in the Visual FoxPro Tools\Cpzero directory. For details, see Removing Code Page Marks later in this chapter.

  6. Repeat this procedure until the code page is correct.

    Note   Text files such as program (.prg) and query (.qpr) files don't have code page marks. This means that you can’t tell which code pages the files use. However, if you include such files in a project, the project can keep a record of the code pages used. For details, see Specifying the Code Page of a Text File later in this chapter.

Removing Code Page Marks

If a .dbf file doesn't display properly, it might have the wrong code page mark. You can remove the code page mark with the CPZERO program located in Tools\Cpzero. Running CPZERO sets the code page to 0, meaning none.

To remove a code page mark

Changing Code Page Marks

You can change the code page of a .dbf file by removing its code page mark and then adding a new one, by copying the file to another file, or by using the CPZERO program.

To change the code page of a .dbf file by copying the file

When the COPY TO completes, the data in the resulting file will have the new code page.

To change a code page mark using CPZERO

Specifying the Code Page of a Text File

If you forget the code page of a text file that’s not part of a project, you cannot determine the code page, because a text file doesn’t have a code page mark  as .dbf files have. The best way to remember the code page of a text file is to add the file to a project.

To specify the code page of a text file

  1. Open the Project Manager.

  2. Select the text file whose code page you want to specify.

  3. From the Project menu, choose Project Info.

  4. In the Project Information dialog box, click the Files tab.

  5. Right-click the selected file.

  6. From the submenu, choose Code Page.

    Visual FoxPro displays the Code Page dialog box.

  7. Choose the appropriate code page.

    Visual FoxPro displays the available code pages.

If you know the code page of a text file, you can specify it by using the AS clause of the appropriate Visual FoxPro command. For files you want to import or append, you can specify the code page in the IMPORT or APPEND commands. For query, program, and other text files already on your computer, you can change the code page using the MODIFY QUERY, MODIFY COMMAND, and MODIFY FILE commands.

If you’re not sure which code page to apply, substitute the GETCP( ) function for the code page number in the command. GETCP( ) displays the Code Page dialog box, allowing you to select the appropriate code page.

Note   Some characters cannot be translated between code pages successfully. In addition, some code page translations aren't supported by Visual FoxPro. Always check the results of a code page change to be sure that your data has been translated successfully.

Determining the Code Page of a Project File

After adding a file to a project, you can determine its code page. The method you use depends on whether the file is a table (.dbf file) or a text file.

To determine the code page of a text file

  1. Open the Project Manager.

  2. Under Other, select the text file whose code page you want to know.

  3. From the Project menu, choose Project Info.

To determine the code page of a table

When you build an application from a project, the Project Manager automatically integrates the files in the project, no matter how many different code pages they have. The resulting application has the current code page.

Note   When you add a .dbf file to a project, you don’t have to specify a code page for the file, because Visual FoxPro automatically determines the code page from the file’s code page mark. However, when you add a text file to a project, you must specify a code page for the file, because Visual FoxPro cannot determine the code page automatically.

To prepare a program for use with another code page, specify the original code page when you save or compile the program on the new platform. For example, to prepare a program created with Visual FoxPro for Macintosh for use with Visual FoxPro, specify the appropriate MS-DOS code page when you save or compile the program with Visual FoxPro. If you use the COMPILE command, specify the code page using the AS clause. Alternatively, specify the code page with SET CPCOMPILE before compiling the program.

Specifying Code Pages for Variables

You might want to manipulate international data in certain ways. For example, you might want to translate the data in a variable to another code page, or you might want to prevent translation of data in a character or memo field.

Translating Data in Variables

If the code in your application includes a variable containing data from another code page, you can translate the data to the proper code page using the CPCONVERT( ) function. For example, suppose the variable x contains data created with the Macintosh® code page (10000). To translate the data to the Windows code page (1252), issue the following command:

cConvert=CPCONVERT(10000,1252,x)

In Windows, the converted data looks just as you see it on the Macintosh. For example, a character that looks like “ä” on the Macintosh looks identical in Windows.

Preventing Translation of Data in Character or Memo Fields

In some cases, you don’t want automatic code page translation. For instance, if a character field contains an encrypted password, you don’t want Visual FoxPro to automatically translate the password, because doing so would alter it.

To prevent translation of data in a character or memo field

  1. Open the project containing the table.

  2. Select the table.

  3. Choose the Modify button.

    The Table Designer appears.

  4. Select the field whose data you want to protect.

  5. From the Type list, select Character (Binary) for a Character field, or Memo (Binary) for a memo field.

  6. Choose OK, and then choose Yes to make the changes permanent.

  7. Verify the changes by displaying the structure of the table with the DISPLAY STRUCTURE command.

    Alternatively, use the MODIFY STRUCTURE command to protect the appropriate fields.

You can also prevent translation of selected characters in text files by using the CHR( ) function.

Code Pages Supported by Visual FoxPro

A code page is a set of characters specific to a language or hardware platform. Accented characters are not represented by the same values across platforms and code pages. In addition, some characters available in one code page are not available in another.

Code page Platform Code page identifier
437 U.S. MS-DOS x01
620 * Mazovia (Polish) MS-DOS x69
737 * Greek MS-DOS (437G) x6A
850 International MS-DOS x02
852 Eastern European MS-DOS x64
861 Icelandic MS-DOS x67
865 Nordic MS-DOS x66
866 Russian MS-DOS x65
895 * Kamenicky (Czech) MS-DOS x68
857 Turkish MS-DOS x6B
1250 Eastern European Windows xC8
1251 Russian Windows xC9
1252 Windows ANSI x03
1253 Greek Windows xCB
1254 Turkish Windows xCA
10000 Standard Macintosh x04
10006 Greek Macintosh x98
10007 * Russian Macintosh x96
10029 Macintosh EE x97

* Not detected when you include CODEPAGE=AUTO in your configuration file.

Sorting Data in International Applications

After creating a table of international data, check to see if your application sorts the data correctly. How the data sorts depends on the code page associated with the table, because the code page specifies the available sort orders or collation sequences.

Understanding Sort Orders

Sort orders incorporate the sorting rules of different locales, allowing you to sort data in those languages correctly. In Visual FoxPro, the current sort order determines the results of character expression comparisons and the order in which records appear in indexed or sorted tables.

Note   Sorting works differently in double-byte character (DBCS) environments. For details, see Sorting DBCS Data later in this chapter.

Use the appropriate sort order, because different sort orders produce different results, as shown in the following table.

Unsorted Machine General Spanish
!@#$ Space space space
1234 !@#$ !@#$ !@#$
space 1234 1234 1234
Caesar Caesar äa äa
cæsar Car ab ab
Strasse Char äb äb
straße Czech Caesar Caesar
Car Strasse cæsar cæsar
Char Ab Car Car
Czech Cæsar Çar Çar
ab Straße Char Czech
Çar Çar Czech Char
äa Äa Strasse Strasse
äb Äb straße straße

Sort Order Guidelines

Consider the following guidelines when choosing a sort order:

The following sections describe how to specify sort orders, check the current sort order, and recognize the effects of sort orders.

Specifying Sort Orders

You can specify a sort order for character fields used in subsequent indexing and sorting operations.

To specify a sort order

  1. From the Tools menu, choose Options.

  2. Select the Data tab.

  3. In the Collating sequence box, select the appropriate sort order.

    To save this setting for future sessions of Visual FoxPro, choose Set as Default.

    Tip   You can also specify a sort order with the SET COLLATE TO command or the COLLATE statement in your Config.fpw file. For details about Config.fpw, see Chapter 3, Configuring Visual FoxPro, in the Installation Guide.

The current sort order doesn’t affect previously created indexes; however, it does affect the results of comparisons and commands such as SEEK and SELECT - SQL. For details, see Recognizing the Effects of Sort Orders later in this chapter.

You can change the sort order at any time. For instance, after opening a customer table, you can create index tags representing different sort orders, as shown in the following code. Then, you can change the sort order by simply using a different tag:

USE customer
SET COLLATE TO "GENERAL"
INDEX ON fname TAG mygeneral ADDITIVE
SET COLLATE TO "MACHINE"
INDEX ON custid TAG mymachine ADDITIVE
SET COLLATE TO "DUTCH"
INDEX ON lname TAG mydutch ADDITIVE

Note   The sort order for an index overrides the current sort order.

The current code page determines which sort orders are available. If you use SET COLLATE to specify a sort order not supported by the current code page, Visual FoxPro generates an error. Also, if you specify a sort order in Config.fpw that isn’t supported by the current code page, the sort order defaults to Machine.

Checking Sort Orders

You can determine the current sort order by using the SET ('COLLATE') function. For example, you can save the current sort order, set the current sort order to Machine, perform whatever work is necessary, and then restore the original sort order by using the following code:

cCurrentOrder=SET('COLLATE')
SET COLLATE TO 'MACHINE'
*
* code that requires the Machine sort order
*
SET COLLATE TO cCurrentOrder  && return to the previous sort order

You can also determine the sort order of an index or index tag by using the IDXCOLLATE( ) function.

Recognizing the Effects of Sort Orders

The sort order affects the results of string comparisons, SEEK, and SELECT - SQL, as described in the following sections.

Comparing Strings

All sort orders except for Machine and Unique Weight ignore case. This means that you don’t have to use UPPER( ) in your index expressions.

The current sort order affects string comparisons. For example, when you set the sort order to General, the following statements return true (.T.):

?"A" = "a"
?"Straße"="Strasse"
?"æ" = "ae"

However, when you use the Machine sort order, all of these statements return false (.F.). because the strings are matched for an exact comparison, byte by byte.

The character string comparison operator (= =) gives you the same result as when you compare by value or when you compare using the Machine sort order; that is, it compares strings byte by byte. For example, the following statement returns false (.F.):

? "Straße" == "Strasse"

Note   Visual FoxPro ignores SET EXACT when you use the character string comparison operator (= =).

Using SEEK

Visual FoxPro ignores diacritical marks when you perform a partial seek. A partial seek occurs when you make the length of the expression less than the length of the key. If diacritics are important, consider using SCAN FOR...ENDSCAN or LOCATE FOR...CONTINUE instead of SEEK.

The advantages of using SCAN and LOCATE instead of SEEK include the following:

Using SELECT - SQL

The SELECT - SQL command uses the current sort order. For example, if you have an index tag based on the General sort order, and the current sort order (returned by SET ('COLLATE')) is Machine, the result of SELECT SQL is based on Machine.

To employ the current sort order, use the ORDER BY clause of SELECT - SQL.

Using Indexes

Sort orders determine the order of records in indexed tables. Consider the following guidelines for using indexes with sort orders:

Working with Double-Byte Character Sets

Visual FoxPro supports DBCS (double-byte character sets) — character sets that require more than one byte to represent a character. Some examples of languages that require a double-byte character set are Simplified Chinese, Traditional Chinese, Japanese, and Korean.

Visual FoxPro DBCS support allows you to create international applications. For example, you can create a Japanese application with a U.S. version of Visual FoxPro if you're running the Japanese version of Windows. The Visual FoxPro DBCS functions operate properly on the Japanese character set, and the Japanese collation sequence is supported.

Note   Visual FoxPro provides special programming functions for use with string in DBCS environments. For details, see Working With Strings in DBCS Environments later in this chapter.

Using DBCS Characters When Naming Objects

Visual FoxPro allows you to use DBCS characters when naming elements of your applications. As with Visual FoxPro generally, elements can:

These rules apply to variables, objects (windows, menus, and so on), function and procedure names, class and subclass names, aliases, and constants. You can also use double-byte characters for file names. To avoid the possibility that characters in the file name are inadvertently treated as delimiters, it's safest to always enclose the file name in quotation marks.

Note   Visual FoxPro length limits are expressed using single-byte characters. Using double-byte characters in field names, index expressions, variable names, window names, and so on, effectively shortens the length of the name. For example, a field name can be up to 10 bytes long in a free table, so a field name can consist of 10 single-byte characters, but only 5 double-byte characters. For more information about Visual FoxPro system capacities, see System Capacities.

Sorting DBCS Data

To help you order information in DBCS environments, Visual FoxPro supports collation sequences for Simplified Chinese, Traditional Chinese, Japanese, and Korean. Collation sequences allow you to properly order character fields in tables for each language.

The following table lists the Visual FoxPro collation sequence options and the corresponding language.

Options Language
JAPANESE Japanese
KOREAN Korean
PINYIN Simplified Chinese
STROKE Simplified and Traditional Chinese

For more information about specifying collation sequences, see Specifying Sort Orders earlier in this chapter.

Creating or Modifying Programs

You can prevent localization problems with code by observing the guidelines described in the following sections.

Testing for International Versions

If it's important for your application to be able to determine what language Visual FoxPro is running in, you can call VERSION( ). Knowing the language environment can help you determine what text to display, how to format data, and so on. For example, the following code determines what language environment Visual FoxPro is running in and then runs a language-specific form:

IF VERSION(3) = 34 THEN
   * Running in Spanish--display Spanish form
   DO FORM CST_SPN.SCX
ELSE
   * Display English form
   DO FORM CST_ENU.SCX
ENDIF

Note   Support for double-byte characters strings has been available in Visual FoxPro only since version 3.0b. If your application is relying on the availability of DBCS functions, you should also call the VERSION(1) function to test the Visual FoxPro version number.

Using Strings

Avoid including strings directly in code because they make localization difficult. For instance, don’t include dates and currencies as strings in code. If possible, write your code so that it retrieves strings from files or tables separate from the program.

Note   The performance of your program might suffer if you remove all strings from it. For example, performance might suffer if the program searches for strings while inside a loop.

One way to work with strings in an application that will be translated is to use string constants throughout the application. You can then define the text for these constants in a separate text file that is referenced from your programs using the #INCLUDE preprocessor directive. For example, instead of embedding the error message “file not found,” you can use the constant ERR_FILE_NOT_FOUND. The text for this constant could be in a file called ERR_TEXT.H. A program that uses this technique might look like this:

#INCLUDE ERR_TEXT.H

* processing here

IF ERR THEN
   MESSAGEBOX( ERR_FILE_NOT_FOUND )
ENDIF

When your application is localized, the translator can create a locale-specific version of the error text file and then recompile the application.

Working With Strings in DBCS Environments

Visual FoxPro includes functions for manipulating character expressions containing any combination of single-byte or double-byte characters. By using DBCS string functions, you can develop applications without having to write extra code that tests for double-byte characters when counting, locating, inserting, or removing characters in a string.

Most DBCS functions are equivalent to their single-byte counterparts except that they're named with a C suffix to distinguish them. You can use these functions with both single-byte and double-byte data; the DBCS functions return exactly the same value as their single-byte counterparts when single-byte data is passed to them. A few other functions help you work with strings specifically in double-byte environments.

DBCS string functions Description
AT_C( ) Returns the position of one string within another (case-sensitive), starting at the left.
ATCC( ) Returns the position of one string within another (case-insensitive).
CHRTRANC( ) Replaces characters in a string.
IMESTATUS( ) Toggles double-byte editing in the Browse window.
ISLEADBYTE( ) Tests whether a character is a DBCS character.
LEFTC( ) Returns leftmost characters from a string.
LENC( ) Returns the number of characters in a string.
LIKEC( ) Determines whether two strings match.
RATC( ) Returns the position of one string within another (case-sensitive), starting at the right.
RIGHTC( ) Returns rightmost characters from a string.
STRCONV( ) Converts characters between single-byte and double-byte representations.
STUFFC( ) Replaces characters in a string with another string.
SUBSTRC( ) Returns a substring.

When working with double-byte string functions, remember that the maximum-length limit for variables, names, and so on is effectively cut in half.  For more information about Visual FoxPro system capacities, see System Capacities.

Note   The Visual FoxPro DBCS functions are not supported in earlier versions of Visual FoxPro, and calling them might cause unpredictable results. If you use any DBCS functions in your application, use VERSION(1) to verify that the Visual FoxPro version is later than version 3.0.

Working with Date, Time, and Currency Formats

To help you format dates, times, and currency to match what your users are accustomed to, you can use a variety of formatting techniques. You can:

To set a format for date, times, and currency

  1. From the Tools menu, choose Options, and then click the Regional tab.

  2. To use the settings made with the Windows Control Panel, choose Use system settings.

    -or-

    Choose a language or format for dates and times and then choose options for formatting currency and numbers. If you choose the format Short or Long for the date format, you cannot specify any further options for the date format, and the settings are read from the Windows Control Panel.

  3. Choose OK to use the options for this session, or Set As Default to make the changes the default settings for this copy of Visual FoxPro.

You can also make these settings using the SET SYSFORMATS and SET DATE commands. As a rule, you would issue this command during the initialization of your application (for example, in the configuration file). The default for SET SYSFORMATS is OFF, so you must explicitly set it to ON when starting your application.

You can establish data validation in individual text boxes by setting the Format property of the text box. However, because text box formatting takes precedence over system-wide formatting, this can make it more difficult to localize your application to an environment that uses a different format for dates, currency, and so on.

Using Preprocessor Directives

You can create application variants for different locales by using preprocessor directives. These control compilation of code in the application and include the #INCLUDE, #DEFINE, #UNDEF, and #IF...#ENDIF constructs.

Using preprocessor directives can produce variants quickly; however, such directives have the following drawbacks:

Managing Files in an International Application

The Project Manager can help you organize an international application. In a project, you can integrate the parts of an application, such as forms, menus, programs, and reports. The project ensures that the parts are current when you build the application for its target market.

Unlike .dbf files, text files such as query and program files don't have code page marks. This means that you must keep track of the code pages used by text files so that you can use the files properly. With the Project Manager, you can track the code pages used by text files. For details, see Specifying the Code Page of a Text File earlier in this chapter.

Distributing Locale-Specific Run-Time Files

If you're distributing your application along with the run-time version of Visual FoxPro, you might need to include a locale-specific resource file. This file contains the dialog boxes and other user-interface elements that Visual FoxPro uses to interact with the user. There is a different run-time resource file for each language in which Visual FoxPro is available.

You would normally need to concern yourself about a locale-specific run-time resource only if all of the following are true:

For information about distributing run-time files with your application, see Chapter 25, Building an Application For Distribution, and Chapter 26, Creating Distribution Disks.

Run-time resource files are named using the format Vfpaaa.dll, where “aaa” is a three-letter code representing the language. For example, the code ENU stands for United States English, the code DEU stands for German, and the code FRA for French. The run-time resource files for these languages are therefore Vfpenu.dll, Vfpdeu.dll, and Vfpfra.dll, respectively.

You must always include at least one run-time resource file, even if you don't intend to use any of the user interface elements in Visual FoxPro as part of your application. By default, Visual FoxPro includes the resource file that's provided with your copy of the program. For example, if you're developing an application using the United States version of Visual FoxPro, Visual FoxPro automatically includes Vfpenu.dll if you include run-time files with your application. If you have no reason to use a locale-specific resource file, you can simply distribute the default resource file as part of your application.

When the application is installed, users can specify the run-time resource file to use by making an entry in the Windows system registry or by using a command-line switch.

To specify a run-time resource file

When the run-time application starts, Visual FoxPro searches for a resource file, first according to the L switch and then according to the Registry setting. If neither of these settings specifies a locale-specific resource file, Visual FoxPro uses the current system (Windows) locale to dynamically construct a DLL file name. Therefore, if the locale-specific resource file for your application matches the system locale on the user’s version of Windows, you don't need to explicitly specify the resource file name. However, it's always safest not to rely on the system default if you want to be sure that the proper file is loaded.