中国计算机报1999年第47期

VB编程实现万能汉字输入法

蒋光明

  本文根据作者的开发实践,介绍如何在Win 95环境下,编程让程序具有万能汉字输入法的功能。下面以五笔字型输入法在VB 5.0中的实现为例,给出了完整的万能汉字输入法程序。



  获得汉字输入法的码表


  一般微机上都装有UCDOS,它提供了一个输入法码表管理器imdmng。进入UCDOS所在的目录,执行下面的命令“imdmng .\drv\wb.imd .\wb.txt”。wb.txt文件内容如下,删除前面的编码规则定义部分:


  为了在程序中能够使用它,首先要进行文件格式的转换。进入VB 5.0,新建一个标准模块。在模块中输入如下的程序:


Type hh 

  hz As String  8 

  bm As String  4 

  End Type

  Public hzbm As hh ′包含汉字及其对应编码的全局变量

  Sub Main()

  Open "c:\ucdos\wb.txt" For Input As #1 

  Open App.Path & "\wb.dat" For Output As #2 

  x = 0 

  Do

  Line Input #1, a$

  hzbm.bm = Left$(a$, 4) ′从每一行的字符串中取得汉字编码

  b$ = Mid$(a$, 13, Len(a$) - 12) 

  hzc = 1

  For i = 1 To Len(b$)

   aa$ = Mid$(b$, i, 1)

   If Asc(aa$) = 32 Or i = Len(a$) - 12 Then 

   hzbm.hz = Trim(Mid$(b$, hzc, i - hzc + 1))

   hzc = i + 1

   Print #2, hzbm.hz, hzbm.bm ′按一编码对应一字(词)的方式输出

   x = x + 1

   End If

  Next

  Loop Until EOF(1)

  close ′关闭打开的文件

  End Sub


  然后保存工程1,运行它,在工程1所在的目录生成一个名为wb.dat的文件。



  码表的词条排序


  在Win 95的附件中,有一个输入法生成器,可以对码表原文件进行词条的排序。在输入法生成器中,选择“词条排序”→“打开文件”,打开上面程序生成的wb.dat,单击排序按钮。不用几秒钟,它就帮你把码表中的两万多条词排好了顺序。



  自定义码表的生成


  要实现汉字输入,快速的编码查询是非常重要的。在码表文件的结构上就不能采取一般的文本文件,我采取了VB中的随机文件模式,文件中每条记录的结构和上面的程序中定义的一样。下面的程序根据排序之后的wb.dat生成自定义码表,运行它可以生成名为wb.ime的码表文件。


Sub ImeGenerate()

  Open app.path & "\wb.dat" For Input As #1

  Open app.path & "\wb.ime" For Random As #2 Len = Len(hzbm) ′建立自定义码表文件

  x = 1 ′记录指针

  Do

   Line Input #1, a ′读入一条汉字编码

  For i = 1 To Len(a)

   aa = Mid$(a, i, 1)

   If Asc(aa) 〈 127 And Asc(aa) 〉 0 Then hzc = i - 1: Exit For 

   Next

   hzbm.hz = Left(a, hzc) 

   hzbm.bm = Mid$(a, hzc + 1, Len(a) - hzc) 

   Put #2, x, hzbm ′写入一条汉字编码记录

   x = x + 1

  Loop Until EOF(1)

  End Sub


  编写输入法的输入模块


  在VB 5.0中新建一个工程,在Form1上放置三个TextBox控件,最上面一个用来显示输入的汉字,中间一个用来显示与Win 95类似的逐渐提示窗口,最下面的一个用来输入编码。把TextBox2和TextBox3的MultiLine属性设置为TRUE,把TextBox1的MaxLength设置为4。双击TextBox3,输入下面的程序(由于篇幅所限,这里只给出编码查询的程序段):


 


Dim HzTs(1 To 10) As String 

  Dim HzY As Boolean 

  Sub SearchIt(ob As String) 

  num = LOF(1) \ 12

  nowwz = 1 

  wzs = 1 

  wze = num 

  wz = 0

  Do

  bm1 = bj(wzs)

  bm2 = bj(wze)

  If ob 〉 bm2 Or ob 〈 bm1 Then ′输入编码在码表中不存在

   Exit Do

  ElseIf ob 〉 bm1 And ob 〈 bm2 Then ′输入的编码可能在码表中

   bm1 = bj(wzs + (wze - wzs) \ 2) ′取码表最中间的编码

   If ob 〉 bm1 Then 

   wzs = wzs + (wze - wzs) \ 2

   wze = wze

   ElseIf ob 〈 bm1 Then

   wzs = wzs

   wze = wzs + (wze - wzs) \ 2

   Else

   wz = wzs + (wze - wzs) \ 2 ′编码不在码表中。

   Exit Do

   End If

  ElseIf ob = bm1 Then ′输入的编码就是码表中的第一个编码

   wz = wzs

   Exit Do

  ElseIf ob = bm2 Then ′输入的编码就是码表中的最后一个编码

   wz = wze

   Exit Do

  End If

  Loop Until wze - wzs = 1 ′查找的结束条件

  If wz 〈〉 0 Then ′找到了对应的编码

  Text2.Text = ""

  For i = wz To wz + 9 ′生成汉字的逐渐提示

   If i 〉 num Then Exit For

   Get #1, i, hzbm

   xx = hzbm.hz

   xx = Trim(jtrim(xx))

   HzTs(i - wz + 1) = xx

   bmx = Right(hzbm.bm, 4 - Len(Text1.Text))

   xh = Trim(Str(i - wz) + ":")

   Text2.Text = Text2.Text & xh & xx & bmx & Chr(13) & Chr(10)

  Next

  HzY = True

  Else ′未找到符合条件的编码

  Text2.Text = ""

  HzY = False

  For i = 1 To 10 ′清空逐渐提示。

   HzTs(i) = ""

  Next

  End If

  End Sub

  万能输入法应用与改进


  现在,你已经基本上完成了一个万能输入法。你只要根据前面介绍的步骤建立自定义的码表文件,就可以用同样的程序实现多种汉字输入方法。只要在程序中设置一个打开不同码表文件的子程序,你甚至可以在同一个程序中实现多种汉字输入法的切换。由于一个功能完善的输入法涉及到很多内容和编程技巧,本文只是提供了一种快速的编码查询算法和相应的程序及相关的外壳程序。你可以改进它达到真正实用的目的。