A Survey of VFP's International Features

Many Visual FoxPro commands have international nuances. Keep these things in mind as you develop your international applications.

Background

This section is a compendium of VFP's international features and dependencies. It is a long and detailed section, though fortunately many of the themes are recurring. Here is a short summary of the main themes found herein:

The language of operating system services will vary with the localized language of the OS.
  • Some services come from the operating system, so the language of display varies with the localization of the operating system. For example, if your German client is running a US version of Windows, then VFP's MESSAGEBOX() function will display English button captions (OK - Cancel) and there is nothing you can do about it (other than use INTL's MsgSvc() function, of course).
The language of native VFP services will vary with the localized language of VFP.
  • Some services come from Visual FoxPro, so their display language varies with the localized version of VFP. For example, dialogs like GETFILE() and LOCFILE() are VFP dialogs, and aside from parameters you can pass, these dialogs will appear in English on English versions of VFP.
The language of some things in VFP cannot be controlled.
  • Some VFP services aren't designed for multi-locale use, like the Relational Integrity (ri) builder. The ri builder is dependent on FoxPro functions that return character strings that vary with the localized version of FoxPro.
The language of third-party services cannot be predicted without experimentation.
  • Some services come from third-parties, and their localization usually cannot be predicted unless you experiment. Things like OLE custom controls, for example, may or may not be internationally enabled, and may require separate versions (if available) for different locales.

A Recurring Theme

Here are a few things to keep in mind. These apply to many of the topics that follow.

These "AS nCodePage" elements recur in many of the topics below, and they are listed here just once. Keep these factors in mind.
  • Wherever you see nCodePage in a command description, you can use GETCP()to display the Code Page dialog box, allowing you to specify a code page for the imported table or file.
  • In general, in cases where a nCodePage argument is permitted and a value of 0 is assigned, no code page translation will take place.
  • If the specified value for nCodePage isn't supported, VFP generates error 1914, with message "Code page number is invalid.".

AERROR( ArrayName )

Creates an array of information about the most recent VFP, OLE, or ODBC error.

VFP errors vary with the localization language of VFP.When a VFP error occurs, ArrayName[2] contains the text of the error message, which is the same as the value returned by MESSAGE().

Internationalization Gotcha: This error message varies according to the localized version of VFP.

OLE error messages vary with the localization language of Windows.When OLE errors numbered 1427 or 1429 occur, then ArrayName[2] contains the text of the VFP error message ("OLE Idispatch exception code"), and ArrayName[3] contains the text of the OLE error message.

Internationalization Gotcha: The VFP error message varies with the localization of VFP, and the OLE error message usually varies with the localization of Windows.

ODBC error messages vary with the localized language of VFP.Similarly, when an ODBC error numbered 1526 occurs, then ArrayName[2] contains the text of the VFP error message ("Connectivity error:"), and ArrayName[3] contains the text of the ODBC error message.

Internationalization Gotcha: Both the VFP and ODBC error messages vary with the localization of VFP.

Obviously, you'll want to avoid passing AERROR() messages to the user unless you are sure that their workstation has the correct localized versions of Windows and VFP.

AFIELDS( ArrayName [, nWorkArea | cTableAlias] )

AFIELDS() places structural information about the current table into an array.

Of note to international developers is the following:

Internationalization Gotcha: ArrayName[6] contains logical true if code page translation is not allowed. Think of this as a NOCPTRANS flag for the field.

Internationalization Gotcha: ArrayName[8] contains the field validation text, which will probably need to be localized.

Internationalization Tip: you can set the field validation text with DBSETPROP(cTableAlias,"Field","RuleText", cRuleText).

Internationalization Gotcha: ArrayName[11] contains the table validation text, which will probably need to be localized.

Internationalization Tip: you can control the table validation text with DBSETPROP(cTableAlias,"Table","RuleText", cRuleText).


ANSITOEM( cExpression )

ANSITOOEM() is for backward compatibility and for conversions with DOS. Use CPCONVERT() instead.ANSITOOEM() converts each character of a character expression to the corresponding character in the ms-dos (oem) character set. ANSITOOEM() is used to move data from VFP and FoxPro for Macintosh to FoxPro for ms-dos.

Internationalization Tip: this function is included for backward compatibility. Use CPCONVERT() instead.


APPEND FROM ... AS nCodePage

Specify the codepage of the new data when appending table data from other locales or platforms.APPEND FROM adds records to the end of the currently selected table from another file.

Internationalization Gotcha: the optional AS nCodePage argument specifies the code page of the source table or file. As VFP appends the data, it automatically converts the data to the code page of the current table.

If you omit AS nCodePage, two things can happen:

  1. If VFP cannot determine the code page of the source table or file, VFP copies the contents of the source table or file, and, as it copies the data, automatically converts the data to the current VFP code page. If SET CPDIALOG is ON, the table in the currently selected work area is marked with a code page. If you're appending from a table not marked with a code page, the Code Page dialog is displayed, allowing you to choose the code page of the table from which you're appending. The current VFP code page can be determined with CPCURRENT( ).
  2. If VFP is able to determine the code page of the file being appended, VFP copies the contents of the appended table or file, and, as it copies the data, automatically converts the data to the code page of the currently selected table.

APPEND MEMO ... AS nCodePage

APPEND MEMO copies the contents of a disk file to a memo field.

Specify the codepage of the new data when appendingmemo field data from other locales or platforms.


APPEND PROCEDURES ... AS nCodePage

APPEND PROCEDURES appends stored procedures in a text file to the stored procedures snippet of the current database.

Specify the codepage of the new data when appending DBC procedure code from other locales or platformsInternationalization Gotcha: AS nCodePage specifies the code page of the text file from which the stored procedures are appended. VFP copies the contents of the text file, and, as it does so, automatically converts the contents of the text file to the code page you specify

If you omit AS nCodePage, VFP copies the contents of the text file from which the stored procedures are appended, and, as it does so, automatically converts the contents of the text file to the current VFP code page. The current VFP code page can be determined with CPCURRENT( ).


AT_C( cSearchExpression, cExpressionSearched [, nOccurrence] )

AT_C() is similar to AT(), but works with single and double-byte characters.


ATCC( cSearchExp, cExpSearched [, nOccurrence] )

ATCC() is like ATC(), and works with single and double-byte characters.


ATCLINE( cSearchExpression, cExpressionSearched )

There is no ATCLINEC() function in VFP as one might expect.ATCLINE() returns the line number of the first occurrence of a character expression or memo field within another character expression or memo field, without regard for the case (upper or lower) of the characters in either expression.

Internationalization Tip: ATCLINE()works with both single-byte and double-byte character sets.


ATLINE( cSearchExpression, cExpressionSearched )

There is no ATLINEC() function in VFP as one might expect.ATLINE() returns the line number of the first occurrence of a character expression or memo within another character expression or memo.

Internationalization Tip: ATLINE()works with both single-byte and double-byte character sets.


BROWSE

BROWSE without NOMENU leads to an unlocalizable "Table" menu pad.Internationalization Gotcha: when using BROWSE without a NOMENU clause, VFP places a "Table" menu pad on the system menu containing a number of bars (with captions like "Properties", "Font", "Go to record", etc). The display language of this pad and its bars is a function of VFP's localization language. In international applications that use BROWSE, make sure you make it a BROWSE...NOMENU and, if required, invoke your own supporting menu.

CDOW( dExpression | tExpression )

CDOW() is dependent on the VFP localization.CDOW()returns the day-of-the-week from a given date or datetime expression.

Internationalization Gotcha: the day name returned varies with the localization of VFP.


CHR()

Using CHR(n) instead of the character itself is a good way to prevent code page translation.CHR() returns the character associated with the specified numeric ANSI code.

Internationalization Tip: you can use CHR() to prevent VFP's automatic code page translation. This is useful for program files which are not marked with code pages ID's. This may save you if you omit the AS nCodePage argument found in many VFP commands.


CHRTRANC( cSearched, cSearchFor, cReplacement )

CHRTRANC() is like CHRTRAN() and works with single and double-byte characters.CHRTRANC(), which is similar to CHRTRAN(), replaces each character in a character expression that matches a character in a second character expression with the corresponding character in a third character expression. As you might expect, CHRTRANC()adjusts for single-byte and double-byte characters automatically.

Internationalization Tip: to enable your application for DBCS, always use CHRTRANC()wherever you might use CHRTRAN().


CMONTH( dExpression | tExpression )

The text returned from CMONTH() varies with the localized version of VFP.CMONTH()returns the name of the month from a given date or datetime expression.

Internationalization Gotcha: the language of the returned string comes from VFP, so you cannot independently control the language of what's returned.


COMPILE ... AS nCodePage

Use COMPILE...AS or SET CPCOMPILE to compile source files originating from other locales or platformsCOMPILE compiles one or more source files.

Internationalization Gotcha: the optional AS nCodePage specifies the code page for which the program is compiled. The code page you specify with AS nCodePage overrides the global compilation code page specified with SET CPCOMPILE.


COPY MEMO ... AS nCodePage

Use AS <code page> to create a file-copy of a memo in another code pageCOPY MEMO copies the contents of the specified memo field in the current record to a file.

Internationalization Gotcha: AS nCodePage specifies the code page for the new file VFP copies the contents of the specified memo field, and, as it copies the data, automatically converts the data to the code page you specify for the text file.


COPY STRUCTURE EXTENDED

COPY STRUCTURE EXTENDED exports NOCPTRANS information, and data that may need to be localizedCOPY STRUCTURE EXTENDED creates a new table with fields containing the structure of the currently selected table.

Internationalization Gotcha : this new table will contain the following notable fields which have internationalization implications.
FIELD_NOCP L Code page translation not allowed (character and memo fields only)
FIELD_ERR M Field validation text
TABLE_ERR M Table validation text


COPY TO ... AS nCodePage

COPY TO creates a new file from the contents of the currently selected table.

Internationalization Gotcha: AS nCodePage specifies the code page for the new file. VFP copies the contents of the currently selected table, and, as it copies the data, automatically converts the data to the code page you specify for the new table or file. If possible, VFP marks the newly created table or file with the code page you specify. If you omit AS nCodePage, the newly created table or file is converted to the current VFP code page.


COPY PROCEDURES ... AS nCodePage

COPY PROCEDURES copies stored procedures in the current database to a text file.

Internationalization Gotcha: the AS nCodePage specifies the code page for the text file to which the stored procedures are copied. VFP copies the stored procedures, and, as it does so, automatically converts the stored procedures to the code page you specify.


CPCONVERT( nCurrentCodePage, nNewCodePage, cExpression )

CPCONVERT() is used to transform character or memo data.

CPCONVERT() converts character or memo fields or character expressions to another code page.

Internationalization Gotcha: don't forget to use CPCONVERT() when moving strings from one platform or locale to another.


CPCURRENT( [1 | 2] )

Use CPCURRENT() to reckon system code page information.

In VFP, the current operating system code page if the CODEPAGE configuration item isn't included in your configuration file. In previous versions of FoxPro, 0 is returned if the CODEPAGE configuration item isn't included in your configuration file.

  • The code page number specified in the CODEPAGE= configuration item in CONFIG.FPW.
  • The current operating system code page if you have included the following line in your configuration file: CODEPAGE = AUTO

In VFP, CPCURRENT(1) returns the Windows code page, regardless of your configuration CODEPAGE setting.

CPCURRENT(2) always returns the underlying operating system code page, regardless of your configuration CODEPAGE setting. For example, if you're running Windows, CPCURRENT(2) returns the MS-DOS code page.


CPDBF( [nWorkArea | cTableAlias] )

CPDBF() gives table code page information.CPDBF()returns the code page of an open table.

Internationalization Gotcha: don't assume that a table is marked with the correct code page, especially if it comes from another platform or another locale.


CPZERO( cFilename[, codepage_number]] )

Use CPZERO.PRG to change a table's code page id.Assuming you've installed tools, CPZERO.PRG can be found in your TOOLS\CPZERO directory. CPZERO.PRG removes the code page mark from any file that has a table file structure. After removing the mark, CPZERO applies another mark that you specify.

Internationalization Gotcha: if tables do not have code page marks when you open them, VFP prompts you for a code page. If you specify the wrong code page, however, the data in the files won't display properly. To correct the code page, use CPZERO.

CPZERO.PRG won't fix a corrupted table.It is worth noting that CPZERO won't fix a file with data corruption resulting from prior automatic code page translation.

CREATE CURSOR ... NOCPTRANS

CREATE CURSOR - SQL creates a temporary table. The NOCPTRANS argument, which applies when specifying field-level attributes, prevents translation to a different code page for character and memo fields.

Internationalization Gotcha: use the NOCPTRANS if conversion to another code page is anticipated. Note that this is more likely if a subset of the temporary table is saved to disk.


CREATE TABLE ... NOCPTRANS

CREATE TABLE - SQL creates a table.

Internationalization Gotcha: the NOCPTRANS field-level argument prevents translation to a different code page for its character and memo fields.


CTOD( cExpression )

If your date format doesn't match SET DATE, no error is generated, and a blank date value ( / / ) results.CTOD() converts a character expression to a date expression.

Internationalization Gotcha: remember that the format for the character expression must conform to the date format specified by SET DATE or by the "International" page of the Options dialog. So the command CTOD("9/24/96" ) works if SET DATE AMERICAN (month-day-year) but creates an empty date value ( / / ) if SET DATE BRITISH (day-month-year) or SET DATE JAPAN (year-month-day).

Arguments passed to CTOD() are unaffected by SET MARK TO.It is worth noting that CTOD() doesn't care about current date delimiters specified by SET MARK TO or by the "International" page of the Options dialog, so CTOD("9/24/96"), CTOD("9-24-96") and CTOD("9.24.96") all work equally well.

CTOT( cExpression )

If your date format doesn't match SET DATE, no error is generated, and a blank value ( / / : : AM ) results.CTOT() returns a DateTime value from a character expression.

Internationalization Gotcha: Remember that, like CTOD(), the format for the character expression must conform to the date format specified by SET DATE or by the "International" page of the Options dialog.

The proper format for cCharacterExpression is determined by the current settings of SET DATE, SET HOURS, and SET MARK. CCharacterExpression must evaluate to a recognizable DateTime value or Visual FoxPro generates an error.

Arguments passed to CTOT() are unaffected by SET MARK TO.It is worth noting that, in spite of what the help file says, CTOT() doesn't care about current date delimiters specified by SET MARK TO or by the format of SET HOURS ( or by what's specified in the "International" page of the Options dialog), so CTOT("9/24/96"), CTOT("9-24-96") and CTOT("9.24.96") all work equally well, as does CTOT("9-24-96 11:00 pm") and CTOT("9.24.96 23:00")

DATASESSIONS

Private datasessions are endowed with VFP default values that have nothing to do with your Regional Window's settings.

Therefore for each new data session you must SET the appropriate values.

Some of VFP's SET commands, including most of those with international implications, are scoped to the current datasession.

Internationalization Gotcha: a problem arises when you create new Datasessions: the new Datasessions have VFP defaults, and these don't necessarily conform to the current SET settings or the current Windows international settings.

This means that whenever a new private datasession is created, you must ensure that its SET settings are correct for the current locale.

Here is a complete list of SET commands that are scoped to the datasession, with the ones in bold face indicating those that are locale-sensitive.

DataSession-Scoped SET commands

SET ANSISET AUTOSAVE
SET BLOCKSIZESET CARRY
SET CENTURYSET COLLATE
SET CONFIRMSET CURRENCY
SET DATABASESET DATE
SET DECIMALSSET DELETED
SET DELIMITERSSET EXACT
SET EXCLUSIVESET FIELDS
SET FIXEDSET LOCK
SET MARK TOSET MEMOWIDTH
SET MULTILOCKSSET NEAR
SET NULLSET POINT
SET REPROCESSSET SAFETY
SET SEPARATORSET SYSFORMATS
SET TALKSET UNIQUE

These SET commands are scoped to the datasession.


DATE()

DATE() returns the current system date.

Internationalization Gotcha: the date is formatted according to SET DATE, SET MARK, and SET CENTURY.


DATETIME()

DATETIME()returns the current date and time as a DateTime value.

Internationalization Gotcha: the format of the DateTime value returned by DATETIME( ) depends on the current settings of SET DATE, SET MARK, SET CENTURY, SET HOURS, and SET SECONDS. The format is also dependent on the settings in the International option in the Windows Control Panel.


DBGETPROP( cName, cType, cProperty )

DBGETPROP() returns a property for the current database, or fields, named connections, tables, or views in the current database.

Internationalization Gotcha: here are localizable elements for table fields:

CPropertyTypeDescription
CaptionCThe field caption (read-write).
RuleTextCThe field rule error text (read-only).

 Here are localizable elements for views:

cPropertyTypeDescription
CaptionCThe field caption (read-write).
RuleTextCThe field rule error text (read-write).

 Here are localizable elements for table properties:

cPropertyTypeDescription
RuleTextCThe row rule error text (read-only).

 Here are localizable elements for views:

cPropertyTypeDescription
RuleTextCThe rule text expression displayed when an error occurs when data is edited in a Browse or Edit window (read-write).

DEFINE BAR

DEFINE BAR creates a menu item on a menu created with DEFINE POPUP.

Internationalization Gotcha: this command is notable because, in my experience, it is often involved in "hard coded" and difficult to localize situations. DEFINE BAR has three internationally sensitive clauses: PROMPT (what the bar displays), FONT (which could vary with locale) and MESSAGE (the status bar message).


DEFINE MENU

DEFINE MENU creates a menu bar.

Internationalization Gotcha: menus are often involved in "hard coded" and difficult to localize situations. DEFINE MENU has two internationally sensitive clauses: the FONT (which could vary with locale) and MESSAGE (the status bar message).


DEFINE PAD

DEFINE PAD creates a menu title (pad) on a menu bar.

Internationalization Gotcha: menus are often involved in "hard coded" and difficult to localize situations. DEFINE MENU has two internationally sensitive clauses: the FONT (which could vary with locale) and MESSAGE (the status bar message).


DEFINE POPUP

DEFINE POPUP creates a menu.

Internationalization Gotcha: menus are often involved in "hard coded" and difficult to localize situations. DEFINE POPUP has several internationally sensitive clauses: the FONT (which could vary with locale); MESSAGE (the status bar message); FOOTER (the text at the bottom of the popup); PROMPT FIELD (which may bring in unlocalized text from a table); and TITLE (on the top border of the menu).


DEFINE WINDOW

DEFINE WINDOW creates and specifies the characteristics of a window.

Internationalization Gotcha: hard-coded window definitions are often the source of localization difficulties. The DEFINE WINDOW may have the following internationally sensitive clauses: the TITLE of the window; its FONT (which might need to vary with locale); and the ICON file (which may not be appropriate for all locales).


DefOLELCID Property

The DefOLELCID property applies to Form and _SCREEN objects, and specifies the default OLE Locale ID for a Form or the main VFP window.

Internationalization Gotcha: this default value determines the Locale ID for OLE Bound controls and OLE Container controls when they are placed on the form or the main VFP window.

If the default OLE Locale ID value for a Form or the main Visual FoxPro window is changed to a new value, then OLE Bound controls and OLE Container controls placed thereon afterwards use the new value.

If DefOLELCID is set to zero for a form or the main Visual FoxPro window, SYS(3004) determines the default Locale ID for OLE Bound controls and OLE Container controls placed on the Form or the main VFP window.

Here is a listing of Locale Ids:

Locale IDLanguage

1029

Czech

1031

German

1033

English (Default)

1034

Spanish

1036

French

1040

Italian

1045

Polish

1046

Portuguese (Brazilian)

2070

Portuguese (Standard)

Note: the DefOLELCID property only affects the language of the user interface, which OLE controls display, and not the language of the OLE automation commands. The OLE automation command language is affected only by the Global LocaleID, set with SYS(3005).


DMY(dExpression | tExpression)

DMY() returns a character expression in day-month-year sequence, for example "26 June 1996".

Internationalization Gotcha: DMY() comes from VFP, and the language varies with VFP's localized language. DMY() respects the setting of SET CENTURY.


DTOC( dExpression | tExpression [, 1] )

DTOC() returns a Character-type Date from a Date or DateTime expression.

Internationalization Gotcha: the date format is determined by SET CENTURY and SET DATE and SET MARK.


DTOS( dExpression | tExpression )

DTOS() returns a character-string date in a yyyymmdd format from a specified Date or DateTime expression.

Internationalization Gotcha: this function is not affected by SET CENTURY.


DTOT( dDateExpression )

DTOT() returns a DateTime value from a Date expression.

Internationalization Gotcha: the format of the returned value depends on the current SET DATE and SET MARK settings.


EDIT

EDIT without NOMENU leads to an unlocalizable "Table" menu padInternationalization Gotcha: when using EDIT without a NOMENU clause, VFP places a "Table" menu pad on the system menu containing a number of bars (with captions like "Properties", "Font", "Go to record", etc). The display language of this pad and its bars is a function of VFP's localization language. In international applications that use BROWSE, make sure you make it a EDIT...NOMENU and, if required, invoke your own supporting menu.

ERROR

The ERROR command generates a VFP error.

Internationalization Gotcha: if you issue an ERROR call with an error number, like this: ERROR 101 , the message is in VFP's localized language. You can always issue ERROR 101, "My localized Error Message" to adorn errors with your own error message. In any event, the ERROR command is preempted by whatever action is specified by ON ERROR.


Error Messages

VFP error messages are in VFP's localized language.Internationalization Gotcha: error messages, which, in the absence of error handling adorn VFP's error dialog boxes and as available with MESSAGE() and AERROR(), are in the language of VFP's localization.

EXPORT TO ... AS nCodePage

EXPORT TO copies data from a VFP table to a file in a different format.

Internationalization Gotcha: AS nCodePage specifies the code page for the file EXPORT creates. VFP copies the contents of the currently selected table and, as it copies the data, automatically converts the data to the code page you specify for the new file. If possible, VFP marks the newly created file with the code page you specify.

If you omit AS nCodePage, no code page conversion occurs. If possible, VFP marks the newly created file with the code page of the table from which the data is copied. If nCodePage is 0, no code page conversion occurs and the new file is not marked with a code page.


FDATE( cFileName )

FDATE() is a low level file function that returns the last modification date for a file.

Internationalization Gotcha: the result is in a format determined by the current settings of SET DATE, SET MARK , and SET CENTURY.


FONTS

Internationalization Gotcha : depending on the localization, Fonts may be an issue. For example, the "Arial" font in the Cyrillic languages is called "Arial Cyr". Of course, in some Asian languages, there is no such thing as an Arial font.

Internationalization Tip : the best place to find locale-specific fonts is with the various localizations of Windows. If you are a member of the Microsoft Developer Network, then you may have several localized versions of Windows on CD-ROM. The advantage of using native fonts is your customers probably have them already installed, and it's one less thing to worry about.


Forms

Internationalization Gotcha: the form's Close box is localized in the language of VFP localization. This otherwise cannot be controlled.


GETCP( [nCodePage] [, cDialogCaption] [, cDialogTitle] )

GETCP() prompts for a code page by displaying the Code Page dialog box, and then returns the number of the code page chosen.

Internationalization Gotcha: other than the parameters you pass, you cannot control the language displayed in this dialog. It comes from within VFP and you will need a localized version of VFP for this dialog to display properly in an alternate language.


GETDIR( [cDirectory [, cDialogCaption]] )

GETDIR() displays the Select Directory dialog box from which a directory or folder can be chosen.

Internationalization Gotcha: you cannot control the language displayed in this dialog. It comes from within VFP and you will need a localized version of VFP for this dialog to display properly in an alternate language.

The line

?GETDIR("C:\", "cDialogCaption")

makes this rather unlocalizable dialog.

The GETDIR() dialog


GETEXPR TO ...

Internationalization Gotcha: the VFP expression builder comes from VFP and you cannot control its display language. To get a localized expression builder, you will need a localized version of VFP.

The GETEXPR TO dialog.


GETFILE( [cFileExtensions] [, cDialogCaption] [, cOpenButtonCaption][, nButtonType] [, cCreatorType] )

GETFILE() displays the Open dialog box and returns the name of the file you chose.

Internationalization Gotcha: other than the parameters you pass, you cannot control the language displayed in this dialog. It comes from within VFP and you will need a localized version of VFP for this dialog to display properly in an alternate language.

The line

?GETFILE([cFileExtensions] ,[cDialogCaption], [cOpenButtonCaption],1)

produces this:

The GETFILE() dialog.


GETFONT()

GETFONT() displays the Font dialog box and returns the name of the font you choose.

Internationalization Gotcha: like many other such dialogs, this comes from VFP and the language of the dialog varies with VFP's localization.

The GETFONT() dialog.


GETPICT( [cFileExt] [, cFileNameCaption] [, cOpenButtonCaption] )

GETPICT() displays the Open dialog box and returns the name of the picture file you chose.

Internationalization Gotcha: other than the parameters you pass, you cannot control the language displayed in this dialog. It comes from VFP and you will need a localized version of VFP for this dialog to display properly in an alternate language.


GETPRINTER()

GETPRINTER() displays the Windows Print Setup dialog box and returns the name of the printer you select.

Internationalization Gotcha: this dialog comes from the operating system and the display language varies with its localization.

The GETPRINTER() dialog.


HOUR( tExpression )

HOUR() returns the hour portion from a DateTime expression.

Internationalization Gotcha: HOUR( ) returns a numeric value based on a 24 hour format, and is not affected by the current setting of SET HOURS.


IDXCOLLATE( [cCDXFileName,] nIndexNumber [, nWorkArea | cTableAlias] )

IDXCOLLATE() returns the collation sequence for an index or index tag.

Internationalization Gotcha: IDXCOLLATE() can be used to return the collation sequence for each tag in multiple-entry compound index files, allowing you to completely delete an index file and rebuild it correctly, using a series of SET COLLATE and INDEX commands.

IDXCOLLATE() isn't required for the proper functioning of REINDEX, because the collation sequence information is present in existing indexes and index tags.


IMESTATUS( [nExpression] )

The Input Method Editor (IME) is a program that performs the conversion between keystrokes and ideographs or other characters, usually by user-guided dictionary lookup. IMESTATUS() turns the IME window on or off or returns the current IME status.

Return values for the IME status in the Japanese locale:

Return ValueIME Status
4Hiragana double-byte.
5Katakana double-byte.
6Katakana single-byte.
7Alphanumeric double-byte.
8Alphanumeric single-byte.

Return values for the IME status in the Korean locale:

Return ValueIME Status
4Hangeul mode.
5Junja mode (double-byte).
6Hanja conversion mode.

IMPORT FROM ... AS nCodePage

IMPORT FROM imports data from an external file format to create a new Visual FoxPro table.

Internationalization Gotcha: AS nCodePage specifies the code page of the imported file. Visual FoxPro copies the contents of the imported file and, as it copies the data, automatically converts the data to the current Visual FoxPro code page.

If you omit AS nCodePage and VFP cannot determine the code page of the imported file, VFP copies the contents of the imported file and, as it copies the data, automatically converts the data to the current Visual FoxPro code page. If you omit AS nCodePage and VFP can determine the code page of the imported file, VFP automatically converts the data in the imported file from the data's code page to the current VFP code page.


INDEX ON

Internationalization Gotcha: A problem occurs when the collating sequence for an index is set to something other than MACHINE. In that case, each character in the key uses two bytes. Since the maximum index key length is 240 characters, the longest key you can use is 120 characters for non-MACHINE collate sequences. The only way around this problem is to SET COLLATE TO MACHINE before creating that particular tag.


ISLEADBYTE( cExpression )

ISLEADBYTE() returns logical true if the first byte of the first character in a character expression is a lead byte. ISLEADBYTE() lets you determine if a character is a double-byte character. If the first byte of a character is a lead byte, the character is a double-byte character. Otherwise, the character is a single-byte character.


LEFTC( cExpression, nExpression )

LEFTC()from a character expression containing, which is similar to LEFT(), returns a specified number of characters any combination of single-byte and double-byte characters, starting with the leftmost character.


LENC()

LENC(), which is similar to LEN(), returns the number of characters in a character expression or memo field containing any combination of single-byte and double-byte characters.


LIKEC()

LIKEC(), which is similar to LIKE(), determines if a character expression matches another character expression. The character expressions can contain any combination of single-byte and double-byte characters.


LIST ...

Internationalization Gotcha: In the "old days" of FoxPro, the only way to get some sorts of information was to execute one of the LIST commands TO FILE and thereafter parse the resulting text. While I can't think of a reason to do this in VFP, some reason may occur. If it does, you should know that the LIST commands will produce output containing text that localized according to the language of VFP.


LOCFILE( cFileName [, cFileExt] [, cCaption] [, cCreatorType] )

LOCFILE() locates a file on disk and returns the file name with its path.

Internationalization Gotcha: other than the dialog caption, you have no control over the captions in this dialog. LOCFILE() comes from VFP and its display language varies with VFP's localization language.

For example, the line:

?LOCFILE("cFileName", "cFileExtensions", "cDialogCaption")

yields the following dialog under Windows NT 3.51. There are many interface strings on this dialog you can't localize. You are at the mercy of the user's VFP installation.

The LOCFILE() dialog.

MDY( dExpression | tExpression )

MDY() returns a character expression in month-day-year sequence, for example "June 26 1996".

Internationalization Gotcha: MDY() comes from VFP, and the language varies with VFP's localized language. MDY() respects the setting of SET CENTURY.


MESSAGE()

MESSAGE() returns the current error message as a character string.

Internationalization Gotcha: the error message is in the localized language of VFP. Note that AERROR(2)returns the same value as MESSAGE().


MESSAGEBOX( cMsgText [, nDialogType [, cTitleBarText]] )

MESSAGEBOX() displays a user-defined dialog box.

You can't directly localize the buttons in MESSAGEBOX(). For example, the following line yields the box below wherein the "Yes" and "No" button captions cannot be touched.

?MESSAGEBOX("cMsgText", 4, "cTitleBarText")

A MESSAGEBOX() dialog.


MODIFY COMMAND ... AS nCodePage

MODIFY COMMAND opens an editing window so you can modify or create a program file.

Internationalization Gotcha: AS nCodePage automatically converts accented characters in a program file created on another VFP platform. The numeric expression nCodePage specifies the code page of the VFP platform on which the program file was created. The file is saved in this code page unless you choose "Save As" from the File menu to save the file in a different code page.


MODIFY FILE ... AS nCodePage

MODIFY FILE opens an editing window so you can modify or create a text file.

Internationalization Gotcha: AS nCodePage automatically converts accented characters in a text file created on another VFP platform. The numeric expression nCodePage specifies the code page of the VFP platform on which the text file was created. The file is saved in this code page unless you choose "Save As" from the File menu to save the file in a different code page.


MODIFY QUERY ... AS nCodePage

Opens the Query Designer so you can modify or create a query. The Query Designer is a VFP dialog whose display language varies according to the localization of VFP.

Internationalization Gotcha: AS nCodePage specifies the code page of the query. Include AS nCodePage if the query was created with a code page other than the current VFP code page. When the query is opened, VFP automatically converts the query to the current VFP code page.

The query is saved in its original code page when it is closed.

If you omit the AS nCodePage clause or nCodePage is 0, the query is not converted to the current VFP code page.

In VFP, queries can be added to a project, and you can specify the query's code page from within the Project Container. The Project Container keeps track of the query's code page. However, if you use MODIFY QUERY to open a query outside of the Project Container, you should include AS nCodePage to specify the query's code page.


ODBC Errors

ODBC drivers generate ANSI SQL standard error codes, which are thereafter interpreted by VFP.

Internationalization Gotcha: the text of ODBC error messages come from VFP and will vary in language with the localized version of VFP.


OEMTOANSI( cExpression )

OEMTOANSI() converts each character of a character expression to the corresponding character in the ansi character set. Included for backward compatibility. OEMTOANSI() is used to move data from FoxPro for ms-dos to Visual FoxPro and FoxPro for Macintosh.


OLE Custom Controls

OLE Custom Controls come from a variety of sources and, for the most part, you'll get a mixed-bag of results when you use OLE controls in international settings. Be sure to inquire about supported locales before you commit to deploy a particular OLE control.


OLE ERRORS

Given that OLE controls come from many sources, it's not surprising to find that they don't all handle errors as you might hope. Some OLE controls return integer error codes for which you need to intercept and localize their messages. Other OLE controls display native error dialogs, and there is little you can do if a particular control doesn't support the current locale.


OLELCID Property

The OLELCID property of OLE Bound Controls and OLE Container Controls returns their numeric OLE Locale. This property is always read-only.

Internationalization Gotcha: the OLELCID value is determined by the value of the DefOLELCID property for the Form or the main VFP window when the OLE Bound control or OLE Container control is instanciated.

If the Form or the main Visual FoxPro window's DefOLELCID property is zero when the OLE Bound control or OLE Container control is placed on the Form or the main Visual FoxPro window, the control uses the current Visual FoxPro Locale ID as witnessed by SYS(3004). You can use the DefOLELCID property of Form objects to specify their Locale ID.

The OLELCID property only affects the language of the user interface, which OLE controls display, and not the language of the OLE automation commands. The OLE automation command language is affected only by the Global LocaleID, set with SYS(3005).

Here is a list of OLE locale id's.

nLocaleIDLanguage
1029Czech
1031German
1033English (Default)
1034Spanish
1036French
1040Italian
1045Polish
1046Portuguese (Brazilian)
2070Portuguese (Standard)

PEMSTATUS( oObject|cClass, cPEMName, nAttibute )

This function returns useful state information about a property, event or method. Internationalization Gotcha: using nAttribute=5, you can find out if this PEM is a "Property", "Event" or "Method". This language of this string varies with the localized version of VFP.


PRMBAR(), PRMPAD(), PROMPT()

Menu text varies with locale.PRMBAR(), PRMPAD() PROMPT()return text from menus.

Internationalization Gotcha: avoid using these functions in international applications because menu text will vary with the language of localization.


PRTINFO( nPrinterSetting [, cPrinterName] )

Printer settings vary from locale to locale.PRTINFO() returns the specified printer setting.

Internationalization Gotcha: your application should anticipate a wide variety of return values because most of them will vary from locale to locale.


PUTFILE( [cDialogCaption] [, cFileName] [, cFileExtensions] )

PUTFILE() invokes the Save As dialog box and returns the file name you specify.

Many PUTFILE() interface elements cannot be translated.Internationalization Gotcha: other than the dialog caption, you have no control over the captions in this dialog. PUTFILE() comes from VFP and it varies with its localization language.

For example, the following line:

?PUTFILE("cCustomText", "cFileName", "Ext")

creates this dialog. We basically can't localize this.

The PUTFILE() dialog.


RATC( cSearchExpression, cExpressionSearched [, nOccurrence] )

RATC(), which is similar to RAT(), returns the numeric position of the last occurrence of a character expression or memo field within another character expression or memo field. The character expressions or memo fields can contain any combination of single-byte and double-byte characters.


RATLINE( cSearchExpression, cExpressionSearched )

RATLINE() returns the line number of the last occurrence of a character expression within another character expression or memo field, counting from the last line.

Internationalization Gotcha: this function works in both single-byte and double-byte character sets.


RELATIONAL INTEGRITY BUILDER

Internationalization Gotcha: unfortunately, from a localization perspective, VFP's Relational Integrity (RI) builder leaves much to be desired. The code generated by the RI builder is unsuitable for international distribution. Here's a summary of the problems:

Update and Delete triggers are problematic because procedures RIDelete and RIUpdate contain a test on (UPPER(SYS(2011))="RECORD LOCKED". This test will always return .F. if your application runs on a different localization of VFP!

As if that weren't enough, calls to the RIError function, which may result if things don't go quite as planned, contain hard-coded error strings, like
DO rierror with -1,"Delete restrict rule violated." And
DO rierror with -1,"Insert restrict rule violated.".

Fortunately there is a workaround (sort-of): It relies on the following bit of trivia: Whenever there is more than one instance of a function in a file or snippet, only the latest instance is seen by VFP.

Therefore, in your stored procedures, you can duplicate and enable the RIError(), RIDelete(), and RIUpdate() functions, and paste them subsequent to the generated code.


RIGHTC()

RIGHTC(), which is similar to RIGHT(), returns the specified number of rightmost characters from a character string. The character expressions or memo fields can consist of any combination of single-byte and double-byte characters.


SET COLLATE TO cSequenceName

SET COLLATE specifies a collation sequence for character fields in subsequent indexing and sorting operations.

The following collation sequence options are available in VFP:

OptionsLanguage
DUTCHDutch
GENERALEnglish, French, German, Modern Spanish, Portuguese, and other Western European languages
GERMANGerman phone book order (DIN)
ICELANDIcelandic
MACHINEMachine (the default collation sequence for earlier FoxPro versions)
NORDANNorwegian, Danish
SPANISHTraditional Spanish
SWEFINSwedish, Finnish
UNIQWTUnique Weight

Note that when SET COLLATE TO is set to something other than "Machine", each index character takes two bytes, effectively reducing the maximum index key length from 240 to 120.


SET CPCOMPILE TO [nCodePage]

SET CPCOMPILE globally specifies the code page for compiled programs.

Internationalization Gotcha: SET CPCOMPILE TO without nCodePage to reset the compilation code page to the current code page. Use CPCURRENT() to determine the current code page. The AS clause in the COMPILE command to override the code page you specify with SET CPCOMPILE.


SET CPDIALOG ON|OFF

In your shipping app, make sure to SET CPDIALOG OFF.SET CPDIALOG specifies whether the Code Page dialog box is displayed when a table is opened.

Internationalization Gotcha: SET CPDIALOG is useful only at design-time. In your completed application, be sure that SET CPDIALOG is OFF.


SET CURRENCY

SET CURRENCY defines the currency symbol and specifies its position in the display of numeric, currency, float and double expressions.

Internationalization Gotcha: SET CURRENCY is scoped to the current data session.


SET DATASESSION

See DATASESSIONS


SET DATE

SET DATE specifies the format for the display of date and datetime expressions.

Internationalization Gotcha: date formats vary from locale to locale. VFP offers the following choices for SET DATE:

SettingFormat
AMERICANmm/dd/yy
ANSIyy.mm.dd
BRITISH/FRENCHdd/mm/yy
DMYdd/mm/yy
GERMANdd.mm.yy
ITALIANdd-mm-yy
JAPANyy/mm/dd
MDYmm/dd/yy
USAmm-dd-yy
YMDyy/mm/dd

SET DECIMALS TO [nDecimalPlaces]

SET DECIMALS specifies the number of decimal places displayed in numeric expressions.

Internationalization Gotcha: in many countries, the unit of currency transforms in the order of hundreds or thousands to the US dollar. In these countries, displaying decimal currency units is usually undesirable. In some situations you may be asked to round all currency amounts to the nearest ten, hundred, or even thousand units.


SET FDOW TO [nExpr]

Specifies the first day of the week.

The values nExpression can assume and the corresponding first day of the week.

NExprDay of the week

1

Sunday

2

Monday

3

Tuesday

4

Wednesday

5

Thursday

6

Friday

7

Saturday

If you omit nExpression, the first-day-of-the-week is reset to Sunday (1). The first-day-of-the-week can also be set with the Week Starts On list box in the International tab of the Options dialog.


SET FWEEK TO [nExpr]

SET FWEEK specifies the requirements for the first-week-of-the-year. nExpression can be:

nExprFirst week requirement

1

(Default) The first week contains January 1st.

2

The larger half (four days) of the first week is in the current year.

3

The first week has seven days.

If you omit nExpression, the first-week-of-the-year is reset to 1 (the first week contains January 1st). The first-week-of-the-year can also be set with the First Week of Year list box in the International tab of the Options dialog.


SET HELP TO [FileName]

SET HELP TO specifies a Help file.

Internationalization Tip: Multilingual applications need multilingual help. Use SET HELP TO to point to different help files as required. To specify a default startup Help file, use a HELP= configuration line in CONFIG.FPW.


SET MARK TO [cDelimiter]

Specifies a delimiter to use in the display of date expressions.

Internationalization Gotcha: the date delimiter separates the day, month and year elements of a date expression. The date delimiter will vary from locale to locale.


SET NOCPTRANS TO [Field1 [, Field2 ...]]

SET NOCPTRANS prevents translation to a different code page for selected fields in an open table.

Issue SET NOCPTRANS TO without a set of fields to return to the default translation (established by the CODEPAGE= configuration item) for all character and memo fields in a table. Use SET("NOCPTRANS") to return the fields specified in the last SET NOCPTRANS command you issued. Use the CHR( ) function to ensure that individual characters don't get translated.

Because Visual FoxPro can be configured to automatically translate character and memo fields into other code pages, the SET NOCPTRANS command is available to prevent the automatic translation of fields containing binary data. For example, a memo field may contain a Microsoft Word document. When you access the Word document, you would like the document in its original, untranslated form. Use SET NOCPTRANS to specify that the memo field not be translated.

You don't need to use SET NOCPTRANS to access binary data if the character or memo field containing the binary data has not been translated. You can ensure that character and memo fields are not translated by omitting the CODEPAGE configuration item from your Visual FoxPro configuration file.


SET POINT TO [cDecimalPointCharacter]

SET POINT TO determines the decimal point character used in the display of numeric and currency expressions.

SET POINT does never changes the decimal character in calculations.Internationalization Gotcha : throughout most of North America, the point character is ".", but in most countries of the world, the point character is ",". Note that you can set the displayed decimal point to a different character, you must use a period as the decimal point in calculations.

SET SEPARATOR TO [cSeparatorCharacter]

SET SEPARATOR specifies the character that separates each group of three digits to the left of the decimal point.

Internationalization Gotcha: throughout most of North America, the separator character is ",", but in most countries of the world, the separator character is ".".


SET SYSFORMATS ON | OFF

SET SYSFORMATS specifies if VFP system settings are updated with the current Windows system settings.

Internationalization Gotcha: by default the VFP system settings are not updated when the Windows system settings are changed.

The Windows system settings are specified in International option of the Windows Control Panel. When SET SYSFORMATS is ON, the following SET commands can be used to override the current system settings. However, changing the Windows system settings when SET SYSFORMATS is ON overrides these SET commands.

When VFP is started, the Visual FoxPro system settings are the default settings of these SET commands. To use the Windows system settings when VFP is started, place the following line in your VFP CONFIG.FPW configuration file:

SYSFORMATS = ON
SET CENTURY
SET CURRENCY
SET DATE
SET DECIMALS
SET HOURS
SET MARK TO
SET POINT
SET SEPARATOR

SET SYSFORMATS is scoped to the current data session.


STRCONV( cExpression, nSetting )

STRCONV() is used to go to transform strings among
n-byte systems.
STRCONV() converts a character expression to a different form. The following table lists the values of nSetting and the type of conversion performed:
nSettingConversion

1

Converts single-byte characters in cExpression to double-byte characters.

2

Converts double-byte characters in cExpression to single-byte characters.

3

Converts double-byte Hiragana characters in cExpression to double-byte Katakana characters.

4

Converts double-byte Katakana characters in cExpression to double-byte Hiragana characters.

5

Converts double-byte characters to UNICODE (wide characters).

6

Converts UNICODE (wide characters) to double-byte characters.

7

Converts cExpression to locale specific lowercase.

8

Converts cExpression to locale specific uppercase.

STUFFC( cExpr, nStartRepl, nCharsReplaced, cReplaced )

STUFFC() is like STUFF(), only it seamlessly handles double-byte characters.STUFFC(), which is similar to STUFF(), returns a character string created by replacing a specified number of characters in a character expression with another character expression. The character expressions can consist of any combination of single-byte and double-byte characters.

SYS( 13 )

Use PRINTSTATUS() instead of SYS(13).SYS(13) returns the status of the printer.

Internationalization Gotcha: in English versions of VFP, this return value is "READY" or "OFFLINE". If the printer is connected to a COM port, SYS(13) returns READY if the printer returns "Clear To Send Data" or "Data Set Ready". This return value comes from VFP and varies with its localization language. Fortunately, we have a language-independent workaround: use PRINTSTATUS(), which returns .T. or .F., instead of SYS(13).


SYS( 15, cTranslationExpression, cTranslated )

SYS(15) is ancient history.Translates a second character string from the first character string. Included for backward compatibility; use SET COLLATE instead.

Included with VFP is a memory variable file called EUROPEAN.MEM that contains sample translation characters. In FoxPro for MS-DOS and VFP, EUROPEAN.MEM is located in the directory in which you install VFP. In FoxPro for Macintosh, EUROPEAN.MEM is located in the Goodies:Misc folder.

Stored in EUROPEAN.MEM is a character memory variable called EUROPEAN, for use with SYS(15) in FoxPro for MS-DOS. Another character memory variable, EUROANSI, is provided for use with SYS(15) in VFP and FoxPro for Macintosh. These memory variables can be used with SYS(15) to translate accented characters to the corresponding characters without the accents.

As an example, the following command can be used in FoxPro for MS-DOS to index a table on a field containing accented characters while preserving normal alphabetical order:

INDEX ON SYS(15, european, field) TO european

This function is primarily intended for the convenience of European users who must use accented characters. Since there are different versions of most vowels, indexing on fields containing accented characters doesn't preserve the expected alphabetical order.


SYS( 20, cExpressionTransformed, nCharacters )

SYS(20) is ancient history too.SYS(20) transforms a character expression containing German text to a character string. Included for backward compatibility. Use SET COLLATE instead.

SYS( 1037 )

The Print Setup language is determined by the OSSYS(1037) invokes the Print Setup dialog.

Internationalization Gotcha: this service comes from the operating system, and will thus be in its localized language.


SYS( 2006 )

The graphics card and monitor information comes from VFPSYS(2006) returns the type of graphics card and monitor you are using, as in "VGA/COLOR".

Internationalization Gotcha: this result is generated by VFP and can only be localized by using a localized version of VFP.


SYS( 2011 )

The lock status reported by SYS(2011) varies with VFP localization.


SYS( 3004 )

SYS(3004) returns the Locale ID used by OLE automation and OLE controls.

Internationalization Gotcha: the Locale ID determines the language in which OLE automation and OLE controls exchange information.


SYS( 3005, nLocaleID )

SYS(3005) sets the Locale ID, used by OLE automation and OLE controls. Here are the locales in VFP:

nLocaleIDLanguage
1029Czech
1031German
1033English (Default)
1034Spanish
1036French
1040Italian
1045Polish
1046Portuguese (Brazilian)
2070Portuguese (Standard)

SYS( 3006, nLanguageID )

SYS(3006) sets the Language ID and the Locale ID.


SUBSTRC( cExpression, nStartPosition [, nCharactersReturned] )

SUBSTRC() is like SUBSTR(), but handles double-byte characters as well.


ToolTips

ToolTips come from Windows, and there is no known way to change their font. ToolTips come from Windows, and there is no way that I know to control the Font from within Visual FoxPro. This means that apps running in Eastern Europe and oriental languages will display garbage in the tooltip window unless you are running on a localized version of windows.

TTOC( tExpression [, 1] )

TTOC() returns a Character value from a DateTime expression that respects SET HOURS, SET CENTURY and SET DATE so parsing this Character expression is not a good idea.


VERSION(), VERSION( 3 )

The return value from VERSION() is localized by VFP. VERSION(3) is useful to determine the current VFP localization language.VERSION() returns a character string containing the VFP version number you are using. Internationalization Gotcha: This string is in the localization language of VFP.

VERSION(3) returns the localized VFP language, according to the following table:

VERSION(3)Language

00

English

33

French

34

Spanish

39

Italian

42

Czech

48

Polish

49

German

55

Portuguese

WAIT WINDOW cExpression

The WAIT WINDOW command has two things about it that merit mentioning here:

Internationalization Gotcha: possibly no other command is more prone to hard-coded literals and hard-wired syntax sentence construction than WAIT WINDOW . I've seen the job of ferreting-out WAIT WINDOW take more time than required to localize the entire rest of the application.

Internationalization Gotcha: there is no way to change the WAIT WINDOW display font.


WEEK( dExpr | tExpr [, nFirstWeek] [, nFirstDayOfWeek] )

You can make WEEK() respect the International settings by passing 0 for parameters 2 and 3WEEK()returns a number representing the week-of-the-year from a Date or DateTime expression. Passing 0 for nFirstWeek or nFirstDayOfWeek causes WEEK() to fetch values from whatever is selected in the International tab in the Options dialog box.