本文将为大家详细讲述的是VB实现MUI程序方法希望本文能给大家的日常开发工作带来一些启示 之前我负责一个VB编写的办公自动化系统要求能在运行时支持在不同语言间切换(英文中文日文德文法文和西班牙文);实质就是实现一个VB的MUI程序 这个需要的困难在于VB显示文本的标准控件(LabelTextbox等)不支持Unicode;但字符串在其内部是按Unicode保存的也就是说VB本身是支持Unicode的 VB中标准控件显示字符串的过程如下: ) 标准控件先将Unicode字符串转换成ANSI字符串; ) 标准控件尝试将ANSI字符串转换成其FontCharset属性中指定的字符集格式的字符串;如果转换失败则显示为问号(?) 具体可参照:Display Unicode Strings in Visual Basic 因此实现MUI程序的思路有两种: ) 将标准控件替换为能支持Unicode的控件; ) 将资源文件中不同字符集的文本转换为ANSI格式提供给标准控件使用; 第)种方式可用 Forms (fmdll); 第)种方式我在网上找到两篇文章但各有不足: a) AutoDetect Language and Display Unicode in VB TextBox and Label Controls; ChilkatCharset控件需购买具对日文的一些标点符号(如全角句号)不支持 b) How To Convert from ANSI to Unicode & Unicode to ANSI for OLE 没有测试成功 下面着重介绍我自己认为比较成功的实现它使用了ADODBStream(msadotlb);其实现思路如下: ) 将程序中用到的文本保存为Unicode格式的资源文件中; 之所以将资源文本保存为双字节的Unicode格式而非Utf或Utf格式可省去从其它格式向VB支持的Unicode格式转换过程 ) 将显示文本的标准控件的FontCharset设置为程序要显示语言所对应的字符集并设置一种支持这种字符集的字体到FontName属性 If g_StrNumJapanese > Then charset = Shift_JIS TextFontName = MS UI Gothic TextFontcharset = ElseIf g_StrNumKorean > Then charset = ks_c_ TextFontName = GulimChe TextFontcharset = ElseIf g_StrNumCentralEuro > Then charset = windows TextFontName = Arial TextFontcharset = ElseIf g_StrNumArabic > Then charset = windows TextFontName = Traditional Arabic TextFontcharset = ElseIf g_StrNumHebrew > Then charset = windows TextFontName = David TextFontcharset = ElseIf g_StrNumCyrillic > Then charset = windows TextFontName = Arial TextFontcharset = ElseIf g_StrNumGreek > Then charset = windows TextFontName = Arial TextFontcharset = ElseIf g_StrNumThai > Then charset = windows TextFontName = Angsana New TextFontcharset = ElseIf g_StrNumChinese > Then charset = gb TextFontName = SimSun TextFontcharset = An alternative is to use Big: TextFontName = MingLiu charset = big fontCh = Else charset = windows TextFontcharset = TextFontName = Arial End If ) 根据要显示的语言利用ADODBStream将资源文件中Unicode格式保存的字符串转换成操作系统的区域语言(Locale)支持字符集的字符串; 调用API来获取操作系统默认的区域语言设置(LocaleID) Private Declare Function GetSystemDefaultLCID Lib kernel () As Long 将Unicode字符串转换为指定字符集的字节数组; 用于转换用资源文件中读取的文本; Public Function ConvertStringToBytes(ByRef strText As String charset As String) As Byte() Dim objStream As ADODBStream Dim data() As Byte init stream Set objStream = New ADODBStream objStreamcharset = charset objStreamMode = adModeReadWrite objStreamType = adTypeText objStreamOpen write bytes into stream objStreamWriteText strText objStreamFlush rewind stream and read text objStreamPosition = objStreamType = adTypeBinary objStreamRead skip first bytes as this is the utf marker data = objStreamRead() close up and return objStreamClose ConvertStringToUtfBytes = data End Function 转换为指定字符集的字节数组转换为ANSI(即LocaleID)对应的字符集的字符串; 用于将ConvertStringToBytes()返回的字节数组转换为GetCharset()字符集的字符串 Public Function ConvertBytesToString(ByRef data() As Byte charset As String) As String Dim objStream As ADODBStream Dim strTmp As String init stream Set objStream = New ADODBStream objStreamcharset = charset objStreamMode = adModeReadWrite objStreamType = adTypeBinary objStreamOpen write bytes into stream objStreamWrite data objStreamFlush rewind stream and read text objStreamPosition = objStreamType = adTypeText strTmp = objStreamReadText close up and return objStreamClose ConvertUtfBytesToString = strTmp End Function 获取操作系统默认区域语言对应的字符集 Public Function GetCharset() As String Dim localeId As Long Dim charset As String 获取操作系统的LocaleId localeId = GetSystemDefaultLCID() Select Case localeId Case charset = windows Case charset = gb Case charset = Shift_JIS Case Else charset = windows End Select GetCharset = charset End Function 显示资源文本中的文本 Private Sub DisplayText(filename As String) 保存资源文本中的文本的变量 Dim textBytes As Variant Dim f As New FileSystemObject Dim fs As TextStream 将Unicode文本读取到变量中 Set fs = fOpenTextFile(filename ForReading False TristateTrue) Do While Not fsAtEndOfStream textBytes = fsReadAll Loop fsClose Convert to a Unicode string: Dim s As String s = textBytes Dim t As Long CkString是免费的第三方组件可自动判定一个字符串所对应的字符集 下载地址: Dim g_Str As New CkString g_StrStr = s 获取资源文本所代表的字符集名称设置对应的字体和字符集到textbox上 Dim charset As String If g_StrNumJapanese > Then 日文 charset = Shift_JIS TextFontName = MS UI Gothic TextFontcharset = ElseIf g_StrNumKorean > Then 韩语 charset = ks_c_ TextFontName = GulimChe TextFontcharset = ElseIf g_StrNumCentralEuro > Then 中欧语言 charset = windows TextFontName = Arial TextFontcharset = ElseIf g_StrNumArabic > Then 阿拉伯语 charset = windows TextFontName = Traditional Arabic TextFontcharset = ElseIf g_StrNumGreek > Then 希腊语 charset = windows TextFontName = Arial TextFontcharset = ElseIf g_StrNumThai > Then 泰语 charset = windows TextFontName = Angsana New TextFontcharset = ElseIf g_StrNumChinese > Then 中文 charset = gb TextFontName = SimSun TextFontcharset = 繁体则使用Big: TextFontName = MingLiu charset = big TextFontcharset = Else 默认值 charset = windows TextFontcharset = TextFontName = Arial End If Dim bytes() As Byte Dim g_OSCharset As String 获取操作系统默认语言对应的字符集 g_OSCharset = GetCharset() 先将Unicode资源文本转换成对应的字节数组; bytes = ConvertStringToBytes(s charset) 将字节数组转换成ANSI(即默认字符集)对应的字符串 vbstr = ConvertBytesToString(bytes g_OSCharset) 设置字符串到VB的标准控件中 MeTextText = vbstr End Sub |