需要将与E X E名字相同的本地化的资源D L L和应用程序捆绑在一起即可。
当应用程序启动时, 它检查本地系统的国别。若发现任何与正使用的E X E、D L L或BPL 文件名字相
同的资源D L L,它检查这些D L L的扩展名。如果资源模块的扩展名匹配系统国别的语言和国家,应用程
序将使用资源模块中的资源来代替可执行文件、D L L或包中的资源。如果没有语言和国家都匹配的资源
模块,应用程序将试着定位只匹配语言的资源模块。如果没有资源模块匹配语言,应用程序将使用与可
执行文件、D L L或包一起编译的资源。
如果想让应用程序使用与匹配本地系统国别的资源模块不同的另一个资源模块,可以在Wi n d o w s注
册表中改变国别的设置。在HKEY_CURRENT_USER\Software\Borland\Locales 关键字下,将应用程序的
路径和文件名作为字符串值输入,并将数据值设为资源DLL 的扩展名。应用程序开始时将在检查系统国
别前按这个扩展名搜索资源D L L。设置这个注册表值允许在不改变系统国别时测试应用程序的本地化版
本。
例如, 下列过程可被用于在安装程序时设置注册表键值以指定当装载C++Builder 应用程序时使用的
国别:
第11章创建国际化的应用程序计计161
下载
在应用程序中,使用全局函数FindResourceHInstance 获得当前资源模块的句柄。例如:
只需提供适当的资源D L L,就可发行能自动适应所运行的系统的国别的应用程序。
11.2.6 动态切换资源D L L
除了在应用程序开始时定位资源D L L,也可在运行时动态切换资源D L L。要把这个功能加到应用程
序中,需要在工程中包括ReInit 单元(ReInit 位于D e m o s目录中Richedit 示例中)。要切换语言,应调用
L o a d R e s o u r c e M o d u l e,传入新语言LCID ,然后调用ReinitializeForms 。
例如,下列代码将语言切换到法语:
这种技巧的优点是应用程序和其所有的窗体使用的都是当前实例。不需要更新注册表设置并重启应
用程序或重新获得应用程序要求的资源, 如登录到数据库服务器。
当切换资源D L L时,新的D L L指定的属性将覆盖当前窗体中运行的实例的属性。
注意在运行时对窗体属性的任何改变都将失效。装载新的D L L时,缺省值不会重置。编写代
码时应避免假设窗体对象会重新初始化到初始状态, 这会由于本地化而产生差异。
11.3 本地化应用程序
一旦应用程序被国际化,就能为想要发行它的不同的外国市场创建本地化版本。
本地化资源
理想情况下,资源被分离到包含DFM 文件和一个R E S文件的资源D L L。可在I D E中打开窗体,并转换
相关的属性。
注意在一个资源DLL 工程中,不能增加或删除组件。可以更改属性,但这可能引起运行时错
误,需要小心并仅修改需转换的那些属性。为避免错误, 可将对象观察器设置为仅显示可本地
化的属性;要这样做, 可在对象观察器中右击鼠标,并使用Vi e w菜单以过滤不需要的属性。
可以打开R C文件并转换相关字符串。从工程管理器中打开R C文件,并使用S t r i n g Table 编辑器。
162计计第一部分使用C++Builder编程
第11章创建国际化的应用程序计计159
下载
ParentBiDiMode 是布尔型属性。当其为t r u e时(缺省),控件的B i D i M o d e属性取决于其父代使用的
B i D i M o d e。若控件是TForm 对象,则使用设置的B i D i M o d e。如果所有控件的ParentBiDiMode 属性为
t r u e,当改变A p p l i c a t i o n的BiDiMode 属性时,工程中所有的窗体和控件都更新相应设置。
8. FlipChildren 方法
F l i p C h i l d r e n方法允许翻转容器控件的子控件的位置。容器控件是能容纳其他控件的控件, 例如
T F o r m、T P a n e l及TGroupBox 。FlipChildren 只有一个布尔型参数A l l L e v e l s。当其为f a l s e时,只有直接的
子控件翻转。当为t r u e时,容器控件所有级别的子控件都被翻转。
C++Builder 通过改变控件的L e f t属性和其排列翻转控件。若控件的左边距其父代控件的左边界为5个
像素,在它被翻转后将是右边距父代控件的右边界为5个像素。若控件为左对齐,调用FlipChildren 将使
控件变为右对齐。
在设计时通过选择Edit|Flip Children并选择A l l或S e l e c t e d翻转子控件,选择A l l或S e l e c t e d取决于是想
要翻转所有的子控件还是只翻转选择的子控件。也可通过在窗体上选择控件,单击鼠标右键,并从上下
文菜单中选择Flip Children。
注意选择一个编辑控件并选择Flip Children|Selected命令不会发生任何事。因为编辑控件不是
容器控件。
9. 其他方法
还有一些对开发适用于双向用户的应用程序有用的方法,见表11 - 2。
表11-2 其他一些方法
方法描述
O k To C h a n g e F i e l d A l i g n m e n t 用于数据库控件。检查控件的排列是否能被改变
D B U s e R i g h t To L e f t A l i g n m e n t 检查数据库控件排列的包装函数
C h a n g e B i D i M o d e A l i g n m e n t 改变传递给它的排列参数。不检查设定的BiDiMode 属性,它只
改变左对齐转换为右对齐并且反之亦然,保持居中排列的控件不变
I s R i g h t To L e f t 当任何从右到左的选项被选择,返回t r u e。若返回f a l s e,控件是从
左到右的模式
U s e R i g h t To L e f t R e a d i n g 当从右到左阅读方式时返回t r u e
U s e R i g h t To L e f t A l i g n m e n t 当控件从右到左排列时返回t r u e。它可通过定制覆盖
U s e R i g h t To L e f t S c r o l l B a r 当控件使用左边的滚动条时返回t r u e
D r a w Te x t B i D i M o d e F l a g s 由控件的B i D i M o d e而返回正确的写文本的标志
D r a w Te x t B i D i M o d e F l a g s R e a d i n g O n l y 由控件的B i D i M o d e而返回正确的写文本的标志。将标志限制为读
顺序
A d d B i D i M o d e E x S t y l e 把适当的ExStyle 标志加入被创建的控件
10. 国别特定的特征
可以为应用程序加入针对特定国别的额外的特征。特别对于亚洲的语言环境,也许会想要应用程序
控制输入方法编辑器(I M E),I M E用于将用户的击键转换为字符串。
V C L组件提供对I M E编程的支持。直接处理文本输入的大多数窗口控件允许通过ImeName 属性指定
当控件具有输入焦点时应该被使用的I M E。同时提供ImeMode 属性指定I M E应该如何转换键盘输入。
T Wi n C o n t r o l还提供了一些保护的方法以便用于控制自定义类的I M E。另外, 全局的S c r e e n变量提供了用户
系统中可用I M E的信息。
全局的S c r e e n变量还提供关于用户系统上已安装的键盘映射的信息。可以使用上述方法来获得应用
程序所运行环境的国别特定信息。
160计计第一部分使用C++Builder编程
下载
11.2.2 设计用户界面
当为国外市场创建应用程序时,设计用户界面以使其能够适应转换时的变化是很重要的。
1. 文本
用户界面中出现的所有文本都必须被翻译。英
语文本一般比其译文短。设计好用户界面的显示文
本的单元,以便为变长的字符串留出空间。创建对
话框、菜单、状态栏及其他显示文本的用户界面单
元,以便能更容易显示更长的字符串。避免缩写,
在使用表意文字字符的语言中不存在缩写。
在翻译时短的字符串会比长字符串增长的更
多。表11 - 3提供一个粗略的估计,以便可以对给定
的英文字符串计划其长度会增大多少:
2. 图形图像
使用不用翻译的图像应该是最理想的。显然, 这意味着图形图像应该不包括文本,因为文本总是要求
翻译。如果必须在图像中包含文本,在图像上使用一个透明背景的标签对象比将文本作为图像的一部分
更好。
在创建图形图像时还有其他的考虑。应试着避免适用由特别的文化而特定的图像。例如, 不同国家的
邮箱看起来很不一样。若应用程序打算在有不同信仰的宗教国家中使用,那么宗教标志也是不适当的。
甚至颜色在不同文化中也会由不同的涵义。
3. 格式和排序顺序
应用程序中使用的日期、时间、数字及货币格式应该按目标国别本地化。如果仅使用Windows 格式,
就不需要翻译格式, 因为这些格式是从用户的Windows 注册表中获得的。然而, 如果指定了任何一种自定
义的格式字符串,应确保将它们声明为资源常数以便能够本地化。
字符串的排序顺序在每个国家中也不相同。许多欧洲的语言因国别而包括不同的排序区分标记。另
外, 在有些国家, 2个字符的组合排序时被当作一个单字符。例如, 西班牙文中的c h组合字符,在排序时
像一个单一的字符一样被排在c 和d 之间。有时单个字符像2个分开的字符一样排序, 例如德文的e s z e t t。
4. 键盘映射
在指定键盘组合键的快捷方式时应该小心。不是美国键盘上的所有可用字符都可以在国际的键盘上
得到。如果可能, 使用数字键和功能键指定快捷方式, 这些是几乎所有键盘上都有的。
11.2.3 分离资源
本地化一个应用程序最明显的任务是翻译用户界面中出现的字符串。为了创建无论在何处都可以无
须修改代码而被翻译的应用程序, 用户界面的字符串应该被分离为一个单独的模块。C++Builder 自动创建
包含菜单、对话框及位图资源的.DFM 文件。
除了这些明显的用户界面单元,还需要分离显示给用户的任何字符串, 如错误消息。字符串资源不包
括在.DFM 文件中,可以将它们分离到一个.RC 文件。
11.2.4 创建资源D L L
分离资源简化了翻译进程。进一步的资源分离是创建资源D L L。资源D L L包含所有的仅供程序使用
的资源。资源D L L允许你通过简单地交换资源D L L而创建支持多种翻译的程序。使用资源D L L向导为程
序创建资源D L L。资源D L L向导要求一个打开的, 已保存的,已编译的工程。它将创建包含使用过的R C文
件中的字符串列表及工程中的r e s o u r c e s t r i n g字符串的R C文件,并且仅为一个包含相关窗体和创建的R E S
表11-3 估计字符串长度
英文字符串长度(字符数) 预期增加
1 ~ 5 1 0 0 %
6 ~ 1 2 8 0 %
1 3 ~ 2 0 6 0 %
2 1 ~ 3 0 4 0 %
3 1 ~ 5 0 2 0 %
大于5 0 1 0 %
文件的资源D L L生成一个工程。R E S文件由新的R C文件编译而来。
应该为想要支持的每个翻译创建资源D L L。每个资源D L L都应该按目标国别来确定文件扩展名。头
两个字符指出目标语言,第3个字符指出国家。若使用资源D L L向导,这些可被自动处理。否则,需使用
下列代码为目标翻译获得国别代码:
11.2.5 使用资源D L L
可执行文件、D L L和包使得应用程序包含了所有必要的资源。要把这些资源替代为本地化的版本, 只
创建国际化的应用程序
本章讨论如何编写计划发布到国际市场的应用程序。通过预先计划,能减少大量时间和代码开销,
而使应用程序能如同在国内市场一样在国外市场工作。
11.1 国际化和本地化
要创建能发布到国外市场的应用程序, 需要施行两个主要的步骤:
• 国际化。
• 本地化。
若你的C++Builder 的版本包括综合的翻译环境( Integrated Translation Environment, ITE),就可使
用ITE 管理本地化。参见ITE 的联机帮助(I T E . h l p)可获得更多的信息。
11.1.1 国际化
国际化是使程序能够在多个国别工作的进程。国别是指用户的环境, 包括目标国家的文化习惯和语言。
Windows 支持一个国别的集合,它们通过语言和国家两个信息说明。
11.1.2 本地化
本地化是翻译应用程序以使其可在特定国别工作的进程。除了翻译用户外,本地化还包括功能的定
制。例如, 金融方面的应用程序应根据不同国家不同的税法而修改。
11.2 国际化应用程序
创建国际化应用程序并不困难。需要完成下列步骤:
1) 必须使代码能够处理国际字符集的字符串。
2) 需要设计用户界面以便能够适应本地化的改变。
3) 应把所有需要本地化的资源独立出来。
11.2.1 应用程序代码
必须保证应用程序的代码能处理各个目标国别的字符串。
1. 字符集
美国版的Wi n d o w s使用ANSI Latin-1 ( 1252 ) 字符集。然而, 其他版本的Windows 使用不同字符
集。例如,日本版的Wi n d o w s使用Shift-Jis 字符集, 它使用1或2字节字符编码来代表日文字符。
2. OEM 和ANSI 字符集
有时有必要在Windows 字符集( ANSI )与由用户的机器编码页确定的字符集(称为O E M字符集)
之间变换。
3. 双字节字符集
亚洲使用的表意文字字符集不能使用语言字符和一个字节(8 b i t)的c h a r类型之间简单的1 : 1映射。
这些语言有太多无法使用1 字节c h a r类型表示的字符。所以,字符以1和2 字节混合编码来表示。
每个双字节字符编码的第一个字节都来自特定的字符集的保留的范围中。第二字节有时会和单独的1
第11章创建国际化的应用程序计计157
下载
字节的字符编码一样,或者会落在为双字节字符的第一字节保留的范围中。这样, 要区别一个字符串中的
一个特定的字节是代表单个的字符或一个双字节字符的一部分,唯一的方法是读字符串, 从头开始分析,
当遇见保留范围中的字节时,把它作为双字节字符的一部分。
当为亚洲国别编写代码时,必须确定使用可分析字符串为1或双字节字符的函数来处理所有的字符串
操作。参见联机帮助中的“国际化A P I”可获得一张可处理多字节字符的RT L函数列表。
记住字符串的字节长度不一定对应于字符串的字符数。截断字符串小心不要把一个双字节字符切成
两半。不要把字符作为一个参数传递到函数或过程,因为字符的大小事先并不能知道。应总是传递字符或
字符串的指针。
4. 宽字符
处理表意文字的字符集的另一种方法是把所有的字符转换为宽字符,如Unicode 编码方式。宽字符
用两个字节替代一个字节,以便字符集能表示更多不同的字符。使用宽字符编码方式有不少优点,如可以
使用MBCS 系统不能处理的对字符串的许多通常假设。在字符串的字符数和字符串的字节数之间有直接
的关系。不需要担心把字符切成一半或错将一个字符的一半当成另一个字符的开始。
使用宽字符的最大的不利条件是Windows 95仅支持很少的宽字符A P I函数调用。所以,V C L组件使
用单字节或M B C S字符串表示所有的字符串值。若每次设置字符串属性或读它的值时要在宽字符系统和
M B C S系统之间转换,这会需要数量惊人的额外代码开销,并会使应用程序变慢。然而, 处理一些特殊的
字符串算法时会需要利用在字符和宽字符之间1:1 映射的优势,而将字符转换为宽字符。
参见联机帮助种的“国际化A P I”获得可用于处理U n i c o d e字符的RTL 函数列表。
5. 在应用程序中包括双向功能
有些语言不像西方语言通常按从左到右顺序阅读,而是文字从右读到左,数字从左读到右。这些语
言因为这种分别而被称为是双向的( B i D i)。最普通的双向语言是阿拉伯语和希伯来语, 其他的中东语言
也是双向的。
TA p p l i c a t i o n有两个属性:B i D i K e y b o a r d和N o n B i D i K e y b o a r d,它们允许指定键盘布局。另外, VCL
通过BiDiMode 和ParentBiDiMode 属性支持双向的本地化。
表11 - 1列出了有这些属性的V C L对象:
表11-1 支持B i D i的V C L对象
组件面板页V C L对象组件面板页V C L对象
S t a n d a r d T B u t t o n T D r a w G r i d
T C h e c k B o x T M a s k E d i t
T C o m b o B o x T S c r o l l B o x
T E d i t T S p e e d B u t t o n
T G r o u p B o x T S t a t i c L a b e l
T L a b e l T S t r i n g G r i d
T L i s t B o x Wi n 3 2 T D a t e Ti m e P i c k e r
T M a i n M e n u T H e a d e r C o n t r o l
T M e m o T L i s t Vi e w
T P a n e l T M o n t h C a l e n d a r
T P o p u p M e n u T P a g e C o n t r o l
T R a d i o B u t t o n T R i c h E d i t
T R a d i o G r o u p T S t a t u s B a r
T S c r o l l B a r T Ta b C o n t r o l
A d d i t i o n a l T B i t B t n Data Controls T D B C h e c k B o x
T C h e c k L i s t B o x T D B C o m b o B o x
158计计第一部分使用C++Builder编程
下载
(续)
组件面板页V C L对象组件面板页V C L对象
T D B E d i t T Q R L a b e l
T D B G r i d T Q R M e m o
T D B L i s t B o x T Q R S y s D a t a
T D B L o o k u p C o m b o B o x 其他类TA p p l i c a t i o n
T D B L o o k u p L i s t B o x (没有P a r e n t B i D i M o d e)
T D B M e m o T F o r m
T D B R a d i o G r o u p T H i n t Wi n d o w
T D B R i c h E d i t (没有P a r e n t B i D i M o d e)
T D B Te x t T S t a t u s P a n e l
Q R e p o r t T Q R D B Te x t T H e a d e r S e c t i o n
T Q R E x p r
注意T H i n t Window 获取激活提示的控件的B i D i M o d e。
双向属性
表11 - 1列出的一些对象有B i D i M o d e和P a r e n t B i D i M o d e属性,这些属性与Ta p p l i c a t i o n的B i D i K e y b o a r d
和N o n B i D i K e y b o a r d属性一起, 支持双向的本地化。
6. BiDiMode属性
B i D i M o d e属性是新的枚举类型, T B i D i M o d e包含4个状态: b d L e f t To R i g h t、b d R i g h t ToLeft 、
b d R i g h t To L e f t N o A l i g n及b d R i g h t ToLeftReadingOnly 。
( 1 ) b d L e f t To R i g h t
b d L e f t ToRight 使用从左到右的顺序写文本,并且排列和滚动条不改变。例如,见图11 - 1,当输入从右
到左的文本时,如阿拉伯语或希伯来语,光标变为压下模式且文本从右到左输入。拉丁文, 如英语或法语,
从左到右输入。b d L e f t To R i g h t是缺省值。
( 2 ) b d R i g h t To L e f t
b d R i g h t To L e f t使用从右到左的顺序写文本, 同时排列被改变并且滚动条被移动。正常时文本输入为
从右到左以适应right-to-left 语言,如阿拉伯语或希伯来语。当键盘被改为拉丁语时,光标变为压下模式,
并且文本从左到右输入,见图11 - 2。
( 3 ) b d R i g h t To L e f t N o A l i g n
b d R i g h t To L e f t N o A l i g n使用从右到左的顺序写文本,排列没被改变但滚动条被移动,见图11 - 3。
( 4 ) b d R i g h t To L e f t R e a d i n g O n l y
b d R i g h t ToLeftReadingOnly 使用从右到左的顺序写文本,排列和滚动条都不改变,见图11 - 4。
7. TParentBiDiMode属性
图11-1 设置为b d L e f t ToRight 的T L i s t B o x 图11-2 设置为b d R i g h t To L e f t的TListBox
图11-3 设置为bdRightToLeftNoAlign的TListBox 图11-4 设置为bdRightToLeft ReadingOnly的TListBox