在DOS年代,具有一个富丽的汉字菜单几乎是每个高档中文运用程序有必要的包装。中文Windows操作体系的呈现使得高档开发渠道完成全中文的提示和界面非常简略和便利。在一般的运用程序中现已很少需求去专门考虑汉字处理的问题。
可是在许多工程操控和字符串处理的环境中,汉字字符的处理依然有别于西文字符的处理,需求加以专门的考虑。
一、VB6对汉字处理的支撑
对汉字处理,VB6主要是供给了一些输入法设置方面的支撑。它供给了一个ImeMode特点和ImeStatus函数来确认和设置输入法的状况。并且此特点和办法只在VB6的东亚区版别中有用。
IMEStatus函数回来一个整数,用来指定当时Windows的输入法(IME)办法。
下面是中文区域的回来值:
常数 值 描绘
vbIMENoOP 0 不装置IME(缺省)
vbIMEOn 1 翻开IME
ImeMode特点回来或许设置被选定的方针的 IME (Input Method Editor,输入办法编辑器)状况。
能够先用ImeStatus函数来检测当时的输入状况,并用IMEMode来操控其输入状况。
如Text1.IMEMode=0(预订值)、=1(切换为中文输入)、=2(切换为英文输入)
关于简体汉字和繁体汉字 IME,只能运用设置 0 到 2。设置 3 到 10 关于汉字体系是无效的。
VB6功用上对汉字处理的直接支撑也仅限于此。关于汉字字符串的处理,VB6并没有供给专门的函数和办法。
二、确认汉字字符串的长度
各个版别的VB对汉字字符的长度界说并不相同。在Windows 3.x中,VB3中以为每个汉字的长度为2字节。VB自从32位版别以後,不论中英文字,均以2 bytes来贮存,这与中文WinArray5的汉字内核有关。可是VB4今后,VB以为每个汉字的长度为1。这在处理包括汉字的字符串时带来许多的不方便。
因为Len、Left、Mid等字符串函数以为一个汉字和一个西文字符的长度都为1,因而处理汉字字符串时有必定的难度。完成上有必要要能把汉字依照两个字符(字节)的办法读出。因而在截取汉字字符串的子串时需特别留意。
因为汉字处理和汉字字模存储的特殊性,在许多情况下咱们期望汉字字符的长度为2,英文字符为1。因为VB5和VB6把一个汉字作为一个字符。因而处理汉字时首要有必要能正确判别汉字字符串的长度。
在VB3或C++++里,汉字的 ASCII码均大于零,而VB5和VB6中汉字的ASCII码小于0。因而经过判别一个不知道字符的ASCII码就能够判别该字符是否汉字。
这儿咱们供给了两种办法来判别汉字字符串的长度。
1、办法1
VB6中供给了LenB函数用于字符串中的字节数据。如同在双字节字符集(DBCS)言语中一样,LenB回来的是用于代表字符串的字节数,而不是回来字符串中字符的数量。如为用户自界说类型,LenB回来在内存中的巨细。
LenB(StrConv(Str1,vbFormUnicode))
对要处理的字符串Str1,有必要先运用StrConv函数把ANSI格局的Byte数组转化为字符串,不然直接运用LenB函数得到的成果比实践成果大。
2、办法2
这儿自界说了一个子函数CLen来核算汉字字符串的实践长度。一起还能判别字符串中汉字的实践个数。
FuncTIon CLen(HzStr$) as Integer
StaTIc HzNum as Integer
L = len(HzStr$)
For n=1 to L
If Asc(mid$( HzStr$,n,1))《0 Then HzNum = HzNum + 1
Next n
Clen = L + HzNum
End FuncTIon
CLen函数中的静态变量HzNum回来字符串中实践汉字的数目。
三、汉字字模读写和存储的机理
核算机是以编码的办法来处理和运用字符的。西文字符选用一个字节表明,即ASCII码,一般只用七位来表明128个字符,而把最高位用作奇偶校验(或许不必)。我国国标规则汉字用内码表明,内码为两个字节。为了确保中西文兼容,也便是说汉字体系的内码有必要一起答应ASCII码和汉字的运用,两者之间不该发生冲突。现在规则每个字节只用七位,若两个字节的最高位均为1,则该字符为汉字。
国标对汉字字库的结构作了一致规则,行将字库分红若干个区,每个区有Array4个汉字,每个汉字在字库中有确认的区和位,因而每个汉字各有一个区位码,知道了区位码也就相当于知道了汉字在字库中的方位。因为汉字的内码与区位码有必定的联系,所以只需经过汉字的内码就可得到该汉字的区位码,也就得到了该汉字的字模。
查找一个汉字字模数据的算法为:
汉字内码 -》 区位码 -》 记载号 -》 字模数据
一个16点阵汉字其字模数据共有32字节,能够看作是一条记载,在程序中能够用一个数组寄存。在DOS的图形方法下,汉字是经过描点的办法逐点画上去的。读取字模中每个字节的每一位,就能确认汉字中的每个点。故一个16×16点阵的汉字有必要要32个字节的字模数据才干确认。
以下是DOS的图形方法下显现一个16×16点阵汉字时的描点次序图。每两个字节的字模数据确认一行。
四、VB6中完成汉字字模转化的技巧
在许多工程操控的运用环境中,常常需求对标准的汉字字模进行调整和转化。
要对汉字字模进行转化首要应该正确地读出16点阵汉字在字库中的32字节的字模数据。设某一汉字的内码为ddff,其间dd表明区内码,ff表明位内码,则dd-&Ha1为该汉字的区码,ff-&Ha1为该汉字的位码。则该汉字在字库中的方位为:
LocaTIon = [(dd-&Ha1)×Array4 + (ff-&Ha1)]×32
需求留意的是,以何种办法从字库文件中读取这32字节也是一个关键问题。因为二进制(Binary)办法拜访文件能够直接查看文件中指定的字节,并且二进制办法也是仅有支撑用户到文件的任何方位读写恣意长度数据的办法。因而以二进制办法翻开汉字字库文件是最适合的。
VB6尽管供给了较强的位运算功用,可是关于在字模转化中运用较多的移位操作,却没有供给对应的移位运算符、指令或函数。其实经过and(与)、or(或)二个位运算符即可编制一个自界说子函数来完成移位运算。
下面的自界说子函数便是完成循环右移的:
Public Function byteRight(byte1 As Byte, n As Integer) As Byte ’将byte1右移n位
Dim TemVar As Byte ’暂时变量
Dim TemVar1 As Byte ’暂时变量
Dim X, Y As Integer
TemVar = byte1
For X = 1 To n ’移多少位就循环多少次
For Y = 1 To 8 ’从榜首位(右边榜首位)开端循环右移
Select Case Y
Case 1
If (TemVar And &H1) = &H1 Then ’假如暂时变量TemVar的榜首位是1,
TemVar1 = &H1 ’则将暂时变量TemVar1置1,
Else
TemVar1 = &H0 ’则将暂时变量TemVar1置0,
End If
Case 2
If (TemVar And &H2) = &H2 Then ’假如暂时变量TemVar的第二位是1,
TemVar = TemVar Or &H1 ’则将其榜首方位1(其它位不变),
Else
TemVar = TemVar And &HFE ’反之将榜首方位0(其它位不变)
End If
Case 3
If (TemVar And &H4) = &H4 Then ’操作与上面相同
TemVar = TemVar Or &H2
Else
TemVar = TemVar And &HFD
End If
Case 4
If (TemVar And &H8) = &H8 Then
TemVar = TemVar Or &H4
Else
TemVar = TemVar And &HFB
End If
Case 5
If (TemVar And &H10) = &H10 Then
TemVar = TemVar Or &H8
Else
TemVar = TemVar And &HF7
End If
Case 6
If (TemVar And &H20) = &H20 Then
TemVar = TemVar Or &H10
Else
TemVar = TemVar And &HEF
End If
Case 7
If (TemVar And &H40) = &H40 Then
TemVar = TemVar Or &H20
Else
TemVar = TemVar And &HDF
End If
Case 8
If (TemVar And &H80) = &H80 Then
TemVar = TemVar Or &H40
Else
TemVar = TemVar And &HBF
End If
If TemVar1 = &H1 Then ’移完第八位后,假如TemVar1是1(即榜首位是1)
TemVar = TemVar Or &H80 ’则将TemVar的第八方位1
Else
TemVar = TemVar And &H7F ’反之置0
End If
End Select
Next Y
Next X
byteRight = TemVar ’将TemVar的值回来给函数名
End Function
特别需求留意的是当把二进制数据写入文件中时,有必要运用Byte数据类型的数组变量,而不是 String 变量。 String 被以为包括的是字符,而二进制型数据或许无法正确地存在 String 变量中。
五、一个实践运用事例
图形点阵液晶在现代单片机体系中是一种非常常用的显现设备,BP机、手机上的显现屏便是图形点阵液晶。它能显现汉字和图形,与行列式键盘组成了单片机体系中最常用的人机交互界面。可是直接从中文体系汉字字库中提取的汉字字模并不能直接在液晶上显现,一般都有必要经过格局上的调整和转化。
1、图形点阵液晶的汉字字模
与在西文DOS中显现汉字不同的是,图形点阵液晶并不是简略地用画点的办法来描出汉字。以常用的HD61202图形点阵液晶显现操控模块为例,它能操控 64×64点阵液晶的显现,其显现RAM共64行,分8页,每页8行,每一页的数据寄存器别离对应液晶屏幕上的8行点,对显现RAM的一个字节单位赋值便是对当时列的8行(一页)的像素点是否显现进行操控。接连16列和相邻的2页的32字节显现RAM就能够操控一个汉字的显现区域。对这些显现RAM赋以相应的值就能够显现出一个汉字。
HD61202图形点阵液晶显现操控模块的汉字字模的摆放实践上是标准汉字字模摆放办法旋转而成的。对标准汉字字模转化的意图便是在单片机体系的数据存储器中(如E2PROM)存储经过调整的接连32字节的16进制数。
2、实践源程序
以下这段程序是放置在汉字源文本输入框(SrcTxt)的Change事情中。经过判别输入在文本框内的字符的ASCII码是否小于零,就能判别输入的字符是不是汉字。这段程序还能核算汉字字符串的长度。一起把输入的汉字存储在一个暂时文件TempSrc.txt中。因为这段代码是放在文本框的 Change事情中,它能当即更新汉字个数的显现。
Private Sub SrcTxt_Change( )
Static SStr As String
Dim i As Integer
Dim TempFile, TempFileBinary As String
TotalNum = 0
L = Len(SrcTxt.Text)
For i = 1 To L
tmpStr = StrConv(Mid$(SrcTxt.Text, i, 1), vbWide)
If Asc(Mid$(SrcTxt.Text, i, 1)) 《 0 Then
TotalNum = TotalNum + 1
SStr = SrcTxt.Text
Else
MsgBox “写入的不是汉字!”
SrcTxt.Text = Left(SrcTxt.Text, Len(SrcTxt.Text) – 1)
Exit Sub
End If
Next i
LblNum.Caption = Str$(TotalNum) + “个汉字”
TempFile = App.Path + “\” + “TempSrc.txt”
’TempFileBinary = App.Path + “\” + “TempSrcBinary.txt”
Open TempFile For Output As #1
Print #1, SrcTxt.Text
Close #1
End Sub
在实例中选用了UCDOS 5.0汉字体系中的16点阵字库Hzk16作为提取汉字字模的标准字库。
Private Sub CmdCnt_Click( )
Dim TempSrcFile As String
Dim TempDestFile As String
Dim TempFile As String
Dim HzFile As String
Dim To61202(32) As Integer
Dim p(1 To 2) As Byte
Dim C1, C2
Dim rec As Integer
Dim Location As Long ’汉字在字库中的方位
Dim Hz(0 To 31) As Byte ’转化完的32字节的字模数据
Dim Buf1(0 To 31) As Byte ’暂存转化过程中的32字节字模数据
Dim HzAll( ) As Byte ’寄存悉数字模数据的动态数组
Dim LoopAll As Integer
Dim bit, k2, k3 As Byte
Dim i, j, i1, k, k1, k4, k5, k6 As Integer
DestTxt.Text = “” ’DestTxt是方针文本框,寄存转化后的16进制数据
Flag = 0
TempDestFile$ = App.Path + “\” + “TempDest.txt”
If FileExists(TempDestFile$) Then Kill TempDestFile ’FileExists是一个查看文件是否存在的自界说函数
If SrcTxt.Text = “” Then ’汉字输入框内无汉字则退出
MsgBox “没有能够转化的字模源文件!”
Exit Sub
End If
HzNum = Len(SrcTxt.Text) ’取得汉字的个数
ReDim HzAll(0 To HzNum * 32 – 1) ’从头界说动态数组的上界
Open TempFile For Output As #1
Print #1, SrcTxt.Text
Close #1
For LoopAll = 0 To HzNum – 1
Open TempFile For Binary Access Read As #1 ’按二进制办法翻开
Get #1, 2 * LoopAll + 1, p
Close #1
C1 = CStr(p(1)) – &Ha1 ’区内码
C2 = CStr(p(2)) – &Ha1 ’位内码
rec = C1 * Array4 + C2
Location = CLng(rec) * 32 + 1 ’该汉字在16*16点阵字库中字模榜首个字节的方位
HzFile = App.Path + “\” + “hzk16”
Open HzFile For Binary Access Read As #1 ’读取该汉字在16点阵字库中的原始字模
Get #1, Location, Hz
Close #1
’以下是将UCDOS字库的存储格局调整为HD61202的标准格局
For j = 0 To 3
If j = 0 Then k4 = 14
If j = 1 Then k4 = 15
If j = 2 Then k4 = 30
If j = 3 Then k4 = 31
For k = 0 To 7
bit = &H80
bit = byteRight((bit), (k))
For i = 0 To 7
k2 = byteleft(Buf1(j * 8 + k), 1) ’整个流程是由低位向高位移动,最终凑成一个字节
k3 = byteRight((Hz(k4 – i * 2) And bit), 7 – k) ’将字节中的某位移到最低位
k3 = k3 And &H1 ’屏蔽掉其他7位
Buf1(j * 8 + k) = k2 Or k3
Next i
Next k
Next j
For i1 = 0 To 31 ’将调整后的汉字字模再装入原数组
Hz(i1) = Buf1(i1)
HzAll(LoopAll * 32 + i1) = Buf1(i1)
Next
Next LoopAll
Open TempDestFile For Binary Access Write As #1 ’转化成果保存到TempDestFile中
Put #1, 1, HzAll
Close #1
MsgBox “OK!”
End Sub
以上程序均在中文VB6专业版上调试经过。
以上程序在有用中取得了很好的作用。此汉字字模转化程序丰厚了单片机体系开发工具的功用,是包括液晶显现功用的单片机体系在体系调试和开发过程中不可或缺的功用模块。