INTL 可以轻松地在 Visual FoxPro (VFP) 中创建多语言软件。它使您能够创建多语言 Visual FoxPro 应用程序,同时最大限度地减少创建多版本软件的麻烦。
本文档用于描述以下内容:
strings.dbf
MsgSvc()
工作原理的详细信息INTL
类cINTLAbstract
cINTLCurrency
cINTLData
cINTLFont
cINTLMemento
类cINTLPicture
cINTLRightToLeft
cINTLStrategy
cINTLString
config.fpw
菜单语句MsgSvc()
对话框返回值MsgSvc()
示例strings.dbf
strings.dbf
strings.dbf
strings.dbf
strings.dbf
INTLVisitor
首先,将 INTL 文件放入一个干净的新目录中。
然后,
部署文件:手动放置与您的项目相关的文件,如如何正确放置 INTL 文件中所述。
修改config.fpw
文件:对于菜单,将两行添加到config.fpw
文件中,如如何本地化菜单中所述。
为 Form 类定义添加种子:现在,可能永远,使用调用 INTL 对象的Form::Init()
语句在表单中调用 INTL。请参阅如何获得自动表单本地化。
如果需要本地化,请实例化 INTL 对象:现在,当需要本地化时,创建并配置 INTL 对象,如如何实例化 INTL 对象中所述。
根据需要找到INTL的文件对于VFP来说很重要。这里是放置 INTL 文件的位置,以便它们可用于您的开发环境:
按如下方式部署您的文件:
genmenux.prg
intl.prg
SET PATH
。strings.dbf strings.fpt strings.cdx
SET PATH
。msgsvc.dbf msgsvc.fpt msgsvc.cdx
SET PATH
。 创建一个名为_SCREEN.oINTL
的成员来保存 INTL 实例。
为了使用 INTL,您的应用程序必须实例化一个 INTL 对象。有很多方法可以做到这一点,最好的是将其添加到_SCREEN
,如下所示:
*-- Anywhere, anytime:
*-- Instantiate INTL in _SCREEN
SET PROCEDURE TO INTL ADDITIVE
SCREEN.AddObject( "oINTL", "INTL" )
通过将对象引用传递给 INTL 对象的Localize()
方法来本地化表单。
表单(以及任何其他容器)通过将其引用传递给oINTL.Localize()
方法来本地化。
*-- Configure oINTL to another language
_SCREEN.oINTL.SetLanguage( "French" )
*-- Instantiate a form. If the form calls INTL in its Init()
*-- method, then the form appears in French....
DO FORM MyForm Name MyForm
....或者您可以即时本地化表单。
_SCREEN.oINTL.Localize( MyForm )
在Form.Init()
层次结构中调用oINTL
。
要使您的表单自动本地化,请在表单类层次结构中调用oINTL.Localize()
方法。为此,请将以下代码放入表单类定义的Init()
方法中。 |
*-- Don't forget to call the ParentClass!
DODEFAULT()
IF TYPE("_SCREEN.oINTL" ) == "O"
_SCREEN.oINTL.Localize( This )
ENDIF
GENMENUX 驱动程序用于本地化菜单。要激活 GENMENUX 及其 INTL.PRG 驱动程序,请将以下行放入config.fpw
中:
将这些行添加到config.fpw
。
*-- Configuring for INTL menus.
_GENMENU = GENMENUX.PRG
_MNXDRV2 = INTL.PRG
*-- End of configuration for INTL menus.
其中一些更改需要重新启动 VFP。要避免此时重新启动 FoxPro,请在命令窗口中发出以下命令:
_GENMENU = HOME()+”GENMENUX.PRG”
这就是您在开发环境中需要进行的所有更改以本地化菜单。此后,照常生成菜单。
GENMENUX 非常酷。一探究竟。
注意:GENMENUX 不会取代 VFP 的本机菜单生成器。由于 GENMENUX 调用 GENMENU.PRG,因此您的代码照常由 VFP 生成。 INTL 工具包使用 GENMENUX 作为预处理器。 GENMENUX 是一个内容丰富的程序。请参阅 GENMENUX 了解有关其功能的更多信息。
strings.dbf
的结构决定了您支持的语言。
使用SetLanguage()
方法更改 INTL 的语言。
INTL 附带一个名为strings.dbf
的表,其中包含各种字段,其中之一是cOriginal
,并且它可能包含不同语言的其他字段,例如cFrench
、 cGerman
、 cSpanish
等。
您支持的语言由strings.dbf
表的结构决定。要添加新语言,请更改strings.dbf
的结构。
要更改当前的本地化语言,请使用SetLanguage()
方法。假设我们想要一个法语表格。首先设置语言,然后本地化表单:
_SCREEN.oINTL.SetLanguage( "French" )
_SCREEN.oINTL.Localize( _SCREEN.ActiveForm )
没有什么比即时切换显示语言更好的演示了。
要动态交换语言(这在演示中总是成功的)(即使不需要,也可以这样做 - 非常简单),请在应用程序中创建一种机制,使用INTL.SetLanguage()
配置 INTL 对象,如下所示接下来。
_SCREEN.oINTL.SetLanguage("German" ) && Configure INTL for German
FOR i = 1 TO ALEN(_SCREEN.Forms ) && Localize active forms
_SCREEN.oINTL.Localize( _SCREEN.Forms[i] )
ENDFOR
DO MAIN.MPR && Refresh the menu too!
要更改应用程序基于区域设置的个性,我建议您将INTL
子类化以根据需要工作。根据您自己的需要对INTL
进行子类化是用最少的代码和最少的麻烦来满足语言环境需求的好方法。
下面是一个 INTL 子类的示例,它适用于多种语言环境。我们对INTL
类进行子类化,以立即更改所有特定于语言环境的设置。
请注意 RightToLeft 策略(类cINTLRightToLeft
),这对于中东书写系统很有用。
DEFINE CLASS MyINTL AS INTL
FUNCTION SetLocale( tcLocale )
IF EMPTY( tcLocale )
tcLocale = this.GetLocale()
ENDIF
IF INTL::SetLocale( @tcLocale )
DO CASE
CASE PROPER(tcLocale )= "Usa"
SET CURRENCY TO "$"
SET CURRENCY LEFT
SET POINT TO "."
SET SEPARATOR TO ","
SET DATE TO American
SET MARK TO "/"
this.SetRightToLeft( .F. )
this.SetConversion( "Usa", 1.33 )
this.SetLanguage( "USEnglish" )
CASE PROPER(tcLocale )= "France"
SET CURRENCY TO " F"
SET CURRENCY RIGHT
SET POINT TO ","
SET SEPARATOR TO "."
SET DATE TO DMY
SET MARK TO "/"
this.SetRightToLeft( .F. )
this.SetConversion( "France", 0.28 )
this.SetLanguage( "French" )
CASE PROPER(tcLocale )= "Germany"
SET CURRENCY TO " DM"
SET CURRENCY RIGHT
SET POINT TO ","
SET SEPARATOR TO "."
SET DATE TO DMY
SET MARK TO "/"
this.SetRightToLeft( .F. )
this.SetConversion( "Germany", 0.28 )
this.SetLanguage( "German" )
CASE PROPER(tcLocale )= "Israel"
SET CURRENCY TO "ILS"
SET CURRENCY LEFT
SET POINT TO "."
SET SEPARATOR TO ","
SET DATE TO British
SET MARK TO "/"
this.SetConversion( "Israel", 0.41 )
this.SetRightToLeft( .T. )
this.SetLanguage( "Hebrew" )
ENDCASE
ENDIF
ENDDEFINE
INTL 旨在快速实施。
以下是您今天早上需要执行的操作来本地化您的应用程序,以便下午进行多语言演示。如果您正确使用了 VFP 的设计工具,这将是一个快速的工作。如果没有,这将需要更长的时间来设计。
基本步骤是:
安装 INTL 并为表单基类的Init()
方法添加种子。按照标题为“安装 INTL”部分中的步骤进行操作。确保您检查了所有步骤。尤其重要的是标题为“如何实例化 INTL 对象”、“如何实现自动表单本地化”以及“如何本地化菜单”的步骤。
修改strings.dbf
的结构并为您需要的每种语言添加一个字段。
strings.dbf
表,放到你的项目根目录下。ZAP
您放置在项目根目录中的strings.dbf
表。strings.dbf
的MODIFY STRUCTURE
并添加一个名为cSwahili
新列,长度为 120。请注意, cSwahili
中的“c”是必需的。让您的应用程序创建一个 INTL 对象。在应用程序的早期,实例化一个 INTL 对象,如如何实例化 INTL 对象中所述。现在可以使用其SetLanguage()
方法以不同的语言显示。
进行“构建全部”。打开您的项目,选择“构建”,然后构建应用程序或 Exe,确保选择“重新编译所有文件”。去吃午饭吧。
要自动加载strings.dbf
,请运行您的应用程序或使用 INTLTool 实用程序。有两种方法可以使用项目的接口字符串填充strings.dbf
表。第一种方法是运行您的程序。当对象被实例化时,INTL 会将字符串(如Caption
、 Tooltiptext
等)附加到字符串表中。更好的方法是运行 INTLTool 更新程序。请参阅 INTL 工具。
在strings.dbf
表中输入翻译。在cSwahili
列中,输入斯瓦希里语翻译,并根据需要提供热键和快捷键。注意:您可以通过执行以下操作获得用于测试和内部演示的“快速而肮脏”的翻译:
`REPLACE ALL cSwahili with "**"+TRIM(cOriginal)+"**" FOR cOriginal <> "(("`
我建议创建一个名为_SCREEN.oINTL
的主要 INTL 对象。
多个单独的 INTL 对象可以共存。每个 INTL 对象都是其他 INTL 对象(称为钩子或策略)的混合体。您的主要 INTL 对象是您环境中的主 INTL 对象,我假设它称为_SCREEN.oINTL
。
使用SetConfig( n )
方法配置您的主 INTL 对象。
您可以使用_SCREEN.oINTL.SetConfig( n )
方法配置 INTL,其中n
是按位整数值,具有以下解释:
价值 | 配置含义 |
---|---|
1 (默认)2 4 8 16 32 | 加载字符串策略 加载字体策略 加载数据策略 加载图片策略 加载货币策略 加载 RightToLeft 策略 |
示例:创建一个本地化字符串和字体的 INTL 对象
*-- create an INTL object
_SCREEN.AddObject("oINTL", "INTL" )
*-- Load the strings and font strategies.
_SCREEN.oINTL.SetConfig( 1 + 2 )
主 INTL 对象的操作语言和区域设置通过SetLanguage()
和SetLocale()
方法进行配置。
策略是按位配置的。
按如下方式配置各个策略:获取策略的引用,然后配置它。以下是每个可配置策略的配置含义。
战略 | 价值 | 本土化 |
---|---|---|
数据 | 1 (默认)2 4 8 16 | BoundColumn ControlSource RowSource RecordSource InputMask |
字体 | 1 (默认)2 (默认) | Font 和FontSize DynamicFont 和DynamicFontSize |
图片 | 1 (默认)2 4 (默认)8 | Picture DownPicture Icon DragIcon |
从右到左 | 1 (默认) | 所有对象在各自的容器内反转 |
弦乐 | 1 (默认)2 (默认)4 (默认) | Caption ToolTipText StatusBarText |
要获取已加载策略的句柄,请使用oINTL.GetStrategy()
方法。此后,使用句柄的oINTL.SetConfig()
方法来配置策略。
示例:创建一个本地化字符串但不本地化工具提示的 INTL 对象
使用oINTL.GetStrategy()
方法获取对象引用,然后使用其oINTL.SetConfig()
方法对其进行配置。
*-- create an INTL object
_SCREEN.AddObject("oINTL", "INTL" )
*-- Load the strings and font strategies.
_SCREEN.oINTL.SetConfig( 3 )
*-- Configure Strings to NOT localize ToolTips
LOCAL loTempHandle
loTempHandle = _SCREEN.oINTL.GetStrategy( "String" )
*-- For the string strategy, the configuration
*-- for Caption and StatusBarText is 5
loTempHandle.SetConfig( 1 + 4 )
示例:创建一个仅本地化字符串和 InputMasks 的 INTL 对象。
*-- create an INTL object
_SCREEN.AddObject( "oINTL", "INTL" )
*-- Load the strings and data strategies.
_SCREEN.oINTL.SetConfig( 5 )
*-- now modify the data strategy from its default.
LOCAL oTemp
oTemp = _SCREEN.oINTL.GetStrategy( "Data" )
*-- Input masks only.
oTemp.SetConfig( 16 )
当我们想到翻译软件时,通常首先想到的是界面字符串。
INTL默认只加载字符串策略。
下表列出了 INTL 的配置位。这些配置位决定加载哪种策略。默认情况下只加载String策略,也就是说字符串默认是由INTL自动本地化的。
班级 | 配置位 | 本土化 |
---|---|---|
国际 | 1 (默认)4 2 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
CINTL字符串 | 1 (默认)2 (默认)3 (默认) | Caption ToolTipText StatusBarText |
激活字符串策略如下:
*-- cINTLString is loaded by default.
*-- So there’s usually no need to do this
_SCREEN.oINTL.SetStrategy( "String", "cINTLString" )
另一种更神秘的加载字符串策略的方法是:
-- Set configuration bit 2^0 "ON"
_SCREEN.oINTL.SetConfig( BITSET( oINTL.GetConfig(), 0 ))
所以有两种方法可以做到这一点。
可以通过在strings.dbf
中提供翻译来本地化字符串。
c原件 | 法语 |
---|---|
Yes | Oui |
No | Non |
使用SetConfig()
方法配置字符串策略。
与所有策略一样,INTL 字符串策略是按位配置的。您可以按如下方式控制字符串策略对象:
示例:禁用ToolTipText
属性的字体处理:
*-- Get a handle on the string strategy:
oFont = _SCREEN.oINTL.GetStrategy( "String" )
*-- We want Caption( 1 ) and StatusbarText( 4 ) only
oFont.SetConfig( 5 )
字体可以是特定于区域设置的。
Arial、Times New Roman、MS Sans Serif 等字体可能不适合某些语言。这很重要;当我们更改语言环境时,我们可能需要一种方法来更改字体。
下表列出了INTL对象加载字体策略的配置位,以及配置字体策略的配置整数。
班级 | 配置位 | 本土化 |
---|---|---|
国际 | 1 (默认)2 4 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
CINTL字体 | 1 (默认)2 (默认) | Font 和FontSize DynamicFont 和DynamicFontSize |
激活字体策略如下:
*-- cINTLFont is the Font strategy class.
_SCREEN.oINTL.SetStrategy( "Font", "cINTLFont" )
另一种更神秘的加载字体策略的方法是:
*-- Set configuration bit 2^1 "ON"
_SCREEN.oINTL.SetConfig(BITSET(oINTL.GetConfig(),1 ))
所以有两种方法可以做到这一点。
可以通过在strings.dbf
中提供翻译来本地化字体。字体规范以标识符“ ((Font ))
”为前缀,例如:
c原件 | c俄语 |
---|---|
((Font))Courier New,10 | ((Font))Courier New Cyr,10 |
((Font))Arial,16 | ((Font))Arial Cyr,16 |
使用其SetConfig()
方法配置字体策略。
与所有策略一样,INTL 字体策略是按位配置的。您可以按如下方式控制字体策略对象:
示例:禁用DynamicFont
和DynamicFontSize
的字体处理,这将稍微提高字体策略性能:
*-- Set Font localization on
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 1 )) && Set 2^1 "ON"
*-- Get a handle on the font strategy:
oFont = _SCREEN.oINTL.GetStrategy("Font" )
*-- We want Font and FontSize and to disable DynamicFont
*-- and DynamicFontSize
oFont.SetConfig( 1 )
数据可以是特定于区域设置的。
有时需要本地化的是数据本身。 INTL 允许您为不同的区域设置呈现不同的字段。
数据策略的工作原理与其他策略类似。
下表列出了INTL对象加载图片策略的配置位,以及配置图片策略的配置整数。
班级 | 配置位 | 本土化 |
---|---|---|
国际 | 1 (默认)2 4 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
CINTL数据 | 1 (默认)2 4 8 16 | BoundColumn ControlSource RowSource RecordSource InpuMask |
激活数据策略如下:
*-- cINTLData is the Graphics strategy class.
_SCREEN.oINTL.SetStrategy( "Data", "cINTLData" )
另一种更神秘的加载数据策略的方法是:
*-- Set configuration bit 2^2 "ON"
_SCREEN.oINTL.SetConfig(BITSET(oINTL.GetConfig(),2 ))
所以有两种方法可以做到这一点。
可以通过在strings.dbf
中提供翻译来本地化数据元素。数据规范以标识符“ ((Data))
”为前缀,例如:
c原件 | 捷克语 |
---|---|
((Data))cEngDesc | ((Data))cRussianDesc |
使用其SetConfig()
方法配置数据策略。
与所有策略一样,INTL 数据策略是按位配置的。您可以按如下方式控制图片策略对象:
示例:本地化 ControlSource 属性。
*-- Set Data localization on
*-- Set 2^2 "ON"
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 2 ))
*-- Get a handle on the data strategy:
oData = _SCREEN.oINTL.GetStrategy("Data" )
*-- We want ControlSource (2)
*-- property localized.
oPicture.SetConfig( 2 )
图像可以是特定于区域设置的。我们每天使用的一些图标和图像可能不适合其他区域。 INTL 提供了一种在我们更改区域设置时更改显示图像的方法。
图片策略的工作原理与其他策略类似。下表列出了INTL对象加载图片策略的配置位,以及配置图片策略的配置整数。
班级 | 配置位 | 本土化 |
---|---|---|
国际 | 1 (默认)2 4 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
cINTLPicture | 1 (默认)2 4 (默认)8 | Picture DownPicture Icon DragIcon |
激活图片策略如下:
*-- cINTLPicture is the Graphics strategy class.
_SCREEN.oINTL.SetStrategy( "Picture", "cINTLPicture" )
另一种更神秘的加载图片策略的方法是:
*-- Set configuration bit 2^3 "ON"
_SCREEN.oINTL.SetConfig(BITSET(oINTL.GetConfig(),3 ))
所以有两种方法可以做到这一点。
可以通过在strings.dbf
中提供翻译来本地化图片。图片规范以标识符“ ((Picture))
”为前缀,例如:
coriginal | crussian |
---|---|
((Picture))Doctor.BMP | ((Picture))Doktor.BMP |
((Picture))Friend.BMP | ((Picture))Comrade.BMP |
使用其SetConfig()
方法配置图片策略。
与所有策略一样,INTL 图片策略是按位配置的。您可以按如下方式控制图片策略对象:
示例:本地化图片、DownPicture 和图标属性。
*-- Set Picture localization on
*-- Set 2^3 "ON"
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 3 ))
*-- Get a handle on the font strategy:
oPicture = _SCREEN.oINTL.GetStrategy("Picture" )
*-- We want Picture (1), DownPicture( 2 ) and Icon (4)
*-- properties localized. 1+2+4 = 7
oPicture.SetConfig( 7 )
INTL 提供简单但适应性强的多货币功能。
INTL 使您能够为您的应用程序赋予简单的多货币功能。这种架构非常灵活,通过子类化cINTLCurrency
类,您可以实现几乎任何您需要的多货币方案。
其核心是,INTL 货币策略仅适用于格式属性为“$”的字段。
回想一下,INTL 策略是根据下表按位配置的。
类(默认) | 价值 | 本土化 |
---|---|---|
国际 (1) | 1 (默认)2 4 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
激活货币策略如下:
使用oINTL.SetConfig()
或oINTL.SetStrategy()
加载货币策略。
OINTL = _SCREEN.oINTL
oINTL.SetStratrgy( "Currency", "cINTLCurrency" )
另一种(更神秘的)方法是使用 INTL 的SetConfig()
方法使 INTL 调用给定类的 Font 策略,如下所示:
OINTL = _SCREEN.oINTL
*-- Set bit 2^4 "ON"
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 4 ))
所以有两种方法可以做到这一点。
货币策略与其他策略不同。 INTL工具包货币策略在三个重要方面与其他策略略有不同:
货币是特定于区域设置的,而不是特定于语言的。
cINTLCurrency
类不使用cINTLString
类服务,并且
当数据处于转换状态时, cINTLCurrency
类使许多输入字段变为只读。
所有货币的默认汇率是1.00
。
使用 INTL 附带的cINTLCurrency
类,您可以将货币转换系数分配给不同的货币。默认情况下,货币策略使用的转换系数为1.00
。
如果您需要与时间相关的货币换算,您可以对cINTLCurrency
进行子类化来执行您需要它执行的任何操作,例如查找。
让我们为以下货币配置 INTL:加元、欧元和美元。假设我们的数据以加元为单位。
oINTL.SetConversion()
设置原始语言环境和其他语言环境之间的汇率。
使用SetLocale()
更改货币区域设置。然后像往常一样进行本地化。
oINTL = _SCREEN.oINTL
*-- Load the currency strategy
*-- Set 2^4 "ON"
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 4 ))
*-- Define a few locales and currencies
oINTL.SetConversion( "Canada", 1 )
oINTL.SetConversion( "Euro", 1.55 )
oINTL.SetConversion( "USA", 1.33 )
*-- Lets assume we want to see it in US dollars
oINTL.SetLocale( "USA" )
*-- Localize the current form
oINTL.Localize(_SCREEN.ActiveForm )
INTL 将自动使您的表单对象从右向左显示。
INTL 使您能够从右到左显示对象,这是中东书写系统所要求的。为此,INTL 沿着容器的垂直中心线反转容器内对象的位置。 INTL 还修改复选框和选项组的对齐属性。
INTL 不会更改标题文本的方向。要更改标题文本的方向,您必须使用 Windows 的中东本地化版本。
结果是形式颠倒了;如果它们是从左到右阅读,那么现在它们是从右到左阅读,反之亦然。
回想一下,INTL 策略是根据下表按位配置的:
类(默认) | 价值 | 本土化 |
---|---|---|
国际 (1) | 1 (默认)2 4 8 16 32 | cINTLString 策略已加载cINTLFont 策略已加载cINTLData 策略已加载cINTLPicture 策略加载cINTLCurrency 策略已加载已加载 cINTLRightToLeft 策略 |
激活货币策略如下:
使用oINTL.SetConfig()
或oINTL.SetStrategy()
加载货币策略。
OINTL = _SCREEN.oINTL
oINTL.SetStratrgy( "RightToLeft", "cINTLRightToLeft" )
An alternate (and more cryptic ) way is to use INTL's `SetConfig()` method make INTL invoke the Font strategy of a given class, as follows:
OINTL = _SCREEN.oINTL<b
*-- Set bit 2^5 "ON"
oINTL.SetConfig( BITSET( oINTL.GetConfig(), 5 ))
所以有两种方法可以做到这一点。
RightToLeft 策略是唯一真正重新排列容器中对象的策略。
INTL 工具包从右到左策略在四个重要方面与其他策略略有不同:
cINTLRightToLeft
不使用类cINTLString
服务。cINTLRightToLeft
沿容器的垂直轴反转容器内对象的位置。左侧的内容最终出现在右侧,反之亦然。此外,复选框和选项组的对齐属性是相反的,页面框架中的页面顺序和网格中的列顺序也是如此。cINTLRightToLeft
策略从左到右进行书写。让我们为从右到左的语言配置 INTL。最简洁的方法是使用INTL::SetLanguage()
方法的子类。或者,您也可以使用SetLocale()
方法来完成此操作。无论哪种方式,实现都是相同的。
在此示例中,我们使用SetLanguage()
来配置 RightToLeft 转换。
注意:为了清楚起见,我们省略了字体策略的配置,而我们可能需要这样做。请参阅如何本地化字体。
DEFINE CLASS MidEastINTL AS INTL
FUNCTION SetLanguage( tcLanguage )
LOCAL llRetVal
LlRetVal = INTL::SetLanguage( tcLanguage )
*-- The right-to-left strategy is configured
*-- with the fifth INTL configuration bit.
IF tcLanguage = "Hebrew" OR ;
TcLanguage = "Arabic"
this.SetConfig( BITSET( this.GetConfig(), 5 ))
ELSE
this.SetConfig( BITCLEAR( this.GetConfig(), 5 ))
ENDIF
RETURN llRetVal
ENDDEFINE
需要不同的行为吗?考虑一个子类。您可能会遇到需要采取不同做法的情况。不要更改 INTL 源代码(这会在合并未来版本时造成困难),而是考虑对现有策略进行子类化以实现所需的行为。
在下图中,我们创建了两个子类,一个来自cINTLString
类,一个来自cINTLCurrency
类。类层次结构现在如下所示:
添加到 INTL 类层次结构中的新类。
要使用您的子类而不是 INTL 附带的子类,请调用 setstrategy() 方法,如下所示:
*-- Assuming _SCREEN.oINTL is already Instantiated
_SCREEN.oINTL.SetStrategy("String", "cMyString" )
_SCREEN.oINTL.SetStrategy("Currency", "cMyCurrency" )
您可以创建自己的策略并使用 INTL 自动调用它们。让您的新策略成为 cINTLStrategy 类的子类(这样您将拥有 INTL 期望的属性和方法),然后运行它!
与子类化现有策略的情况一样,使用SetStrategy()
方法将策略加载到 INTL 中。
三种方式:
您可以通过将字符串“INTL Ignore”放入对象的注释属性中来使 INTL 忽略对象或容器对象。该字符串不区分大小写。
如果可以的话,给你的对象的类一个 INTL 属性,并为其分配逻辑 .F。
如果可以的话,为对象的类指定一个 INTL 属性,并为其指定一个小于 0 的数值。
如果您对特定对象有特殊需求,请为对象的类提供一个 INTL 属性,并为类定义中的属性或该对象的实例分配一个数值。该数值是您分配给 INTL 的SetConfig()
方法以为此特定对象配置 INTL 的值。
如果您希望在后续策略实例化中替换您自己的策略,请使用SetStrategyClass()
方法将新策略类分配给现有策略别名。
*-- Permanently install cMyStringStrategy for the string strategy.
_SCREEN.oINTL.SetStrategyClass( "String", "cMyStringStrategy" )
strings.dbf
INTL 附带了迭代器和访问者类,旨在重复 VFP 结构,并将所有字符串接口元素加载到strings.dbf
中。
请参阅基于 .PJX 更新strings.dbf
。
VFP 报告结构不会生成或编译——它们“按原样”绑定到您的应用程序中。因此,必须在创建 .APP 或 .EXE 之前转换报告。
本地化报告实际上只需要做一次。转换过程将您的报表标签转换为包含对 INTL 的I()
函数的调用的报表表达式。例如,报表标签"Name:"
变为表达式I("Name:")
。
请参阅基于 .PJX 转换报告。
如果您打算真正喜欢即时交换语言,那么了解以下内容将会很有帮助:
INTL 本地化表单后,它会向表单添加一个名为 oINTL 的对象,该对象属于cINTLMemento
类,配置为 INTL 配置。这个备忘录是一个轻量级对象,它允许多个 INTL 对象和平共存,因为它们可以知道某个特定的表单此时以日语显示。
当 INTL 对象找到包含名为 oINTL 的成员的表单时,它将采用由其GETCONFIG()
值确定的成员配置。
如果您需要替代行为 - 例如,如果您需要第二个 INTL 对象完全覆盖第一个的备忘录 - 那么首先将表单本地化回原始状态(这会删除 Form.oINTL 成员),然后使用第二个 INTL 对象。
MsgSvc()
工作原理的详细信息第一次调用时, MsgSvc()
创建一个名为_SCREEN.oMsgSvc
的对象,此后它将管理消息传递。如果存在名为_SCREEN.oINTL
的对象,则_SCREEN.MsgSvc
对象将遵循其语言设置并使用其服务。
对于运行时本地化,您需要分发以下文件:
文件 | 笔记 |
---|---|
i.prg | 为了获得最佳性能,请将此函数放置在您的第一个SET PROCEDURE 文件中。 |
intl.prg | 为了获得最佳性能, SET PROCEDURE TO INTL Additive 。 |
msgsvc.dbf | |
msgsvc.fpt | |
msgsvc.cdx | 如果您使用MsgSvc() 您将需要分发这些文件。 |
msgsvc.prg | 消息服务库。 |
nohot.prg | 为了获得最佳性能,请将此函数放置在您的第一个SET PROCEDURE 文件中。 |
strings.dbf | |
strings.fpt | |
strings.cdx | 您还需要分发这些。 |
对于 STRINGS 和 MSGSVC 表和文件,如果您将它们包含在 APP 或 EXE 中,那么它们当然是只读的。
以下是 INTL 使用的文件的描述。要计算这些文件相对于您的项目的最佳放置位置,请参阅如何正确放置 INTL 文件。
文件 | 描述 |
---|---|
addendum.txt | 文档或帮助文件中可能包含也可能不包含的最新突发新闻。 |
genmenux.zip | Andrew Ross MacNeill 提供的最新可用 GENMENUX 程序的存档。 |
i.prg | 一个独立函数,用作_SCREEN.oINTL.I() 方法的快捷方式。 |
intl.prg | INTL 工具包中的类和实用程序的核心代码。 |
intltool.prg | 开发人员的实用程序,用于对项目文件和其他 VFP 结构进行批处理操作。不要将此文件与您的应用程序一起分发。 |
msgsvc.dbf msgsvc.fpt msgsvc.cdx | 包含对话框、等待窗口、温度计条和文本块消息的表格和支持文件。 |
msgsvc.prg | 消息服务库。 |
nohot.prg | nohot() 从 FoxPro 提示表达式中去除热键字符。它是一个单行函数,您应该将其作为过程剪切并粘贴到应用程序调用堆栈中的某个位置。 |
strings.dbf strings.fpt strings.cdx | 包含翻译短语的表格和支持文件。 |
INTL 类层次结构基于类cINTLAbstract
。 cINTLAbstract
用于定义整个层次结构的接口。只要有可能,就避免向子类添加恶意属性、事件和方法。
下图显示了INTL类层次结构的OMT图。
INTL 类层次结构。
在正常情况下,您可能使用的唯一对象是INTL
类。
cINTLMemento
类可以用作令牌。
cINTLMemento
是一个配置令牌,INTL 对象可以使用它来存储特定本地化的详细信息。 cINTLMemento
包括对受保护属性的访问方法。
INTL 是本地化过程的公共接口和模板方法。
cINTLStrategy 是各种本地化引擎的父类。
cINTLString
、 cINTLCurrency
、 cINTLFont
、 cINTLMeasures
、 cINTLPicture
和cINTLData
是特定战略实施的类。
INTL
类INTL 类提供本地化应用程序中的对象和其他元素的服务。
INTL
公开属性INTL::cCurrencyStrategy
INTL 允许您本地化货币。
指定货币策略类名称的字符串。
默认 | "cINTLCurrency" |
评论 | 您可以对cINTLCurrency 进行子类化以满足您的特定需求。然后,您可以使用SetStrategy("Currency",cYourCurrencyClass) 方法将此货币策略属性设置为默认值以外的值。 |
参见 | cINTLMemento::GetStrategy() |
INTL::cDataStrategy
INTL 允许不同的区域设置使用不同的数据源。指定数据策略类名称的字符串。
默认 | "cINTLData" |
评论 | 您可以对cINTLData 进行子类化以满足您的特定需求。您可以使用SetStrategy("Data", cYourDataClass) 方法将此数据策略属性设置为默认值以外的值。 |
参见 | cINTLMemento::GetStrategy() |
INTL::cFontStrategy
INTL 允许替换正确的字体。
指定字体策略类名称的字符串。
默认 | "cINTLFont" |
评论 | 您可以对cINTLFont 进行子类化以满足您的特定需求。您可以使用SetStrategy("Font", cYourFontClass) 将字体策略属性设置为默认值以外的值。 |
参见 | cINTLMemento::GetStrategy() |
INTL::cPictureStrategy
INTL 可以本地化图片、图标和图像。
指定图片策略类名称的字符串。
默认 | "cINTLPicture" |
评论 | 您可以对cINTLPicture 进行子类化以满足您的特定需求。您可以使用 ::SetStrategy("Picture", cYourPictureClass ) 将图片策略属性设置为默认值以外的值。 |
参见 | cINTLMemento::GetStrategy() |
INTL::cStringStrategy
INTL 本地化单词和短语。
指定字符串策略类名称的字符串。字符串策略类负责本地化应用程序中的字符串和短语,并且还充当其他策略类的函数存储库。
默认 | "cINTLSting" |
评论 | 您可以对cINTLString 进行子类化以满足您的特定需求。您可以使用SetStrategy("String", cYourStringClass) 来设置该属性。 |
参见 | cINTLMemento::GetStrategy() |
cINTLString 策略类是迄今为止最有用的,它为其他策略提供服务。 | 注意:许多策略使用由活动字符串策略类提供的基于字符串的服务。为了减少与特定cStringStrategy 类的内聚性,许多通常属于cStringStrategy 类的字符串方法可在父策略类cINTLStrategy 类中找到。因此,所有策略都具有一些固有的字符串本地化能力。 |
INTL
公开方法INTL::Execute()
本地化数字、字符串、对象或对象数组。对于对象和对象数组,执行函数依次将每个对象传递给所有主动定位策略。
句法 | oINTL.Execute( @PassedObject ) |
返回 | 没有什么 |
论点 | PassedObject :可以是数字、字符串或对象类型。它也可以是对象引用的数组。 |
参见 | INTL::ObjArray() |
例子
DIMENSION laScratchArray[1]
SET PROC TO INTL
oINTL = CREATEOBJECT("INTL" )
oXX = CREATEOBJECT("Form" )
*-- Load the array with object references
oINTL.ObjArray( oXX, @laScratchArray )
oINTL.Execute( @laScratchArray )
INTL::GetAlias()
|策略可能需要资源文件,这些资源文件通过别名引用。
返回与默认本地化策略关联的资源表的别名。通常,默认策略对象属于cINTLString
类。
句法 | oINTL.GetAlias() |
返回 | 字符串策略表别名的字符值。 |
论点 | 没有任何。 |
评论 | GetAlias() 方法是一个可钩子方法,这意味着如果类INTL 的对象具有附加的钩子对象,则GetAlias() 遵循钩子对象的方法。由于默认情况下, INTL 类的对象与cINTLStringStrategy 类的对象挂钩,因此调用oINTL.GetAlias() 相当于调用oINTL.oStringStrategy.getAlias() 。 |
例子
_SCREEN.AddObject( "oINTL", "INTL" )
*-- The following two are equivalent
_SCREEN.oINTL.oStringStrategy.GetAlias()
_SCREEN.oINTL.GetAlias() |
INTL::GetTable()
返回关联的资源表的名称