.TEAMS本地化说明 .微软关于本地化的说明
1
国际化软件的定义 ................................................................................................................... 4 1.1 国际化软件 ............................................................................................................... 4 1.2 区域 ........................................................................................................................... 4 1.3 本地化 ....................................................................................................................... 4 1.4 字符串资源 ............................................................................................................... 5 设计国际化软件 ....................................................................................................................... 5 2.1 设计国际化软件的优点 ........................................................................................... 5 2.2 本地化模型 ............................................................................................................... 5 使用本地化资源文件 ............................................................................................................... 7 3.1 使用本地化资源文件 ............................................................................................... 7
3.1.1 把字符串保存在资源文件中的优点 ............................................................... 7 3.1.2 锁定资源文件 ................................................................................................... 8 3.2 设计区域识别的用户界面 ....................................................................................... 8
3.2.1 信息 ................................................................................................................... 9 3.2.2 菜单和对话框 ................................................................................................... 9 3.2.3 图标和位图 ..................................................................................................... 10 3.2.4 访问键和快捷键 ............................................................................................. 11 3.3 编写国际化代码时的一般考虑 ............................................................................. 11
3.3.1 硬编码的可本地化字符串 ............................................................................. 11 3.3.2 缓冲区大小 ..................................................................................................... 11 3.3.3 字符串联接 ..................................................................................................... 12 用 Visual Basic编写国际化代码 .......................................................................................... 13 4.1 用 Visual Basic编写国际化代码 .......................................................................... 13
4.1.1 系统区域和代码区域 ..................................................................................... 13 4.1.2 日期 ................................................................................................................. 13 4.1.3 货币 ................................................................................................................. 14 4.1.4 数值和分隔符 ................................................................................................. 14 4.2 区域识别函数 ......................................................................................................... 15
4.2.1 Print 方法 ....................................................................................................... 15 4.2.2 Format 函数 ................................................................................................... 16 4.3 国际排序顺序和字符串比较 ................................................................................. 16
4.3.1 文本排序 ......................................................................................................... 16 4.4 Visual Basic 中的字符串比较 ............................................................................... 17
4.4.1 用 Option Compare 语句比较字符串 .......................................................... 17 4.4.2 用 Like 操作符比较字符串.......................................................................... 18 4.4.3 用 StrComp 函数比较字符串 ...................................................................... 18 4.5 国际文件的输入/输出 ......................................................................................... 19
2
3
4
5
6
4.5.1 Print # .............................................................................................................. 19 4.5.2 Write # ............................................................................................................. 19 4.6 基于日期的区域识别的 SQL 查询...................................................................... 20
4.6.1 使用 DateSerial 和 DateValue ..................................................................... 20 双字节字符集 (DBCS) 的特殊问题 .................................................................................... 21 5.1 ANSI、DBCS 和 Unicode 的定义 ...................................................................... 22
5.1.1 ANSI ............................................................................................................... 23 5.1.2 DBCS .............................................................................................................. 23 5.1.3 Unicode ........................................................................................................... 23 5.1.4 字符代码示例 ................................................................................................. 23 5.2 DBCS 排序顺序和字符串比较 ............................................................................ 24 5.3 DBCS 字符串操作函数 ........................................................................................ 24
5.3.1 DBCS 字符串转换 ........................................................................................ 26 5.4 DBCS 环境下字体、显示和打印的考虑因素 ..................................................... 26
5.4.1 如何避免改变字体设定值 ............................................................................. 27 5.4.2 运行时改变字体的操作方法 ......................................................................... 27 5.5 处理使用双字节字符的文件 ................................................................................. 28 5.6 DBCS 环境的标识符 ............................................................................................ 29 5.7 允许 DBCS 的 KeyPress 事件 ........................................................................... 29 5.8 调用 Windows API 函数 ...................................................................................... 29 Visual Basic 的双向特征 ....................................................................................................... 30
.TEAMS本地化说明
本地化的对象包括窗体模块、类模块、标准模块、资源文件、ActiveX 文档、ActiveX 控件、部件、可插入的对象、引用、ActiveX 设计器、标准控件等,本地化的实质是软件的国际化。下面对一些常用的对象做一下说明:
1}窗体模块(具有 .frm 文件扩展名)包含窗体及其控件的正文描述,包括它们的属性设置。它们也含有窗体级的常数、变量和外部过程的声明、事件过程和一般过程。
2}资源文件(具有 .res 文件扩展名)包含着无需重新编辑代码便可以改变的位图、字符串和其它数据。例如,如果计划用一种外语将应用程序本地化,可以将用户界面的全部正文串和位图存放在资源文件里,然后将资源文件本地化,而不是将整个应用程序本地化。一个工程最多包含一个资源文件。 一、 Teams本地化
采用手工与编程相结合的方式来解决。 1、 消息框的本地化
当用户同应用程序发生交互时,应用程序能够给用户一些消息,一般的做法是MsgBox(Msg, Style, Title, Help, Ctxt) Msg 定义信息,Style定义按钮分格,Title定义标题,Help定义帮助文件Ctxt定义标题,在Teams工程中,作者使用Access建立数据库,数据库中定义一个表,表中每一记录存放应用程序需要的相应消息,每一消息对应一个ID号,当Teams应用程序需要消息反馈时,给出唯一的消息号,通过函数GF_GetMessage和GF_GetMessageDesc取得消息。当应用需要本地化时,不需要改动源代码,只需将Access所建的数据库中的表的列内容改动即可,。
2、窗体的本地化 1)建立资源文件
资源文件的后缀为”.Res”,属性包括标识和语言。可以使用微软的Visual c++或Visual Basic所带的资源编辑器来生成或编辑资源文件。语言属性的定义使得本地化工作非常的方便。
2)调用资源文件
在窗体的Initialize事件中,给出唯一的标识符作为输入参数,调用系统函数LoadResString返回需要的字符串,再对窗体及其包容的对象赋值。
二、本地化步骤
1. 搜索所有待修改的语句(如Form的Caption、Tooltips、Msgbox语句等) 2. 编辑资源文件,定义字符串资源
3. 在适当的地方(如Form的Load事件)调入资源并赋值 4. 一些Caption采用从常量赋值方式 ,所以必须该为变量,如
Public Const G_TITLE = \"Training Management System\" label1.caption=G_TITLE
所以必须改为变量,变量命名保持与常量一致 5. 对资源串的命名,采用IDS_xxxxx方式,xxxxx全部大写
6. 对热键的汉化,采取(&X)方式,例如:原文&File,本地化:文件(&F) 7. 本地化后符号一律用全角,如:句号用“。”而非“.”,括号用“()”而非“()” 8. 所有本地化变量、函数声明放在BAS\\ Localization.BAS 9. 资源文件放在MAK目录,文件名为RESOURCE.RES
10. 如需要对变量初始化(如对版本声明变量初始化),将所有初始化语句放在BAS\\
Localization.BAS中的GF_LocInit,在程序入口(一般为main)再调用GF_LocInit()。
三、其它
1、由于语言表达的差异,有时要适当的调整标签或文本框的长度。
2、Visual Basic内部一般是以Unicode格式来表达字符,当接受到Ansi或其它类型表达的字符时,系统本身作相应的转化时可能会有一些问题。
3、其它可以添加到工程里的诸多对象。
.微软关于本地化的说明
1 国际化软件的定义
开发国际化软件前需要了解一些基本术语。
1.1 国际化软件
国际化软件是指在全世界都可以出售的软件。只有国内市场版本和国际市场版本功能相同的软件才能称为国际化软件。关于如何本地化应用程序的详细信息,请参阅本章后面的“设计国际化软件”。
1.2 区域
区域描述了用户的环境—用户地理区域内的惯例、文化和语言。区域是语言和国家/地区的唯一的组合。区域的两个例子是:英语/美国和法语/比利时。 一种语言可能在不只一个国家/地区中使用,比如:法国、比利时、加拿大和一些非洲国家/地区都使用法语。虽然这些国家/地区都使用同一种语言,但各国都有自己独特的惯例(如货币的表示方法)。因此每个国家/地区代表一个唯一的区域。同样地,一个国家/地区可能有不止一种官方语言:比利时有三种— 法语、荷兰语和德语。因此比利时有三个不同的区域。关于特定区域设定的详细信息,请参阅本章后面的“编写国际化代码时的一般考虑”。
1.3 本地化
本地化是指使应用程序适应区域的过程。不仅指在文字上逐字逐句地翻译这些资源,更重要的是要与用户交流。关于如何本地化应用程序的详细信息,请参阅本章后面的“设计国际化软件”。
1.4 字符串资源
字符串资源是指在应用程序的用户界面中出现的所有文本。其中包括菜单、对话框以及提示、警告和错误信息,但不仅限于此。如果应用程序要在不同于开发区域的其它区域中使用,就需要翻译或本地化这些资源。
详细信息 东亚术语的定义请参阅本章后面的“ANSI, DBCS 和 Unicode 的定义”。关于字符串资源和资源文件的详细信息,请参阅本章后面的“使用本地化资源文件”。
2 设计国际化软件
从设计开始就考虑应用程序的本地化,把字符串资源从代码中分离出来,这样做比在后面的开发过程中修订已完成的应用程序效率要高得多。
2.1 设计国际化软件的优点
设计和实现 Visual Basic 应用程序,以适应国际惯例、外国数据及格式处理,主要有以下四个优点:
使 Visual Basic 应用程序更快地面市。初始版本完成后不需要再进行国际化的工作。 更有效地使用资源。在已完成的 Visual Basic 应用程序中增加国际化支持可能使稳定性降低。这样做与在原始开发过程就提供该项支持相比,在开发和测试上要花费更多的资源。
如果国际版本的 Visual Basic 应用程序使用了原始开发应用程序的相同源代码,只有一些独立的模块需要国际化,那么在进行国际化支持的过程中可以更方便、更节约地维护代码。请参阅本章后面的“使用本地化资源文件”。
开发国际应用程序更加简便。比如,可以开发英语版的应用程序在德语操作系统下使用而不必重新编写代码。需要做的只是定制用户界面。请参阅本章后面的“设计区域识别的用户界面”。
2.2 本地化模型
本地化的应用程序都是由两个概念块构成:代码块和数据块。如图 16.1 所示,数据块代表“用户界面部件”,代码块代表“应用程序部件”。
图 16.1 数据块和代码块构成一个本地化产品
数据块包含所有用户界面的字符串资源而不包含代码。相反,代码块只包含可运行于所有区域的应用程序代码。Visual Basic 代码处理字符串资源和区域的设定。在“用 Visual Basic 编写国际化代码”一节中将详细介绍如何编写 Visual Basic 代码来处理诸如日期、货币、数字和分隔符等与区域有关的设置。
理论上开发本地化版本的 Visual Basic 应用程序只须修改数据块。代码块对所有的区域都是相同的。把数据块和代码块结合在一起就构成了本地化版本的应用程序。成功地设计国际应用程序的关键在于分离数据块和代码块,并使 Visual Basic 应用程序能够准确地读取数据而不用考虑区域。
尽管要麻烦一些,但在开发 Visual Basic 应用程序时还是应该把所有用户界面的字符串资源放到单独的文件而不是代码中,该文件可以在运行时加载。这就是资源文件 (.res)。它包含了所有本地化的字符串、位图和图标。关于资源文件的详细信息,请参阅本章后面的“使用本地化资源文件”。
开发不同语言版本的应用程序时,本地化小组应把精力只花在资源文件上。这样做有以下优点:
高效:由于代码块是相同的,因此开发新的国际应用程序只需创建新的资源文件。这样可以很顺利地开发多国语言版本的 Visual Basic 应用程序。
安全:无论在内部或利用外部公司本地化应用程序,都不用修改源代码。这样做还可以减少花在国际版测试上的精力。
更好的本地化:由于所有的字符串资源都在一个文件中,因此可以提高本地化工作的效率并防止遗漏。
下表列出了在设计 Visual Basic 应用程序时要考虑的一些因素。
因素 语言 项目 用户界面(菜单、对话框及错误信息)中的字符串 打印的文档和联机的文档 与区域有关的设置 日期/时间格式(分隔符、年月日的顺序) 数字格式(小数点和千分位符) 货币格式(符号和格式) 排序顺序和字符串比较
作为第一因素的语言,在 Visual Basic 应用程序的设计阶段就应该首先指出。详细信息,请参阅“设计区域识别的用户界面”。与区域有关的设置,将在本章中的“用 Visual Basic 编写国际化代码”及“国际排序和字符串比较”中介绍。
3 使用本地化资源文件
3.1 使用本地化资源文件
Visual Basic 通过使用资源文件有效地把本地化信息从代码中分离出来。
注意 工程中只能有一个资源文件,如果试图添加一个以上的资源文件 Visual Basic 将产生一个错误信息。
3.1.1 把字符串保存在资源文件中的优点
编写代码时,可以调用 LoadResString、LoadResPicture 和 LoadResData 函数代替对文字、图象和数据的引用。把这些元素存储在资源文件中有两大好处:
提高性能和增加空间,这是因为字符串、位图、图标和数据可以不必在调用窗体或模块时就全部加载,而可以按需要从资源文件中加载。
把需要翻译的资源单独放在一个资源文件中,因此没有必要访问源代码或重新编译应用程序。
要创建资源文件,请按照以下步骤执行:
1. 从“工程”菜单中选择“新资源文件”。
注意 该命令只有在资源编辑器外接程序加载的情况下才能使用。要加载资源管理器外接程序,请选择“外接程序”菜单中的“外接程序管理器”。在“外接程序管理器”对话框中,选择“VB6 资源编辑器”并复选“加载/卸载”。
2. 在“打开一个资源文件”对话框中,为资源文件输入一个名称。资源文件名称将被添
加到“工程资源管理器”的“相关文档”节点。 Visual Basic 把具有 .res 扩展名的文件识别为资源文件。如果资源文件不具有正确的扩展名,Visual Basic 将不会加载它。相反地,任何具有 .res 扩展名的文件被加入到工程时都会被 Visual Basic 当作资源文件处理,如果该文件不具有标准的资源文件格式,Visual Basic 将在第一次使用资源文件支持函数
(LoadResString、LoadResPicture 和 LoadResData)或试图编译成 .exe 文件时产生错误信息。试图添加 16 位的资源文件到工程中也会产生同样的错误信息。 资源文件被添加到工程后,.res 文件将出现在“工程”窗口中。与窗体或模块不同,在 Visual Basic 中不能查看 .res 文件。该文件是标准的资源文件,可由 Microsoft Visual C++ 和其它大部分的 Windows 开发工具创建或使用。一旦在“文件”菜单中选中“生成 projectname.exe”一项,Visual Basic 将把该文件中的所有资源编译到 .exe 文件中作为 Windows 的资源。
在编译 .exe 文件之前和之后,.res 文件都是标准的 Windows 资源文件,这意味着任何标准的 Windows 资源编辑器都可以加载该文件。
要编辑资源文件,请按照以下步骤执行:
1. 从“工具”菜单中选择“资源编辑器”。
注意 该命令仅在资源编辑器外接程序加载的情况下才能使用。要加载资源编辑器外接程序,请从“外接程序”菜单中选择“外接程序管理器”。在“外接程序管理器”对话框中,选择“VB6 资源编辑器”并复选“加载/卸载”框。
2. 从“资源编辑器工具栏”中选择一个按钮来编辑一个现存资源文件或添加一个新的。
有关编辑资源文件的更详细信息,请参阅资源编辑器外接程序文档。
3.1.2 锁定资源文件
Visual Basic 可以对 .res 文件进行文件锁定,以防止同时有几个应用程序使用该文件。在下列条件下 .res 文件将被锁定:
Visual Basic 处于运行模式或中断模式。 创建了一个 .exe 文件。
详细信息 关于如何使用资源文件开发多区域应用程序的示例,请参阅本章后面的“自动取款机应用程序示例”。 关于使用资源文件编程的背景资料,请参阅“再论编程”中的“利用资源文件进行工作”。
3.2 设计区域识别的用户界面
对应用程序进行本地化时文本会加长,因此在设计以下用户界面时应特别注意:
信息 菜单和对话框 图标和位图 访问键和快捷键
3.2.1 信息
英语字符串一般比其它语言的字符串短。下表列出了在初始长度基础上字符串长度增加的平均值。数据取自以前的 Visual Basic 本地化工程的平均增加率。 英语长度(字符数) 本地化字符串的长度增加率 100% 1 到 4 5 到 10 11 到 20 21 到 30 31 到 50 超过 50 设计界面时,应考虑上述的增加率,当信息过长时应允许文本折行。
80% 60% 40% 20% 10% 3.2.2 菜单和对话框
与信息类似,应用程序在进行本地化时,菜单和对话框的长度会增加。在以下
自动取款机示例应用程序中两个内容相同的对话框中,为了允许文本变长增加的附加的空格。图 16.2 为英语对话框,图 16.3 为西班牙语对话框。预先考虑文本长度的增加,安排好界面,这样在本地化时就不用再改变控件的大小或重新设计其它的元素了。
图 16.2 在 ATM 示例应用程序中的英语输入对话框
图 16.3 在 ATM 示例应用程序中的西班牙语输入对话框
由于在其它语言中即便使用缩写文本也可能太长或根本不存在缩写,因此在菜单和对话框中应避免使状态栏过于拥挤。
3.2.3 图标和位图
图标和位图常用来代替文本表示某个特定功能。使用图标和位图时应考虑以下规则:
避免使用非国际标准的位图。以下位图在美国表示邮箱,但其它国家/地区的人可能不认识。
避免使用包含文本的位图。否则要花费时间重画位图,另外文本的长度也可能成为障碍,如以下位图所示。
位图或图标在文化上是敏感的。在一个区域可以接受的在另一个区域可能是不合适的或令人不快的。
3.2.4 访问键和快捷键
不同的区域有不同的键盘布局。并非所有的键盘布局都包含全部字符。开发 Visual Basic 应用程序时,应保证组合的访问键和快捷键可以在国际键盘上重建。使键盘设置满足本地化要求的一个简单的方法是从 Windows 的控制面板上选择合适的键盘布局,并通过键盘布局图(一些参考手册中有)找到适当的访问键和快捷键组合。
由于一些访问键和快捷键组合不能在某些区域下使用,或已被某版本 Windows 系统保留,因此在开发 Visual Basic 应用程序时应尽量避免使用。以下是一些应该避免使用的字符的示例:
@ $ { } [ ] \\ ~ | ^ ' < >
绕过该限制的一个方法是在快捷键组合中使用数字键和功能键(F1、F2 等)替代字母。这样做虽然不太直观但不需要本地化,因为实际上所有的键盘布局都有数字键和功能键。
注意 DBCS 字符不能被用作访问键或快捷键。
3.3 编写国际化代码时的一般考虑
无论使用 Visual Basic 或是其它工具,开发将要本地化的应用程序时,都必须估计到语言间的差异。指明需要本地化的字符串,允许字符串变长,避免字符串接在一起。
3.3.1 硬编码的可本地化字符串
“设计国际化软件”中的本地化模型介绍了数据块和代码块的概念。在创建包含所有本地化字符串的资源文件时,应特别注意只提取需要本地化的字符串。对那些部分或全部都不需本地化的字符串可以是硬编码的。相反的,应该确保所有需要本地化的资源都放到了资源文件中。
3.3.2 缓冲区大小
在根据字符串或词的长度声明缓冲区大小时,应确保缓冲区可以适应更长的词和字符串。关于翻译字符串的平均增长率,请参阅“设计区域识别的用户界面”。在 Visual Basic 代码中声明的缓冲区必须适应这种增长。
例如,Visual Basic 为“确定”这个词声明一个 2 字节的缓冲区,但实际上西班牙语中,该词译作“Aceptar”,这将引起程序溢出。双字节字符也要考虑这些
相同的问题。关于 DBCS 的详细信息,请参阅本章后面的“双字节字符集 (DBCS) 的特殊问题”一节。
3.3.3 字符串联接
可以通过字符串联接来缩短串的长度。该方法允许把一个资源分解到几个字符串中。但是这样做有一定的危险,请注意以下的示例: 英语 字符串 1: one after the other 字符串 2: The controls will be deleted. 字符串 3: The forms will be deleted.
单独看,字符串 1、2、3 很容易本地化。代码执行字符串 2 + 字符串 1 或字符串 3 + 字符串 1 的合并操作,结果的英语含义很正确。但本地化字符串的结果却可能是错误的。比如在法语中,字符串 3 + 字符串 1 是错误的,因为在法语语法中窗体 (feuilles) 是阴性词,因此字符串 1 应变为“une après l'autre”而不是“un après l'autre”。类似的情况在其它许多外语中都有。因此只有把字符串 2 和 字符串 1 及字符串 3 和 字符串 1 合在一起保存在资源文件中才是避免此类错误发生的唯一办法。
在上述示例中,组成句子的词序对英语和法语都是一样的。但通常对这两种语言或其它许多外语,词序并不总是相同的(例如,德语和日语总是把动词放在句尾)。以下示例列举了这种情况: 英语 字符串 1:DLL 字符串 2:Missing Data Access 字符串 3:Missing OLE
当代码执行字符串 1 + 字符串 2 的操作时,本地化版本将出现错误因为两个字符串组成的信息构不成一个句子。一个解决方法是把字符串 1 分别与字符串 2 和字符串 3 组合保存在资源文件中并去掉字符串 1。
以下是另一种解决方法:
英语 字符串 2:Missing Data Access '|1' 字符串 3:Missing OLE '|1'
此时,本地化版本可以识别占位符 '|1' 并在资源文件中进行必要的调整以构成本地化语言的句子。
法语 字符串 2:'|1' d'accès aux données manquant 字符串 3:'|1' OLE manquant 法语 字符串 1:DLL 字符串 2:Accès aux données manquante 字符串 3:OLE manquante 法语 字符串 1: un après l'autre 字符串 2: Les contr鬺es seront supprim閟. 字符串 3: Les feuilles seront supprimées. 最后一点特别要注意的是在英语中相同的词或句在本地化时可能要翻译为不同的词或句。请注意以下的示例: 英语 字符串 1:Setup program 法语 字符串 1:Programme d'installation 字符串 2:String1 did not complete 字符串 2:String1 a échoué。 successfully。 在英语版中,字符串 1 可以作为安装程序标志,也可以在字符串 2 中作为错误信息的一部分。在法语版中,字符串 1 作为单独的标志是合适的,但要变成“Le programme d'installation”才能作为字符串 2 的一部分。
4 用 Visual Basic编写国际化代码
4.1 用 Visual Basic编写国际化代码
对一个产品进行本地化不仅仅是翻译文本信息,该产品还必须支持本国的惯例和数字格式。为了使用不同格式的日期、货币、及数值和分隔符,必须了解 Visual Basic 是如何区分系统区域和代码区域的。
4.1.1 系统区域和代码区域
系统区域是应用程序用户的区域—它是用户输入和输出的参照,是通过设置操作系统的控制面板实现的。在 Visual Basic 中 code locale 总是英语/美国而不考虑用的是哪一国际版本。代码区域决定编程语言和所有与区域有关的设置。
4.1.2 日期
在 Visual Basic 中不要把日期当成字符串输入。应以 # 月/日/年 # 的格式输入日期以确保能被任何系统区域识别。由于 Visual Basic 只允许英语/美国作为编程的区域,因此无论应用程序在哪里运行,日期都是一样的。
例如,在输入对话框中输入 8/2/97,
CDate (\"8/2/97\")
根据不同的系统区域返回以下结果:
操作系统 法语/法国 英语/美国
但如果在代码中输入 8/2/97,
CDate (#8/2/97#)
输出 08/02/97 (= 1997 年 2 月 8 日) 8/2/97 (= 1997 年 8 月 2 日) 根据不同的系统区域返回以下结果:
操作系统 法语/法国 英语/美国. 如果在法国输入 8/2/97,应用程序将解释为 1997 年 2 月 8 日,这是因为在法国日期格式为日/月/年。而在美国输入相同的字符串,应用程序就知道该日期为 1997 年 8 月 2 日,因为日期的格式为月/日/年。
输出 02/08/97 (= 1997 年 8 月 2 日) 8/2/97 (= 1997 年 8 月 2 日) 4.1.3 货币
避免在代码中按字符串输入货币。以下代码只能运行于把美元符号 ($) 当作货币符号的区域。
Money = \"$1.22\" NewMoney = CCur(Money)
如果本代码示例运行于法语/法国区域,此时“F”代表货币符号,Visual Basic 将产生一条错误信息“类型不匹配”,这是因为 $ 不被本国当成货币符号。此时应只简单地使用数字,如下例所示。由于 Visual Basic 的区域总是英语/美国,因此使用句号作为小数点。以下代码将不考虑区域因而能正确执行。
Money = 1.22
NewMoney = CCur(Money)
4.1.4 数值和分隔符
在美国,句号 (.) 被作为小数点。但在一些欧洲国家/地区,小数点是逗号 (,)。类似地,美国把逗号作为分隔小数点左边每三位的千分位符,而一些欧洲国家/地区使用空格实现此功能。下表列出了不同数字格式的一些例子。 国家/地区 数字格式 1,234,567.89 美国 1,234.56 法国 意大利 .123 1 234 567,89 1 234,56 0,123 1.234.567,89 1.234,56 0,123
注意 在Visual Basic 中函数 Str 和 Val 总是把句号当成小数点。但这在大多数区域中是不适用的。因此应该使用 CStr, CDbl, CSng, CInt 和 CLng 函数把其它数据类型转换为需要的数据类型。这些函数通过系统区域来决定小数点。
详细信息 关于 Print 和 Format 函数的详细信息请参阅本章后面的“区域识
别函数”。关于函数“CStr 函数”,“CDbl 函数”,“CSng 函数”,“CInt 函数”,“CLng 函数”,“CDate 函数”和“CCur 函数”,请参阅《语言参考》。也可参阅“变量、常数和数据类型”。
4.2 区域识别函数
不同的区域在显示日期、时间、数字、货币和其它信息时有不同的惯例。但是,没有必要了解用户所在区域的所有惯例。这是因为在 Visual Basic 中的一些函数使用用户的系统区域运行时自动确定惯例,系统区域可以使用操作系统提供的控制面板来设置。这些函数被称为区域识别函数。
4.2.1 Print 方法
尽管 Print 方法为不同的输出格式提供了很少的灵活性,但它确实使用了用户的系统区域。在以下示例中,将用正确的短日期格式打印日期,将用正确的小数点打印数字,将用正确的符号打印货币。
MyDate = #11/24/1997# MyNumber = 26.5 Money = 1636.32
MyMoney = Format(Money, \"###,###.##\") Debug.Print MyDate, MyNumber, MyMoney
此代码运行在英语/美国的区域时,以下输出将出现在立即窗口中。
11/24/1997 26.5 1,636.32
此代码运行在德语/德国的区域时,以下输出将出现在立即窗口中。
24/11/1997 26,5 1.632,32
详细信息 请参阅《语言参考》的“Print 方法”。
4.2.2 Format 函数
Format 函数可以接受格式代码,但格式代码总是产生相同的输出而不考虑用户的区域。例如,格式代码“mm-dd-yy”对于比利时的用户不适用,因为他们的日在月之前。
为了增加更多的灵活性,Format 函数还提供了命名格式可以在运行时自动决定使用何种转换,包括 General Date, Long Date, Short Date 和 Long Time。使用命名格式产生基于用户的系统区域的输出。命名格式甚至可以采用用户本国语言的输出,包括月名和星期名。如下例所示:
MyDate = #8/22/1997 5:22:20 PM#
NewDate1 = Format(MyDate, \"Medium Date\") NewDate2 = Format(MyDate, \"Short Date\") NewDate3 = Format(MyDate, \"Long Date\") NewDate4 = Format(MyDate, \"General Date\")
Debug.Print NewDate1, NewDate2, NewDate3, NewDate4
代码运行在英语/美国区域时,下列输出显示在立即窗口中:
22-Aug-97 8/22/97 Monday, August 22, 1997 8/22/97 5:22:20 PM
代码运行在法语/法国区域时,下列输出显示在立即窗口中:
22-ao鹴-97 22/08/97 lundi 22 ao鹴 1997 22/08/97 17:22:20f
详细信息 请参阅《语言参考》里的“Format 函数”。
4.3 国际排序顺序和字符串比较
字符串比较在 Visual Basic 中应用很广。然而使用此功能时,如果忽略某些编程要求,有可能导致错误的结果。
4.3.1 文本排序
文本排序的意思是根据语言惯例对文本排序。由于格式和字体只代表表示形式而不是内容,因此它们与排序过程无关。乍看起来,文本排序看似简单:a 优先于 b,b 优先于 c,等等。然而,很多语言具有很复杂的排序规则。正确的国际排序不是英文文本排序的简单扩展,因此需要对排序过程有不同的理解。
正确的国际排序的意思是上下文相关排序。字符收缩和扩展是上下文相关排序的两个重要方面。
当把两个字符组合作为单个的唯一字母对待时,出现字符收缩。例如,西班牙语中的两个字符组合 ch 是一个单独字母,排序时排在 c 和 d 之间。
代表一个字符的一个字母在排序时却看作是两个,在这种情况下出现字符扩展。例如,在德语/德国和德语/瑞士区域中,?/I> (eszett) 等同于 ss。而在德语/奥地利区域中,?/I> 等同于 sz。
在进行排序顺序之前,必须考虑代码页。代码页是一顺序字符集,由一数字索引(代码指针)指向其中的每一个字符。因为有各种各样的代码页,所以单个代码指针在不同代码页中代表不同的字符。然而很多代码页共享代码指针 32 至 127(ASCII 字符集),除此之外,它们是不同的。通常,代码页中其它额外字母不是按字母排序的。
详细信息 关于东亚语言排序顺序的详细信息,请参阅本章后面的“DBCS 排序顺序和字符串比较”。
4.4 Visual Basic 中的字符串比较
每个国家/地区的字符串比较规则不同。Visual Basic 提供了许多具有区域识别功能的字符串比较工具,例如 Like 和 StrComp。 为了有效使用这些工具,首先必须清楚地了解 Option Compare 语句。
4.4.1 用 Option Compare 语句比较字符串
使用此语句时,对给定的模块必须指定字符串的比较方法:Binary 或 Text。如果指定 Binary,则根据代表字符的内部二进制码的排序顺序进行字符串比较。如果指定 Text,则根据由用户系统区域决定的不区分大小写的文本排序顺序完成字符串比较。缺省的文本比较方法是 Binary。
在下面的代码示例中,用户在两个输入框中输入信息。接着,按适当的字母顺序进行信息的比较和排序。
Private Sub Form_Click ()
Dim name1 As String, name2 As String
name1 = InputBox(\"Enter 1st hardware name here:\") name2 = InputBox(\"Enter 2nd hardware name here:\") If name1 < name2 Then
msg = \" ' \" & name1 & \" ' comes before ' \" & _ name2 & \" ' \" Else
msg = \" ' \" & name2 & \" ' comes before ' \" & _ name1 & \" ' \" End If MsgBox msg End Sub
如果该代码在区域为英语/美国的系统下运行,输入 printer 和 Screen,则消息框内的输出如下:
'Screen' comes before 'printer'
这是基于缺省的文本比较方法为 Binary 时的结果。因为大写 S 的内部二进制代码小于小写 p 的内部二进制代码,所以条件语句 Screen < printer 被确认。当在模块的声明区内增加 Option Compare Text 语句后,Visual Basic 按不区分大小写的方法比较这两个字符串,输出结果如下:
'printer' comes before 'Screen'
如果该代码在区域为法语/加拿大的系统下运行,而且输入 imprimante 和 écran,则消息框内的输出如下:
'imprimante' comes before 'écran'
同样,如果在代码中增加 Option Compare Text 语句,则这两项以正确的顺序出现—即 écran 先于 imprimante。此外,由于不区分大小写,比较时应考虑重音字符,例如法语中的 é,排序时将它紧排在其标准字符之后—此时是 e。
如果输入 ecran 和 écran,输出将是:
'ecran' comes before 'écran'
详细信息 请参阅《语言参考》的“Option Compare 语句”。
4.4.2 用 Like 操作符比较字符串
可以使用 Like 操作符比较两个字符串。也可以使用其模式匹配功能。当编写国际化软件时,必须考虑模式匹配功能。当字符范围使用 Like 时,指定的模式表示排序顺序范围。例如,用 Binary 方法比较字符串时(通过设置缺省值或通过在代码中添加 Option Compare Binary),字符范围 [A – C] 将忽略大写重读 a 字符和所有小写字符。只有以 A、B 和 C 开头的字符串才能与之匹配。而在很多语言中却不是这样。例如德语中,上述范围将忽略所有以 ?开头的字符串。在法语中,则忽略所有以 à 开头的字符串。
使用 Text 方法比较字符串时,所有重音 A 和 a 字符将包含在内。然而在区域为法语/法国中,由于 ? 和 ? 在排序顺序中出现在 C 和 c 之后,所以以 ? 或 ? 开头的字符串不包含在内。
在某些区域里,利用 [A - Z] 范围来选定所有以字母字符开头的字符串并不是一种有效的方法。如果在区域为丹麦语/丹麦的系统下运行应用程序,用 Text 方法比较字符串时,以 ? 和 ? 开头的字符串不包含在此范围内。虽然这两个字符是丹麦语字符的一部分,但它们排在 Z 之后。因此,应在 Z 之后增加这些字母。例如,用 Option Compare Text 语句比较字符串时,Print \"?l\" Like \"[A-Z]*\" 将返回 False,但是 Print \"?l\" Like \"[A-Z?]*\" 将返回 True。
4.4.3 用 StrComp 函数比较字符串
用 StrComp 函数比较字符串很有用。它的返回值表明某一字符串是否小于、等于或大于另一字符串。返回值也与用 Option Compare 语句定义的字符串比较方法
(Binary 或 Text)有关。在比较同一字符串时,根据定义的字符串比较方法不同,StrComp 的返回值也不同。
详细信息 关于东亚语言字符串比较的详细信息,请参阅本章后面的“DBCS 排序顺序和字符串比较”一节。也可参阅《语言参考》的“StrComp 函数”。
4.5 国际文件的输入/输出
Visual Basic 中,当有文件的输入/输出操作时,区域也是考虑的重要因素。Print # 和 Write # 语句都可用于数据文件输出,但它们有不同的用途。
4.5.1 Print #
Print # 语句以区域识别的格式将数据输出到文件里,就象数据显示到屏幕上一样。例如,日期输出使用系统 Short Date 格式,数字值使用系统小数点。 在 Visual Basic 中,当数据是用 Print # 语句写到文件里时,Input # 语句不能读取具有区域识别格式的数据。为了能使 Visual Basic 在任何区域里读取不依赖于区域的数据,可使用 Write # 语句,而不是 Print # 语句。
4.5.2 Write #
与 Print # 语句类似,Write # 语句也是以固定的格式将数据输出到文件,并保证这些数据在任何区域里都能用 Input # 语句从文件中读取。例如,使用通用日期格式将日期输出到文件里,使用句号作为小数点将数字值输出到文件里。在下面的代码示例中,使用 Write # 语句将日期和数字值写到文件里。然后再打开该文件,使用 Input # 语句读取其内容,同时将结果输出到立即窗口中。Long Date 信息从系统区域中获取:
Dim MyDate As Date, NewDate As Date Dim MyNumber As Variant MyDate = #8/2/67# MyNumber = 123.45
Open \"Testfile\" for Output As #1 Write #1, MyDate, MyNumber Close #1
Open \"Testfile\" for Input As #1 Input #1, MyDate, MyNumber
NewDate = Format(Mydate, \"Long Date\") Debug.Print NewDate, MyNumber Close #1
在英语/美国的区域中运行该代码,立即窗口出现如下信息:
Wednesday, August 02, 1967 123.45
在法语/法国的区域中运行该代码,立即窗口出现如下信息:
mercredi 2 ao鹴 1967 123,45
在这两个区域中,输出都是准确的—通过使用 Write # 和 Input # 语句,信息得到了恰当的存储和获取。
详细信息 有关文件处理的背景信息,请参阅第十四章“处理驱动器、文件夹和文件”中的“使用文件”。有关文件处理的背景信息,请参阅“处理驱动器、文件夹和文件”中“使用文件”。也可参阅《语言参考》的“Print # 语句”或“Write # 语句”。
4.6 基于日期的区域识别的 SQL 查询
正如“用 Visual Basic 编写国际化代码”中说明的那样,不同的国家/地区具有不同的日期格式。当应用程序执行比较两个日期的操作时,为了可靠,日期必须以唯一的格式存储,而忽略其区域。在 Visual Basic 中,数据库引擎存储一日期/时间值作为 DateSerial 值,它由 8 位浮点数表示,日期为整数部分,时间为分数部分。这种表示方法完全不依赖于区域,而且可使用国际日期/时间格式执行日期/时间比较操作。
结构化查询语言 (SQL) 是 ANSI 标准,Visual Basic 也遵从该标准。存入表和数据库中的日期,使用的是英语/美国格式(月/日/年)。Microsotft Jet 数据库引擎也采用这种格式。如果使用非美国日期格式,用这些字段查寻时可能返回错误的记录或没有记录返回。
该约束同样适用于 Filter 属性,Recordset 对象中的 FindFirst, FindNext, FindPrevious 和 FindLast 方法,以及 SQL 语句中的 WHERE 子句。
4.6.1 使用 DateSerial 和 DateValue
这里有两个函数可以解决 SQL 标准的限制。避免代码中使用日期/时间,代之以使用 DateValue 或 DateSerial 函数生成所需日期。DateValue 函数用系统的 Short Date 设置解释所提供的字符串,DateSerial 函数使用一系列可在任何区域中运行的参数。如果 SQL 查询或 Filter 属性中使用日期/时间,则日期和时间只能使用英语/美国格式,除此之外别无选择。
以下示例说明了如何执行基于日期的查询。第一个例子使用非美国日期格式。由于日期表达式中出现语法错误,返回的 Recordset 是空的:
Dim mydb As Database Dim myds As Recordset
Set mydb = OpenDatabase(\"MyDatabase.mdb\") '包含日期/时间字段的表。
Set myds = mydb.OpenRecordset(\"MyTable,dbopenDynaset\") '日期格式是日/月/年。
myds.FindFirst \"DateFiled > #30/03/97#\" '数据控件和 mydb 相联。
Data1.Recordset.Filter = \"DateFiled = #30/03/97#\"
mydb.Close myds.Close
然而,下面的例子由于日期采用适当的格式,因此在任何区域里执行都正确:
Dim mydb As Database Dim myds As Recordset
Set mydb = OpenDatabase(\"MyDatabase.mdb\") '包含日期/时间字段的表。
Set myds = mydb.OpenRecordset(\"MyTable, dbopenDynaset\")
myds.FindFirst \"DateFiled > #03/30/97#\" '日期格式是 '月/日/年。
'数据控件和 mydb 相联。
Data1.Recordset.Filter = \"DateFiled = _ DateValue(\"\"\" & DateString & \"\"\")\"
mydb.Close myds.Close
5 双字节字符集 (DBCS) 的特殊问题
建立双字节字符集 (DBCS) 是用来处理使用象形文字字符的东亚语言,它需要使用的字符超过 ANSI 支持的 256 。DBCS 中字符是双字节、16 位符号。虽然为东亚语言定义的字符很少,但 16 位符号可代表 65,536 个字符。例如,现在定义的日语字符集大约有 12,000 个字符。
在使用 DBCS 的区域包括中国、日本、和朝鲜,字符集里都包含单字节和双字节字符。对每个国家/地区,使用的单字节字符都符合 8 位符号标准,并且与 ASCII 字符集相一致。在单字节字符集 (SBCS) 里,有些代码的范围在 DBCS 字符里称为前
导字节。由一前导字符和一后续字符组成的一对连续字符代表一双字节字符。使用前导字符的代码范围根据区域而定。
注意 DBCS 是有别于 Unicode 的另一类字符。由于 Visual Basic 内部表示所有字符的格式是 Unicode,所以需要时,ANSI 和 DBCS 字符会自动转换成 Unicode 字符或者 Unicode 字符自动转换成 ANSI 或 DBCS 字符。也可人工完成 Unicode 和 ANSI/DBCS 之间的转换。有关不同字符集间转换的详细信息,请参阅“DBCS 字符串操作函数”一节。
当用 Visual Basic 开发允许使用 DBCS 的应用程序时,应考虑:
Unicode、ANSI 和 DBCS 之间的差别。 DBCS 排序顺序和字符串比较。 DBCS 字符串操作函数。 DBCS 字符串转换。
在 DBCS 环境下如何正确显示和打印字体。 如何处理包括双字节字符的文件。 DBCS 标识符。 允许 DBCS 的事件。 如何调用 Windows API。
提示 无论应用程序是否运行在使用 DBCS 的区域下,开发允许 DBCS 的应用程序都是很好的方法。该方法帮助用户开发灵活、便捷和真正的国际应用程序。在使用单一单字符集 (SBCS) 的环境下,允许 DBCS 功能并不干扰应用程序的运行,并且由于 DBCS 和 SBCS 内部使用 Unicode,所以应用程序的大小不会增加。
详细信息 有关使用 DBCS 访问键和快捷键的限制,请参阅“设计国际识别的用户界面”。
5.1 ANSI、DBCS 和 Unicode 的定义
Visual Basic 使用 Unicode 存储和操作字符串。Unicode 是一种用两个字节表示一个字符的字符集。另外一些程序,如 Windows 95 API,使用 ANSI (American National Standards Institute) 或 DBCS 存储和操作字符串。当从 Visual Basic 移出字符串时,会遇到 Unicode 和 ANSI/DBCS 之间的差别。下表列出了不同环境下 ANSI、DBCS 和 Unicode 字符集。
环境 Visual Basic 32-bit 对象库 16-bit 对象库 Windows NT API Automation in Windows NT Windows 95 API
使用的字符集 Unicode Unicode ANSI 和 DBCS Unicode Unicode ANSI 和 DBCS Automation in Windows 95 Unicode 5.1.1 ANSI
ANSI 是个人计算机使用得最普遍的字符集。由于 ANSI 标准使用单一字节表示每个字符,因此最多只能有 256 个字符和标点符号代码。虽然对英语来说已经足够了,但不能完全支持其它语言。
5.1.2 DBCS
发行在亚洲大部分地区的 Microsoft Windows 系统使用 DBCS。它支持很多不同的东亚语言字母,如汉语、日语和朝鲜语。DBCS 使用数字 0–128 表示 ASCII 字符集。其它大于 128 的数字作为前导字节字符,它并不是真正的字符,只是简单的表明下一个字符属于非拉丁字符集。在 DBCS 中,ASCII 字符的长度是一个字节,而日语、朝鲜语和其它东亚字符的长度是 2 个字节。
5.1.3 Unicode
Unicode 是用两个字节表示每个字符的字符编码方案。国际标准组织 (ISO) 几乎为每种语言的每个字符和符号在 0 到 65,535 (216 – 1) 范围内定义了一个数字(再加上为将来发展保留的一些空余空间)。在所有 32 位版本的 Windows 中,部件对象模型 (COM) 都使用 Unicode,它是 OLE 和 ActiveX 技术的基础。Windows NT 全部支持 Unicode。虽然 Unicode 和 DBCS 都是双字节字符,但它们的编码方案完全不同。
5.1.4 字符代码示例
图 16.4 显示了每一个字符集中的一个字符代码示例。注意双字节字符每一个字节的代码不同。
图 16.4 ANSI、Unicode 和 DBCS 中 \"A\" 的字符代码
5.2 DBCS 排序顺序和字符串比较
对 DBCS 字符串使用 Option Compare Text 语句时,由于该语句产生一些特殊动作,因此必须清楚 DBCS 文本排序和比较的内容。当使用 Option Compare Binary 语句时,根据字符内部二进制码的排序顺序进行比较。当使用 Option Compare Text 语句时,根据由用户的系统区域决定的、不区分大小写的文本排序顺序进行比较。 英语中“不区分大小写”的意思是忽略大写和小写的差别。在 DBCS 环境中,不区分大小写有另外的意思。例如,在有些 DBCS 字符集(包括日语、繁体汉语和朝鲜语)中,对同一字符有两种表示法,半角字符和全角字符。例如,单字节“A”和双字节“A”。虽然它们显示时字符宽度不同,但 Option Compare Text 将它们作为同一字符处理。每个 DBCS 字符集都有类似的规则。
比较字符串时应小心。即使是使用 Like 或 StrComp 比较时认为相等的两个字符串,该字符串中确切的字符可能是不同的,字符串长度也可能不同。
详细信息 有关使用 Option Compare 语句比较字符串的一般信息,请参阅“国际排序顺序和字符串比较”一节。
5.3 DBCS 字符串操作函数
虽然双字节字符由一个前导字节和一个后续字节组成,并存储在两个连续的字节里,但是在任何涉及到字符和字符串的操作时,它应作为一个单元处理。一些字符串操作函数可以处理基于字符的所有字符串,包括 DBCS 字符。
这些函数有 ANSI/DBCS 版本、二进制版本或者 Unicode 版本,如下表所示。根据操作字符串的目的,使用适当的函数。
下表中函数的“下”版本尤其适合于使用二进制数据的字符串,“W”版本适合于使用 Unicode 的字符串。 函数 Asc 描述 返回字符串第一个字符的 ANSI 或 DBCS 字符代码。 AscB AscW Chr ChrB ChrW Input InputB InStr InStrB Left, Right LeftB, RightB Len LenB Mid MidB
返回给定包含二进制数据的字符串第一个字节的值。 返回字符串第一个字符的 Unicode 字符代码。 返回包含指定 ANSI 或 DBCS 字符代码的字符串。 返回包含指定字节的二进制字符串。 返回包含指定 Unicode 字符代码的字符串。 从文件中返回指定数目的 ANSI 或 DBCS 字符。 从文件中返回指定数目的字节。 返回一字符串在另一字符串中第一次出现的位置。 返回一字节在另一二进制字符串中第一次出现的位置。 返回字符串左边或右边指定数目的字符。 返回二进制字符串左边或右边指定数目的字节。 返回以字符数为单位的字符串长度。 返回以字节数为单位的字符串长度。 从字符串中返回指定数目的字符。 从二进制字符串中返回指定数目的字节。 表中没有 \"B\" 或 \"W\" 的函数能正确处理 DBCS 或 ANSI 字符。除上述函数以外,String 函数也能处理 DBCS 字符。这就是说所有函数把 DBCS 字符作为一个字符处理,即使该字符由两个字节组成。
当处理 SBCS 和 DBCS 字符时,这些函数的过程是不同的。例如,在 Visual Basic 中使用 Mid 函数从字符串中返回指定数目的字符。在使用 DBCS 的区域中,字符数和字节数不一定相同,Mid 函数只返回字符数而不是字节数。
大多数情况下,由于这些函数能够正确处理 ANSI、DBCS 和 Unicode 字符串,因此处理字符串数据时,都使用基于字符的函数。
基于字节的字符串操作函数,例如 LenB 和 LeftB 用于处理二进制数据的字符串数据。当向 String 变量存储字符或从 String 变量读取字符时,Visual Basic 会自动完成 Unicode 和 ANSI 字符间的转换。当处理二进制数据时,应使用 Byte 数组而不是 String 变量和基于字节的字符串操作函数。
详细信息 关于相应的函数,请参阅《语言参考》。
处理二进制数据的字符串时,使用下列代码将字符串中的字符映射到 Byte 数组中:
Dim MyByteString() As Byte '将字符串映射到一 Byte 数组中。
MyByteString = \"ABC\" '显示二进制数据。
For i = LBound(MyByteString) to UBound(MyByteString) Print Right(\" \" + Hex(MyByteString(i)),2) + \" ,\"; Next Print
5.3.1 DBCS 字符串转换
Visual Basic 提供了一些对 DBCS 字符进行字符串转换的函数:StrConv、UCase 和 LCase。
5.3.1.1 StrConv 函数
StrConv 函数的全局选项是将大写转换成小写或将小写转换成大写。此外,该函数还有一些 DBCS 特定的选项。例如,通过指定该函数第二个参数中的 vbWide,可将半角字符转换成全角字符。也可用此函数将一种字符类型转换成另一种字符类型,如日语中的平假名转换成片假名。如果与系统的 LocaleID 不同,StrConv 允许您为该字符串指定一个 LocaleID。
也可使用 StrConv 函数将 Unicode 字符转换成 ANSI/DBCS 字符或将 ANSI/DBCS 字符转换成 Unicode 字符。通常,Visual Basic 中的字符串由 Unicode 字符组成。当需要处理 ANSI/DBCS 字符串时(例如,在将字符串写入文件之前,计算字符串的字节数),可使用 StrConv 函数的这一功能。
5.3.1.2 全角字符的大小写转换
可使用 StrConv 函数的 vbUpperCase 或 vbLowerCase 选项,或者使用 UCase 或 LCase 函数进行字母的大小写转换。使用这些函数完成 DBCS 包括 ANSI 字符的英语全角字符的大小写转换。
5.4 DBCS 环境下字体、显示和打印的考虑因素
使用为 SBCS 字符设计的字体时,Windows 的 DBCS 版本不会正确显示 DBCS 字符。使用 Visual Basic 英语版本或其它 SBCS 语言版本开发允许 DBCS 的应用程序时,需要改变 Font 对象的 Name 属性。Name 属性决定控件中显示文本的字体、运行时图片中的字体和打印操作中的字体。该属性的缺省值是 Visual Basic 英语版本中的 MS Sans Serif。为在 DBCS 环境中正确显示文本,将设置值改成应用程序在 DBCS
环境下运行时适当的字体。也可能需要通过改变 Font 对象的 Size 属性来改变字体大小。通常,在大字数东亚平台上,应用程序中的文本最好以 9 磅字体显示,而欧洲平台上典型的是 8 磅字体。
同样,通过应用程序打印 DBCS 字符时,也应考虑这些因素。
5.4.1 如何避免改变字体设定值
如果没有允许 DBCS 的字体,或者不知道那一种字体适合于目标平台,可用一些选项来解决这些字体问题。
在 Windows 的繁体汉语、简体汉语和朝鲜语版本中,有一称为字体关联的系统功能。例如,朝鲜语 Windows 中,字体关联自动地将应用程序中的英语字体映射成朝鲜语字体。因此,即使是应用程序使用英语字体,仍然能够显示朝鲜语字符。关联的字体由运行平台的系统注册表中的
\\HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\control\\fontassoc
\\Associated DefaultFonts 的设置决定。由于有系统支持的字体关联,可以不用改变任何字体设置,而在汉语或朝鲜语平台上运行英语应用程序。其它平台如日语 Windows 没有字体关联。
另一选项是使用 System 字体或 FixedSys 字体。每个平台都可使用这些字体。注意 System 字体和 FixedSys 字体大小不能改变。如果在设计时设置的任何一种字体大小(用 Font 对象的 Size 属性)与使用机器上的字体大小不匹配,则忽略设置值、截断显示文本。
5.4.2 运行时改变字体的操作方法
虽然有上述选项,这些解决方法仍有限制。下面的示例是应用程序在运行时,使用全局解决方法改变其中的字体。下面的代码可在 Windows 的任何语言版本上运行,它决定驻留在系统中的字体,应用程序将在该系统下运行,将适当的字体应用到参数中指定的 Font 对象。
Private Const DEFAULT_CHARSET = 1 Private Const SYMBOL_CHARSET = 2 Private Const SHIFTJIS_CHARSET = 128 Private Const HANGEUL_CHARSET = 129 Private Const CHINESEBIG5_CHARSET = 136 Private Const CHINESESIMPLIFIED_CHARSET = 134
Private Declare Function GetUserDefaultLCID Lib \"kernel32\" () As Long
Public Sub SetProperFont(obj As Object) On Error GoTo ErrorSetProperFont Select Case GetUserDefaultLCID Case &H404 ' 繁体中文
obj.Charset = CHINESEBIG5_CHARSET
obj.Name = ChrW(&H65B0) + ChrW(&H7D30) + ChrW(&H660E) _ + ChrW(&H9AD4) 'New Ming-Li obj.Size = 9 Case &H411 ' 日语
obj.Charset = SHIFTJIS_CHARSET
obj.Name = ChrW(&HFF2D) + ChrW(&HFF33) + ChrW(&H20) + _ ChrW(&HFF30) + ChrW(&H30B4) + ChrW(&H30B7) + ChrW(&H30C3) + _ ChrW(&H30AF) obj.Size = 9
Case &H412 '朝鲜 UserLCID
obj.Charset = HANGEUL_CHARSET
obj.Name = ChrW(&HAD74) + ChrW(&HB9BC) obj.Size = 9 Case &H804 ' 简体中文
obj.Charset = CHINESESIMPLIFIED_CHARSET obj.Name = ChrW(&H5B8B) + ChrW(&H4F53) obj.Size = 9
Case Else ' 其他国家/地区 obj.Charset = DEFAULT_CHARSET obj.Name = \"\" ' 获得缺省 UI 字体。 obj.Size = 8 End Select Exit Sub ErrorSetProperFont: Err.Number = Err
也可更改这个简单的示例代码将字体应用到其它字体设置上,如打印选项。
5.5 处理使用双字节字符的文件
在使用 DBCS 的区域里,文件可能包含双字节字符和单字节字符。由于 DBCS 字符由两个字节表示,Visual Basic 代码必须避免把它们分开。下面的示例,假定 Testfile 是一个包含 DBCS 字符的文本文件。
'打开文件,准备输入。
Open \"TESTFILE\" For Input As #1
'读取文件中的所有字符。 Do While Not EOF(1)
MyChar = Input(1, #1) '读取一字符。 '使用 Mychar 执行操作。 Loop
Close #1 '关闭文件。
当从二进制文件读取固定长度的字节时,使用 Byte 数组而不是 String 变量,以阻止 Visual Basic 中 ANSI 到 Unicode 的转换。
Dim MyByteString(0 to 4) As Byte
Get #1,, MyByteString
使用 String 变量,用 Input 或 InputB 从二进制文件中读取字节时,将出现 Unicode 字符转换,结果是错误的。
记住文件名称和目录也可能包含 DBCS 字符。
详细信息 有关文件处理的背景信息,请参阅“处理驱动器、文件夹和文件”中的“使用文件”。有关 Byte 数据类型的信息,请参阅“编程基础”中的“数据类型”。
5.6 DBCS 环境的标识符
在下面的标识符中不支持 DBCS 字符:
公共过程名 公共变量 公共常数
工程名(当在“工程属性”对话框中指定时)
类名(类模块的 Name 属性、用户控件、属性页或用户文档)
5.7 允许 DBCS 的 KeyPress 事件
KeyPress 事件能够将双字节字符代码作为事件处理。keyascii 参数的高位字节代表双字节字符的前导字节,低位字节代表后续字节。
在下面的示例中,可将 KeyPress 事件传递给文本框,而不管输入的字符是单字节还是双字节。
Sub Text1_KeyPress (KeyAscii As Integer) Mychar = Chr(KeyAscii) '使用 Mychar 执行操作。 End Sub
详细信息 请参阅《语言参考》的“KeyPress 事件”。
5.8 调用 Windows API 函数
很多 Windows API 和 DLL 函数的返回值是字节大小。返回值代表返回字符串的长度。Visual Basic 将返回的字符串转换成 Unicode,即使是返回值仍然代表 ANSI 和 DBCS 字符串的长度。因此不能使用返回长度作为字符串长度。下面的代码得到正确的返回的字符串:
buffer = String(145, Chr(\" \"))
ret = GetPrivateProfileString(section, _
entry, default, buffer, Len(buffer)-1, filename) retstring = Left(buffer, Instr(buffer, Chr(0))-1))
详细信息 有关详细信息,请参阅专业版和企业版的《部件工具指南》里“访问 DLL 和 Windows API ”中的“访问 Microsoft Windows API”一节。
6 Visual Basic 的双向特征
Visual Basic 是允许双向(也被称为 \"BiDi\")的,
“双向”是一个一般术语,是指一个软件产品支持阿拉伯语或其它的从右向左书写的语言。更确切地说,“双向”是软件产品的一种能力,既能操作和显示从左向右书写的语言的文本,也能操作和显示从右向左书写的语言的文本。例如,如果一句话中既包含有英文单词,又包含有阿拉伯文的单词,那么显示这句话就需要“双向”能力。
Microsoft Visual Basic 提供了创建和运行具有完全双向语言能力的 Windows 应用程序的功能。但是,仅当 Microsoft Visual Basic 被安装在象 Arabic Microsoft Windows 95 这样的双向 32-位 Microsoft Windows 环境中时,这些功能才可使用。对于其它的双向 32-位 Microsoft Windows 环境同样可用。
RightToLeft 属性已经被添加到窗体、控件和其它的 Visual Basic 对象中,以便能够提供一种简单机制,来创建具有双向特征的对象。尽管在每一个 Microsoft Visual Basic 的安装程序中都包含有 RightToLeft,但是仅当 Microsoft Visual Basic 被安装在一个双向 32-位 Microsoft Windows 环境中时,它才可用。 有关双向特征的文档描述了所有有关 Microsoft Visual Basic 的双向特征的问题。您可以在 Visual Basic 的目录表中参考的附加信息中找到该信息。单击该主题标题下的“请参阅”直接到概述主题。
为与 Microsoft Visual Basic 4.0 保持兼容,在 Microsoft Visual Basic 中包含有两个版本的 32-位 Grid 控件 (Grid32.ocx),但是没有安装它们。这两个版本都位于产品媒介安装路径的 \\Tools 文件夹下。标准版位于 \\Controls 子文件夹,双向版位于 \\Controls\\Bidi 子文件夹。
因篇幅问题不能全部显示,请点此查看更多更全内容